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
This commit is contained in:
parent
3ee3c38f9c
commit
156bf6d16e
52
cell.go
52
cell.go
|
@ -200,12 +200,12 @@ func (f *File) setCellTimeFunc(sheet, axis string, value time.Time) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
|
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.Lock()
|
ws.Lock()
|
||||||
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
|
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
|
||||||
ws.Unlock()
|
ws.Unlock()
|
||||||
|
|
||||||
var isNum bool
|
var isNum bool
|
||||||
|
@ -214,10 +214,7 @@ func (f *File) setCellTimeFunc(sheet, axis string, value time.Time) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if isNum {
|
if isNum {
|
||||||
err = f.setDefaultTimeStyle(sheet, axis, 22)
|
_ = f.setDefaultTimeStyle(sheet, axis, 22)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -254,13 +251,13 @@ func (f *File) SetCellInt(sheet, axis string, value int) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
|
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.Lock()
|
ws.Lock()
|
||||||
defer ws.Unlock()
|
defer ws.Unlock()
|
||||||
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
|
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
|
||||||
cellData.T, cellData.V = setCellInt(value)
|
cellData.T, cellData.V = setCellInt(value)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -279,13 +276,13 @@ func (f *File) SetCellBool(sheet, axis string, value bool) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
|
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.Lock()
|
ws.Lock()
|
||||||
defer ws.Unlock()
|
defer ws.Unlock()
|
||||||
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
|
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
|
||||||
cellData.T, cellData.V = setCellBool(value)
|
cellData.T, cellData.V = setCellBool(value)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -316,13 +313,13 @@ func (f *File) SetCellFloat(sheet, axis string, value float64, prec, bitSize int
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
|
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.Lock()
|
ws.Lock()
|
||||||
defer ws.Unlock()
|
defer ws.Unlock()
|
||||||
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
|
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
|
||||||
cellData.T, cellData.V = setCellFloat(value, prec, bitSize)
|
cellData.T, cellData.V = setCellFloat(value, prec, bitSize)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -341,13 +338,13 @@ func (f *File) SetCellStr(sheet, axis, value string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
|
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.Lock()
|
ws.Lock()
|
||||||
defer ws.Unlock()
|
defer ws.Unlock()
|
||||||
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
|
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
|
||||||
cellData.T, cellData.V, err = f.setCellString(value)
|
cellData.T, cellData.V, err = f.setCellString(value)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -439,13 +436,13 @@ func (f *File) SetCellDefault(sheet, axis, value string) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
|
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ws.Lock()
|
ws.Lock()
|
||||||
defer ws.Unlock()
|
defer ws.Unlock()
|
||||||
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
|
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
|
||||||
cellData.T, cellData.V = setCellDefault(value)
|
cellData.T, cellData.V = setCellDefault(value)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -937,14 +934,14 @@ func (f *File) SetCellRichText(sheet, cell string, runs []RichTextRun) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cellData, col, _, err := f.prepareCell(ws, sheet, cell)
|
cellData, col, row, err := f.prepareCell(ws, sheet, cell)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := f.sharedStringsLoader(); err != nil {
|
if err := f.sharedStringsLoader(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
cellData.S = f.prepareCellStyle(ws, col, cellData.S)
|
cellData.S = f.prepareCellStyle(ws, col, row, cellData.S)
|
||||||
si := xlsxSI{}
|
si := xlsxSI{}
|
||||||
sst := f.sharedStringsReader()
|
sst := f.sharedStringsReader()
|
||||||
textRuns := []xlsxR{}
|
textRuns := []xlsxR{}
|
||||||
|
@ -1133,14 +1130,19 @@ func isTimeNumFmt(format string) bool {
|
||||||
|
|
||||||
// prepareCellStyle provides a function to prepare style index of cell in
|
// prepareCellStyle provides a function to prepare style index of cell in
|
||||||
// worksheet by given column index and style index.
|
// worksheet by given column index and style index.
|
||||||
func (f *File) prepareCellStyle(ws *xlsxWorksheet, col, style int) int {
|
func (f *File) prepareCellStyle(ws *xlsxWorksheet, col, row, style int) int {
|
||||||
if ws.Cols != nil && style == 0 {
|
if ws.Cols != nil && style == 0 {
|
||||||
for _, c := range ws.Cols.Col {
|
for _, c := range ws.Cols.Col {
|
||||||
if c.Min <= col && col <= c.Max {
|
if c.Min <= col && col <= c.Max && c.Style != 0 {
|
||||||
style = c.Style
|
return c.Style
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for rowIdx := range ws.SheetData.Row {
|
||||||
|
if styleID := ws.SheetData.Row[rowIdx].S; style == 0 && styleID != 0 {
|
||||||
|
return styleID
|
||||||
|
}
|
||||||
|
}
|
||||||
return style
|
return style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1150,6 +1152,11 @@ func (f *File) mergeCellsParser(ws *xlsxWorksheet, axis string) (string, error)
|
||||||
axis = strings.ToUpper(axis)
|
axis = strings.ToUpper(axis)
|
||||||
if ws.MergeCells != nil {
|
if ws.MergeCells != nil {
|
||||||
for i := 0; i < len(ws.MergeCells.Cells); i++ {
|
for i := 0; i < len(ws.MergeCells.Cells); i++ {
|
||||||
|
if ws.MergeCells.Cells[i] == nil {
|
||||||
|
ws.MergeCells.Cells = append(ws.MergeCells.Cells[:i], ws.MergeCells.Cells[i+1:]...)
|
||||||
|
i--
|
||||||
|
continue
|
||||||
|
}
|
||||||
ok, err := f.checkCellInArea(axis, ws.MergeCells.Cells[i].Ref)
|
ok, err := f.checkCellInArea(axis, ws.MergeCells.Cells[i].Ref)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return axis, err
|
return axis, err
|
||||||
|
@ -1170,8 +1177,7 @@ func (f *File) checkCellInArea(cell, area string) (bool, error) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rng := strings.Split(area, ":")
|
if rng := strings.Split(area, ":"); len(rng) != 2 {
|
||||||
if len(rng) != 2 {
|
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
coordinates, err := areaRefToCoordinates(area)
|
coordinates, err := areaRefToCoordinates(area)
|
||||||
|
|
11
col.go
11
col.go
|
@ -592,9 +592,8 @@ func (f *File) positionObjectPixels(sheet string, col, row, x1, y1, width, heigh
|
||||||
row++
|
row++
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialise end cell to the same as the start cell.
|
// Initialized end cell to the same as the start cell.
|
||||||
colEnd := col
|
colEnd, rowEnd := col, row
|
||||||
rowEnd := row
|
|
||||||
|
|
||||||
width += x1
|
width += x1
|
||||||
height += y1
|
height += y1
|
||||||
|
@ -632,7 +631,7 @@ func (f *File) getColWidth(sheet string, col int) int {
|
||||||
return int(convertColWidthToPixels(width))
|
return int(convertColWidthToPixels(width))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Optimisation for when the column widths haven't changed.
|
// Optimization for when the column widths haven't changed.
|
||||||
return int(defaultColWidthPixels)
|
return int(defaultColWidthPixels)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,7 +657,7 @@ func (f *File) GetColWidth(sheet, col string) (float64, error) {
|
||||||
return width, err
|
return width, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Optimisation for when the column widths haven't changed.
|
// Optimization for when the column widths haven't changed.
|
||||||
return defaultColWidth, err
|
return defaultColWidth, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,7 +706,7 @@ func (f *File) RemoveCol(sheet, col string) error {
|
||||||
return f.adjustHelper(sheet, columns, num, -1)
|
return f.adjustHelper(sheet, columns, num, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// convertColWidthToPixels provieds function to convert the width of a cell
|
// convertColWidthToPixels provides function to convert the width of a cell
|
||||||
// from user's units to pixels. Excel rounds the column width to the nearest
|
// from user's units to pixels. Excel rounds the column width to the nearest
|
||||||
// pixel. If the width hasn't been set by the user we use the default value.
|
// pixel. If the width hasn't been set by the user we use the default value.
|
||||||
// If the column is hidden it has a value of zero.
|
// If the column is hidden it has a value of zero.
|
||||||
|
|
20
col_test.go
20
col_test.go
|
@ -289,18 +289,24 @@ func TestOutlineLevel(t *testing.T) {
|
||||||
func TestSetColStyle(t *testing.T) {
|
func TestSetColStyle(t *testing.T) {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
assert.NoError(t, f.SetCellValue("Sheet1", "B2", "Hello"))
|
assert.NoError(t, f.SetCellValue("Sheet1", "B2", "Hello"))
|
||||||
style, err := f.NewStyle(`{"fill":{"type":"pattern","color":["#94d3a2"],"pattern":1}}`)
|
styleID, err := f.NewStyle(`{"fill":{"type":"pattern","color":["#94d3a2"],"pattern":1}}`)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
// Test set column style on not exists worksheet.
|
// Test set column style on not exists worksheet.
|
||||||
assert.EqualError(t, f.SetColStyle("SheetN", "E", style), "sheet SheetN is not exist")
|
assert.EqualError(t, f.SetColStyle("SheetN", "E", styleID), "sheet SheetN is not exist")
|
||||||
// Test set column style with illegal cell coordinates.
|
// Test set column style with illegal cell coordinates.
|
||||||
assert.EqualError(t, f.SetColStyle("Sheet1", "*", style), newInvalidColumnNameError("*").Error())
|
assert.EqualError(t, f.SetColStyle("Sheet1", "*", styleID), newInvalidColumnNameError("*").Error())
|
||||||
assert.EqualError(t, f.SetColStyle("Sheet1", "A:*", style), newInvalidColumnNameError("*").Error())
|
assert.EqualError(t, f.SetColStyle("Sheet1", "A:*", styleID), newInvalidColumnNameError("*").Error())
|
||||||
|
|
||||||
assert.NoError(t, f.SetColStyle("Sheet1", "B", style))
|
assert.NoError(t, f.SetColStyle("Sheet1", "B", styleID))
|
||||||
// Test set column style with already exists column with style.
|
// Test set column style with already exists column with style.
|
||||||
assert.NoError(t, f.SetColStyle("Sheet1", "B", style))
|
assert.NoError(t, f.SetColStyle("Sheet1", "B", styleID))
|
||||||
assert.NoError(t, f.SetColStyle("Sheet1", "D:C", style))
|
assert.NoError(t, f.SetColStyle("Sheet1", "D:C", styleID))
|
||||||
|
ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml")
|
||||||
|
assert.True(t, ok)
|
||||||
|
ws.(*xlsxWorksheet).SheetData.Row[1].C[2].S = 0
|
||||||
|
cellStyleID, err := f.GetCellStyle("Sheet1", "C2")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, styleID, cellStyleID)
|
||||||
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetColStyle.xlsx")))
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetColStyle.xlsx")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -147,6 +147,7 @@ func TestOpenFile(t *testing.T) {
|
||||||
assert.NoError(t, f.SetCellValue("Sheet2", "G4", time.Now()))
|
assert.NoError(t, f.SetCellValue("Sheet2", "G4", time.Now()))
|
||||||
|
|
||||||
assert.NoError(t, f.SetCellValue("Sheet2", "G4", time.Now().UTC()))
|
assert.NoError(t, f.SetCellValue("Sheet2", "G4", time.Now().UTC()))
|
||||||
|
assert.EqualError(t, f.SetCellValue("SheetN", "A1", time.Now()), "sheet SheetN is not exist")
|
||||||
// 02:46:40
|
// 02:46:40
|
||||||
assert.NoError(t, f.SetCellValue("Sheet2", "G5", time.Duration(1e13)))
|
assert.NoError(t, f.SetCellValue("Sheet2", "G5", time.Duration(1e13)))
|
||||||
// Test completion column.
|
// Test completion column.
|
||||||
|
|
7
merge.go
7
merge.go
|
@ -11,7 +11,9 @@
|
||||||
|
|
||||||
package excelize
|
package excelize
|
||||||
|
|
||||||
import "strings"
|
import (
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
// Rect gets merged cell rectangle coordinates sequence.
|
// Rect gets merged cell rectangle coordinates sequence.
|
||||||
func (mc *xlsxMergeCell) Rect() ([]int, error) {
|
func (mc *xlsxMergeCell) Rect() ([]int, error) {
|
||||||
|
@ -68,7 +70,8 @@ func (f *File) MergeCell(sheet, hCell, vCell string) error {
|
||||||
ws.MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: ref, rect: rect}}}
|
ws.MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: ref, rect: rect}}}
|
||||||
}
|
}
|
||||||
ws.MergeCells.Count = len(ws.MergeCells.Cells)
|
ws.MergeCells.Count = len(ws.MergeCells.Cells)
|
||||||
return err
|
styleID, _ := f.GetCellStyle(sheet, hCell)
|
||||||
|
return f.SetCellStyle(sheet, hCell, vCell, styleID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnmergeCell provides a function to unmerge a given coordinate area.
|
// UnmergeCell provides a function to unmerge a given coordinate area.
|
||||||
|
|
|
@ -921,6 +921,9 @@ func TestSetRowStyle(t *testing.T) {
|
||||||
assert.EqualError(t, f.SetRowStyle("Sheet1", 1, 1, -1), newInvalidStyleID(-1).Error())
|
assert.EqualError(t, f.SetRowStyle("Sheet1", 1, 1, -1), newInvalidStyleID(-1).Error())
|
||||||
assert.EqualError(t, f.SetRowStyle("SheetN", 1, 1, styleID), "sheet SheetN is not exist")
|
assert.EqualError(t, f.SetRowStyle("SheetN", 1, 1, styleID), "sheet SheetN is not exist")
|
||||||
assert.NoError(t, f.SetRowStyle("Sheet1", 10, 1, styleID))
|
assert.NoError(t, f.SetRowStyle("Sheet1", 10, 1, styleID))
|
||||||
|
cellStyleID, err := f.GetCellStyle("Sheet1", "B2")
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, styleID, cellStyleID)
|
||||||
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetRowStyle.xlsx")))
|
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestSetRowStyle.xlsx")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2613,11 +2613,11 @@ func (f *File) GetCellStyle(sheet, axis string) (int, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
cellData, col, _, err := f.prepareCell(ws, sheet, axis)
|
cellData, col, row, err := f.prepareCell(ws, sheet, axis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return f.prepareCellStyle(ws, col, cellData.S), err
|
return f.prepareCellStyle(ws, col, row, cellData.S), err
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCellStyle provides a function to add style attribute for cells by given
|
// SetCellStyle provides a function to add style attribute for cells by given
|
||||||
|
|
Loading…
Reference in New Issue