forked from tealeg/xlsx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sheet.go
148 lines (140 loc) · 3.43 KB
/
sheet.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package xlsx
import (
"fmt"
"strconv"
)
// Sheet is a high level structure intended to provide user access to
// the contents of a particular sheet within an XLSX file.
type Sheet struct {
Name string
File *File
Rows []*Row
Cols []*Col
MaxRow int
MaxCol int
Hidden bool
}
// Add a new Row to a Sheet
func (s *Sheet) AddRow() *Row {
row := &Row{Sheet: s}
s.Rows = append(s.Rows, row)
if len(s.Rows) > s.MaxRow {
s.MaxRow = len(s.Rows)
}
return row
}
// Make sure we always have as many Cols as we do cells.
func (s *Sheet) maybeAddCol(cellCount int) {
if cellCount > s.MaxCol {
col := &Col{
Min: cellCount,
Max: cellCount,
Hidden: false,
Collapsed: false,
// Style: 0,
Width: ColWidth}
s.Cols = append(s.Cols, col)
s.MaxCol = cellCount
}
}
// Get a Cell by passing it's cartesian coordinates (zero based) as
// row and column integer indexes.
//
// For example:
//
// cell := sheet.Cell(0,0)
//
// ... would set the variable "cell" to contain a Cell struct
// containing the data from the field "A1" on the spreadsheet.
func (sh *Sheet) Cell(row, col int) *Cell {
if len(sh.Rows) > row && sh.Rows[row] != nil && len(sh.Rows[row].Cells) > col {
return sh.Rows[row].Cells[col]
}
return new(Cell)
}
// Dump sheet to it's XML representation, intended for internal use only
func (s *Sheet) makeXLSXSheet(refTable *RefTable, styles *xlsxStyleSheet) *xlsxWorksheet {
worksheet := newXlsxWorksheet()
xSheet := xlsxSheetData{}
maxRow := 0
maxCell := 0
XfId := 0
for r, row := range s.Rows {
if r > maxRow {
maxRow = r
}
xRow := xlsxRow{}
xRow.R = r + 1
for c, cell := range row.Cells {
style := cell.GetStyle()
if style != nil {
xFont, xFill, xBorder, xCellStyleXf, xCellXf := style.makeXLSXStyleElements()
fontId := styles.addFont(xFont)
fillId := styles.addFill(xFill)
borderId := styles.addBorder(xBorder)
xCellStyleXf.FontId = fontId
xCellStyleXf.FillId = fillId
xCellStyleXf.BorderId = borderId
xCellStyleXf.NumFmtId = 0 // General
xCellXf.FontId = fontId
xCellXf.FillId = fillId
xCellXf.BorderId = borderId
xCellXf.NumFmtId = 0 // General
styles.addCellStyleXf(xCellStyleXf)
XfId = styles.addCellXf(xCellXf)
}
if c > maxCell {
maxCell = c
}
xC := xlsxC{}
xC.R = fmt.Sprintf("%s%d", numericToLetters(c), r+1)
switch cell.cellType {
case CellTypeString:
xC.V = strconv.Itoa(refTable.AddString(cell.Value))
xC.T = "s"
xC.S = XfId
case CellTypeBool:
xC.V = cell.Value
xC.T = "b"
xC.S = XfId
case CellTypeNumeric:
xC.V = cell.Value
xC.S = XfId
case CellTypeFormula:
xC.V = cell.Value
xC.F = cell.formula
xC.S = XfId
case CellTypeError:
xC.V = cell.Value
xC.F = cell.formula
xC.T = "e"
xC.S = XfId
}
xRow.C = append(xRow.C, xC)
}
xSheet.Row = append(xSheet.Row, xRow)
}
worksheet.Cols = xlsxCols{Col: []xlsxCol{}}
for _, col := range s.Cols {
if col.Width == 0 {
col.Width = ColWidth
}
worksheet.Cols.Col = append(worksheet.Cols.Col,
xlsxCol{Min: col.Min,
Max: col.Max,
Hidden: col.Hidden,
Width: col.Width,
Collapsed: col.Collapsed,
// Style: col.Style
})
}
worksheet.SheetData = xSheet
dimension := xlsxDimension{}
dimension.Ref = fmt.Sprintf("A1:%s%d",
numericToLetters(maxCell), maxRow+1)
if dimension.Ref == "A1:A1" {
dimension.Ref = "A1"
}
worksheet.Dimension = dimension
return worksheet
}