From 0c5cdfec1868f31f6e355cdcb0a91220bad80522 Mon Sep 17 00:00:00 2001 From: xuri Date: Wed, 7 Sep 2022 00:18:16 +0800 Subject: [PATCH] This closes #1293, add new function `GetColStyle` - Fix generate workbook corruption after insert cols/rows in some case - Update unit tests - Update dependencies module --- adjust.go | 28 +++++++++++++++++++--------- col.go | 26 ++++++++++++++++++++++++++ col_test.go | 20 +++++++++++++++++++- go.mod | 4 ++-- go.sum | 8 ++++---- 5 files changed, 70 insertions(+), 16 deletions(-) diff --git a/adjust.go b/adjust.go index fd570bb..5f4ee3d 100644 --- a/adjust.go +++ b/adjust.go @@ -73,14 +73,19 @@ func (f *File) adjustHelper(sheet string, dir adjustDirection, num, offset int) // adjustColDimensions provides a function to update column dimensions when // inserting or deleting rows or columns. func (f *File) adjustColDimensions(ws *xlsxWorksheet, col, offset int) error { + for rowIdx := range ws.SheetData.Row { + for _, v := range ws.SheetData.Row[rowIdx].C { + if cellCol, _, _ := CellNameToCoordinates(v.R); col <= cellCol { + if newCol := cellCol + offset; newCol > 0 && newCol > MaxColumns { + return ErrColumnNumber + } + } + } + } for rowIdx := range ws.SheetData.Row { for colIdx, v := range ws.SheetData.Row[rowIdx].C { - cellCol, cellRow, _ := CellNameToCoordinates(v.R) - if col <= cellCol { + if cellCol, cellRow, _ := CellNameToCoordinates(v.R); col <= cellCol { if newCol := cellCol + offset; newCol > 0 { - if newCol > MaxColumns { - return ErrColumnNumber - } ws.SheetData.Row[rowIdx].C[colIdx].R, _ = CoordinatesToCellName(newCol, cellRow) } } @@ -92,12 +97,17 @@ func (f *File) adjustColDimensions(ws *xlsxWorksheet, col, offset int) error { // adjustRowDimensions provides a function to update row dimensions when // inserting or deleting rows or columns. func (f *File) adjustRowDimensions(ws *xlsxWorksheet, row, offset int) error { - for i := range ws.SheetData.Row { + totalRows := len(ws.SheetData.Row) + if totalRows == 0 { + return nil + } + lastRow := &ws.SheetData.Row[totalRows-1] + if newRow := lastRow.R + offset; lastRow.R >= row && newRow > 0 && newRow >= TotalRows { + return ErrMaxRows + } + for i := 0; i < len(ws.SheetData.Row); i++ { r := &ws.SheetData.Row[i] if newRow := r.R + offset; r.R >= row && newRow > 0 { - if newRow >= TotalRows { - return ErrMaxRows - } f.adjustSingleRowDimensions(r, newRow) } } diff --git a/col.go b/col.go index c0deb58..b998f65 100644 --- a/col.go +++ b/col.go @@ -638,6 +638,30 @@ func (f *File) getColWidth(sheet string, col int) int { return int(defaultColWidthPixels) } +// GetColStyle provides a function to get column style ID by given worksheet +// name and column name. +func (f *File) GetColStyle(sheet, col string) (int, error) { + var styleID int + colNum, err := ColumnNameToNumber(col) + if err != nil { + return styleID, err + } + ws, err := f.workSheetReader(sheet) + if err != nil { + return styleID, err + } + ws.Lock() + defer ws.Unlock() + if ws.Cols != nil { + for _, v := range ws.Cols.Col { + if v.Min <= colNum && colNum <= v.Max { + styleID = v.Style + } + } + } + return styleID, err +} + // GetColWidth provides a function to get column width by given worksheet name // and column name. func (f *File) GetColWidth(sheet, col string) (float64, error) { @@ -649,6 +673,8 @@ func (f *File) GetColWidth(sheet, col string) (float64, error) { if err != nil { return defaultColWidth, err } + ws.Lock() + defer ws.Unlock() if ws.Cols != nil { var width float64 for _, v := range ws.Cols.Col { diff --git a/col_test.go b/col_test.go index 1076f31..f01ffdc 100644 --- a/col_test.go +++ b/col_test.go @@ -293,7 +293,7 @@ func TestSetColStyle(t *testing.T) { assert.NoError(t, err) // Test set column style on not exists worksheet. assert.EqualError(t, f.SetColStyle("SheetN", "E", styleID), "sheet SheetN does not exist") - // Test set column style with illegal cell coordinates. + // Test set column style with illegal column name. assert.EqualError(t, f.SetColStyle("Sheet1", "*", styleID), newInvalidColumnNameError("*").Error()) assert.EqualError(t, f.SetColStyle("Sheet1", "A:*", styleID), newInvalidColumnNameError("*").Error()) // Test set column style with invalid style ID. @@ -302,6 +302,10 @@ func TestSetColStyle(t *testing.T) { assert.EqualError(t, f.SetColStyle("Sheet1", "B", 10), newInvalidStyleID(10).Error()) assert.NoError(t, f.SetColStyle("Sheet1", "B", styleID)) + style, err := f.GetColStyle("Sheet1", "B") + assert.NoError(t, err) + assert.Equal(t, styleID, style) + // Test set column style with already exists column with style. assert.NoError(t, f.SetColStyle("Sheet1", "B", styleID)) assert.NoError(t, f.SetColStyle("Sheet1", "D:C", styleID)) @@ -343,6 +347,20 @@ func TestColWidth(t *testing.T) { convertRowHeightToPixels(0) } +func TestGetColStyle(t *testing.T) { + f := NewFile() + styleID, err := f.GetColStyle("Sheet1", "A") + assert.NoError(t, err) + assert.Equal(t, styleID, 0) + + // Test set column style on not exists worksheet. + _, err = f.GetColStyle("SheetN", "A") + assert.EqualError(t, err, "sheet SheetN does not exist") + // Test set column style with illegal column name. + _, err = f.GetColStyle("Sheet1", "*") + assert.EqualError(t, err, newInvalidColumnNameError("*").Error()) +} + func TestInsertCols(t *testing.T) { f := NewFile() sheet1 := f.GetSheetName(0) diff --git a/go.mod b/go.mod index b03e254..9d49dbe 100644 --- a/go.mod +++ b/go.mod @@ -10,9 +10,9 @@ require ( github.com/stretchr/testify v1.7.1 github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 - golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 + golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 - golang.org/x/net v0.0.0-20220812174116-3211cb980234 + golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b golang.org/x/text v0.3.7 gopkg.in/yaml.v3 v3.0.0 // indirect ) diff --git a/go.sum b/go.sum index 9512add..3f9cd78 100644 --- a/go.sum +++ b/go.sum @@ -17,13 +17,13 @@ github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj0 github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M= github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= -golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c= -golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM= +golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE= golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= -golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= +golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=