Skip to content

Commit 156bf6d

Browse files
committed
This closes #1129, make cell support inheritance columns/rows style
Correct cells style in merge range Fix incorrect style ID returned on getting cell style in some cases Unit test updated and simplified code
1 parent 3ee3c38 commit 156bf6d

7 files changed

+58
-40
lines changed

cell.go

+29-23
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,12 @@ func (f *File) setCellTimeFunc(sheet, axis string, value time.Time) error {
200200
if err != nil {
201201
return err
202202
}
203-
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
203+
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
204204
if err != nil {
205205
return err
206206
}
207207
ws.Lock()
208-
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
208+
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
209209
ws.Unlock()
210210

211211
var isNum bool
@@ -214,10 +214,7 @@ func (f *File) setCellTimeFunc(sheet, axis string, value time.Time) error {
214214
return err
215215
}
216216
if isNum {
217-
err = f.setDefaultTimeStyle(sheet, axis, 22)
218-
if err != nil {
219-
return err
220-
}
217+
_ = f.setDefaultTimeStyle(sheet, axis, 22)
221218
}
222219
return err
223220
}
@@ -254,13 +251,13 @@ func (f *File) SetCellInt(sheet, axis string, value int) error {
254251
if err != nil {
255252
return err
256253
}
257-
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
254+
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
258255
if err != nil {
259256
return err
260257
}
261258
ws.Lock()
262259
defer ws.Unlock()
263-
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
260+
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
264261
cellData.T, cellData.V = setCellInt(value)
265262
return err
266263
}
@@ -279,13 +276,13 @@ func (f *File) SetCellBool(sheet, axis string, value bool) error {
279276
if err != nil {
280277
return err
281278
}
282-
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
279+
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
283280
if err != nil {
284281
return err
285282
}
286283
ws.Lock()
287284
defer ws.Unlock()
288-
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
285+
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
289286
cellData.T, cellData.V = setCellBool(value)
290287
return err
291288
}
@@ -316,13 +313,13 @@ func (f *File) SetCellFloat(sheet, axis string, value float64, prec, bitSize int
316313
if err != nil {
317314
return err
318315
}
319-
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
316+
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
320317
if err != nil {
321318
return err
322319
}
323320
ws.Lock()
324321
defer ws.Unlock()
325-
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
322+
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
326323
cellData.T, cellData.V = setCellFloat(value, prec, bitSize)
327324
return err
328325
}
@@ -341,13 +338,13 @@ func (f *File) SetCellStr(sheet, axis, value string) error {
341338
if err != nil {
342339
return err
343340
}
344-
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
341+
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
345342
if err != nil {
346343
return err
347344
}
348345
ws.Lock()
349346
defer ws.Unlock()
350-
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
347+
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
351348
cellData.T, cellData.V, err = f.setCellString(value)
352349
return err
353350
}
@@ -439,13 +436,13 @@ func (f *File) SetCellDefault(sheet, axis, value string) error {
439436
if err != nil {
440437
return err
441438
}
442-
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
439+
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
443440
if err != nil {
444441
return err
445442
}
446443
ws.Lock()
447444
defer ws.Unlock()
448-
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
445+
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
449446
cellData.T, cellData.V = setCellDefault(value)
450447
return err
451448
}
@@ -937,14 +934,14 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
937934
if err != nil {
938935
return err
939936
}
940-
cellData, col, _, err := f.prepareCell(ws, sheet, cell)
937+
cellData, col, row, err := f.prepareCell(ws, sheet, cell)
941938
if err != nil {
942939
return err
943940
}
944941
if err := f.sharedStringsLoader(); err != nil {
945942
return err
946943
}
947-
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
944+
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
948945
si := xlsxSI{}
949946
sst := f.sharedStringsReader()
950947
textRuns := []xlsxR{}
@@ -1133,14 +1130,19 @@ func isTimeNumFmt(format string) bool {
11331130

11341131
// prepareCellStyle provides a function to prepare style index of cell in
11351132
// worksheet by given column index and style index.
1136-
func (f *File) prepareCellStyle(ws *xlsxWorksheet, col, style int) int {
1133+
func (f *File) prepareCellStyle(ws *xlsxWorksheet, col, row, style int) int {
11371134
if ws.Cols != nil && style == 0 {
11381135
for _, c := range ws.Cols.Col {
1139-
if c.Min <= col && col <= c.Max {
1140-
style = c.Style
1136+
if c.Min <= col && col <= c.Max && c.Style != 0 {
1137+
return c.Style
11411138
}
11421139
}
11431140
}
1141+
for rowIdx := range ws.SheetData.Row {
1142+
if styleID := ws.SheetData.Row[rowIdx].S; style == 0 && styleID != 0 {
1143+
return styleID
1144+
}
1145+
}
11441146
return style
11451147
}
11461148

@@ -1150,6 +1152,11 @@ func (f *File) mergeCellsParser(ws *xlsxWorksheet, axis string) (string, error)
11501152
axis = strings.ToUpper(axis)
11511153
if ws.MergeCells != nil {
11521154
for i := 0; i < len(ws.MergeCells.Cells); i++ {
1155+
if ws.MergeCells.Cells[i] == nil {
1156+
ws.MergeCells.Cells = append(ws.MergeCells.Cells[:i], ws.MergeCells.Cells[i+1:]...)
1157+
i--
1158+
continue
1159+
}
11531160
ok, err := f.checkCellInArea(axis, ws.MergeCells.Cells[i].Ref)
11541161
if err != nil {
11551162
return axis, err
@@ -1170,8 +1177,7 @@ func (f *File) checkCellInArea(cell, area string) (bool, error) {
11701177
return false, err
11711178
}
11721179

1173-
rng := strings.Split(area, ":")
1174-
if len(rng) != 2 {
1180+
if rng := strings.Split(area, ":"); len(rng) != 2 {
11751181
return false, err
11761182
}
11771183
coordinates, err := areaRefToCoordinates(area)

col.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -592,9 +592,8 @@ func (f *File) positionObjectPixels(sheet string, col, row, x1, y1, width, heigh
592592
row++
593593
}
594594

595-
// Initialise end cell to the same as the start cell.
596-
colEnd := col
597-
rowEnd := row
595+
// Initialized end cell to the same as the start cell.
596+
colEnd, rowEnd := col, row
598597

599598
width += x1
600599
height += y1
@@ -632,7 +631,7 @@ func (f *File) getColWidth(sheet string, col int) int {
632631
return int(convertColWidthToPixels(width))
633632
}
634633
}
635-
// Optimisation for when the column widths haven't changed.
634+
// Optimization for when the column widths haven't changed.
636635
return int(defaultColWidthPixels)
637636
}
638637

@@ -658,7 +657,7 @@ func (f *File) GetColWidth(sheet, col string) (float64, error) {
658657
return width, err
659658
}
660659
}
661-
// Optimisation for when the column widths haven't changed.
660+
// Optimization for when the column widths haven't changed.
662661
return defaultColWidth, err
663662
}
664663

@@ -707,7 +706,7 @@ func (f *File) RemoveCol(sheet, col string) error {
707706
return f.adjustHelper(sheet, columns, num, -1)
708707
}
709708

710-
// convertColWidthToPixels provieds function to convert the width of a cell
709+
// convertColWidthToPixels provides function to convert the width of a cell
711710
// from user's units to pixels. Excel rounds the column width to the nearest
712711
// pixel. If the width hasn't been set by the user we use the default value.
713712
// If the column is hidden it has a value of zero.

col_test.go

+13-7
Original file line numberDiff line numberDiff line change
@@ -289,18 +289,24 @@ func TestOutlineLevel(t *testing.T) {
289289
func TestSetColStyle(t *testing.T) {
290290
f := NewFile()
291291
assert.NoError(t, f.SetCellValue("Sheet1", "B2", "Hello"))
292-
style, err := f.NewStyle(`{"fill":{"type":"pattern","color":["#94d3a2"],"pattern":1}}`)
292+
styleID, err := f.NewStyle(`{"fill":{"type":"pattern","color":["#94d3a2"],"pattern":1}}`)
293293
assert.NoError(t, err)
294294
// Test set column style on not exists worksheet.
295-
assert.EqualError(t, f.SetColStyle("SheetN", "E", style), "sheet SheetN is not exist")
295+
assert.EqualError(t, f.SetColStyle("SheetN", "E", styleID), "sheet SheetN is not exist")
296296
// Test set column style with illegal cell coordinates.
297-
assert.EqualError(t, f.SetColStyle("Sheet1", "*", style), newInvalidColumnNameError("*").Error())
298-
assert.EqualError(t, f.SetColStyle("Sheet1", "A:*", style), newInvalidColumnNameError("*").Error())
297+
assert.EqualError(t, f.SetColStyle("Sheet1", "*", styleID), newInvalidColumnNameError("*").Error())
298+
assert.EqualError(t, f.SetColStyle("Sheet1", "A:*", styleID), newInvalidColumnNameError("*").Error())
299299

300-
assert.NoError(t, f.SetColStyle("Sheet1", "B", style))
300+
assert.NoError(t, f.SetColStyle("Sheet1", "B", styleID))
301301
// Test set column style with already exists column with style.
302-
assert.NoError(t, f.SetColStyle("Sheet1", "B", style))
303-
assert.NoError(t, f.SetColStyle("Sheet1", "D:C", style))
302+
assert.NoError(t, f.SetColStyle("Sheet1", "B", styleID))
303+
assert.NoError(t, f.SetColStyle("Sheet1", "D:C", styleID))
304+
ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml")
305+
assert.True(t, ok)
306+
ws.(*xlsxWorksheet).SheetData.Row[1].C[2].S = 0
307+
cellStyleID, err := f.GetCellStyle("Sheet1", "C2")
308+
assert.NoError(t, err)
309+
assert.Equal(t, styleID, cellStyleID)
304310
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetColStyle.xlsx")))
305311
}
306312

excelize_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ func TestOpenFile(t *testing.T) {
147147
assert.NoError(t, f.SetCellValue("Sheet2", "G4", time.Now()))
148148

149149
assert.NoError(t, f.SetCellValue("Sheet2", "G4", time.Now().UTC()))
150+
assert.EqualError(t, f.SetCellValue("SheetN", "A1", time.Now()), "sheet SheetN is not exist")
150151
// 02:46:40
151152
assert.NoError(t, f.SetCellValue("Sheet2", "G5", time.Duration(1e13)))
152153
// Test completion column.

merge.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111

1212
package excelize
1313

14-
import "strings"
14+
import (
15+
"strings"
16+
)
1517

1618
// Rect gets merged cell rectangle coordinates sequence.
1719
func (mc *xlsxMergeCell) Rect() ([]int, error) {
@@ -68,7 +70,8 @@ func (f *File) MergeCell(sheet, hCell, vCell string) error {
6870
ws.MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: ref, rect: rect}}}
6971
}
7072
ws.MergeCells.Count = len(ws.MergeCells.Cells)
71-
return err
73+
styleID, _ := f.GetCellStyle(sheet, hCell)
74+
return f.SetCellStyle(sheet, hCell, vCell, styleID)
7275
}
7376

7477
// UnmergeCell provides a function to unmerge a given coordinate area.

rows_test.go

+3
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,9 @@ func TestSetRowStyle(t *testing.T) {
921921
assert.EqualError(t, f.SetRowStyle("Sheet1", 1, 1, -1), newInvalidStyleID(-1).Error())
922922
assert.EqualError(t, f.SetRowStyle("SheetN", 1, 1, styleID), "sheet SheetN is not exist")
923923
assert.NoError(t, f.SetRowStyle("Sheet1", 10, 1, styleID))
924+
cellStyleID, err := f.GetCellStyle("Sheet1", "B2")
925+
assert.NoError(t, err)
926+
assert.Equal(t, styleID, cellStyleID)
924927
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetRowStyle.xlsx")))
925928
}
926929

styles.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -2613,11 +2613,11 @@ func (f *File) GetCellStyle(sheet, axis string) (int, error) {
26132613
if err != nil {
26142614
return 0, err
26152615
}
2616-
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
2616+
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
26172617
if err != nil {
26182618
return 0, err
26192619
}
2620-
return f.prepareCellStyle(ws, col, cellData.S), err
2620+
return f.prepareCellStyle(ws, col, row, cellData.S), err
26212621
}
26222622

26232623
// SetCellStyle provides a function to add style attribute for cells by given

0 commit comments

Comments
 (0)