This closes #1293, add new function `GetColStyle`
- Fix generate workbook corruption after insert cols/rows in some case - Update unit tests - Update dependencies module
This commit is contained in:
parent
961a3e8933
commit
0c5cdfec18
28
adjust.go
28
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
|
// adjustColDimensions provides a function to update column dimensions when
|
||||||
// inserting or deleting rows or columns.
|
// inserting or deleting rows or columns.
|
||||||
func (f *File) adjustColDimensions(ws *xlsxWorksheet, col, offset int) error {
|
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 rowIdx := range ws.SheetData.Row {
|
||||||
for colIdx, v := range ws.SheetData.Row[rowIdx].C {
|
for colIdx, v := range ws.SheetData.Row[rowIdx].C {
|
||||||
cellCol, cellRow, _ := CellNameToCoordinates(v.R)
|
if cellCol, cellRow, _ := CellNameToCoordinates(v.R); col <= cellCol {
|
||||||
if col <= cellCol {
|
|
||||||
if newCol := cellCol + offset; newCol > 0 {
|
if newCol := cellCol + offset; newCol > 0 {
|
||||||
if newCol > MaxColumns {
|
|
||||||
return ErrColumnNumber
|
|
||||||
}
|
|
||||||
ws.SheetData.Row[rowIdx].C[colIdx].R, _ = CoordinatesToCellName(newCol, cellRow)
|
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
|
// adjustRowDimensions provides a function to update row dimensions when
|
||||||
// inserting or deleting rows or columns.
|
// inserting or deleting rows or columns.
|
||||||
func (f *File) adjustRowDimensions(ws *xlsxWorksheet, row, offset int) error {
|
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]
|
r := &ws.SheetData.Row[i]
|
||||||
if newRow := r.R + offset; r.R >= row && newRow > 0 {
|
if newRow := r.R + offset; r.R >= row && newRow > 0 {
|
||||||
if newRow >= TotalRows {
|
|
||||||
return ErrMaxRows
|
|
||||||
}
|
|
||||||
f.adjustSingleRowDimensions(r, newRow)
|
f.adjustSingleRowDimensions(r, newRow)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
26
col.go
26
col.go
|
@ -638,6 +638,30 @@ func (f *File) getColWidth(sheet string, col int) int {
|
||||||
return int(defaultColWidthPixels)
|
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
|
// GetColWidth provides a function to get column width by given worksheet name
|
||||||
// and column name.
|
// and column name.
|
||||||
func (f *File) GetColWidth(sheet, col string) (float64, error) {
|
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 {
|
if err != nil {
|
||||||
return defaultColWidth, err
|
return defaultColWidth, err
|
||||||
}
|
}
|
||||||
|
ws.Lock()
|
||||||
|
defer ws.Unlock()
|
||||||
if ws.Cols != nil {
|
if ws.Cols != nil {
|
||||||
var width float64
|
var width float64
|
||||||
for _, v := range ws.Cols.Col {
|
for _, v := range ws.Cols.Col {
|
||||||
|
|
20
col_test.go
20
col_test.go
|
@ -293,7 +293,7 @@ func TestSetColStyle(t *testing.T) {
|
||||||
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", styleID), "sheet SheetN does not exist")
|
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", "*", styleID), newInvalidColumnNameError("*").Error())
|
||||||
assert.EqualError(t, f.SetColStyle("Sheet1", "A:*", styleID), newInvalidColumnNameError("*").Error())
|
assert.EqualError(t, f.SetColStyle("Sheet1", "A:*", styleID), newInvalidColumnNameError("*").Error())
|
||||||
// Test set column style with invalid style ID.
|
// 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.EqualError(t, f.SetColStyle("Sheet1", "B", 10), newInvalidStyleID(10).Error())
|
||||||
|
|
||||||
assert.NoError(t, f.SetColStyle("Sheet1", "B", styleID))
|
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.
|
// Test set column style with already exists column with style.
|
||||||
assert.NoError(t, f.SetColStyle("Sheet1", "B", styleID))
|
assert.NoError(t, f.SetColStyle("Sheet1", "B", styleID))
|
||||||
assert.NoError(t, f.SetColStyle("Sheet1", "D:C", styleID))
|
assert.NoError(t, f.SetColStyle("Sheet1", "D:C", styleID))
|
||||||
|
@ -343,6 +347,20 @@ func TestColWidth(t *testing.T) {
|
||||||
convertRowHeightToPixels(0)
|
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) {
|
func TestInsertCols(t *testing.T) {
|
||||||
f := NewFile()
|
f := NewFile()
|
||||||
sheet1 := f.GetSheetName(0)
|
sheet1 := f.GetSheetName(0)
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -10,9 +10,9 @@ require (
|
||||||
github.com/stretchr/testify v1.7.1
|
github.com/stretchr/testify v1.7.1
|
||||||
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470
|
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470
|
||||||
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22
|
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/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
|
golang.org/x/text v0.3.7
|
||||||
gopkg.in/yaml.v3 v3.0.0 // indirect
|
gopkg.in/yaml.v3 v3.0.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
8
go.sum
8
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/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 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M=
|
||||||
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
|
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-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
|
||||||
golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
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 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE=
|
||||||
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
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-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E=
|
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
|
||||||
golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
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-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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
|
Loading…
Reference in New Issue