This closes #1565, support adjust formula when instering columns and rows (#1567)

This commit is contained in:
lidp20 2023-07-04 00:06:37 +08:00 committed by GitHub
parent 700af6a529
commit e2c7416292
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 3 deletions

View File

@ -131,6 +131,7 @@ func (f *File) adjustColDimensions(ws *xlsxWorksheet, col, offset int) error {
if cellCol, cellRow, _ := CellNameToCoordinates(v.R); col <= cellCol {
if newCol := cellCol + offset; newCol > 0 {
ws.SheetData.Row[rowIdx].C[colIdx].R, _ = CoordinatesToCellName(newCol, cellRow)
_ = f.adjustFormula(ws.SheetData.Row[rowIdx].C[colIdx].F, columns, offset, false)
}
}
}
@ -152,21 +153,46 @@ func (f *File) adjustRowDimensions(ws *xlsxWorksheet, row, offset int) error {
for i := 0; i < len(ws.SheetData.Row); i++ {
r := &ws.SheetData.Row[i]
if newRow := r.R + offset; r.R >= row && newRow > 0 {
f.adjustSingleRowDimensions(r, newRow)
f.adjustSingleRowDimensions(r, newRow, offset, false)
}
}
return nil
}
// adjustSingleRowDimensions provides a function to adjust single row dimensions.
func (f *File) adjustSingleRowDimensions(r *xlsxRow, num int) {
func (f *File) adjustSingleRowDimensions(r *xlsxRow, num, offset int, si bool) {
r.R = num
for i, col := range r.C {
colName, _, _ := SplitCellName(col.R)
r.C[i].R, _ = JoinCellName(colName, num)
_ = f.adjustFormula(col.F, rows, offset, si)
}
}
// adjustFormula provides a function to adjust shared formula reference.
func (f *File) adjustFormula(formula *xlsxF, dir adjustDirection, offset int, si bool) error {
if formula != nil && formula.Ref != "" {
coordinates, err := rangeRefToCoordinates(formula.Ref)
if err != nil {
return err
}
if dir == columns {
coordinates[0] += offset
coordinates[2] += offset
} else {
coordinates[1] += offset
coordinates[3] += offset
}
if formula.Ref, err = f.coordinatesToRangeRef(coordinates); err != nil {
return err
}
if si && formula.Si != nil {
formula.Si = intPtr(*formula.Si + 1)
}
}
return nil
}
// adjustHyperlinks provides a function to update hyperlinks when inserting or
// deleting rows or columns.
func (f *File) adjustHyperlinks(ws *xlsxWorksheet, sheet string, dir adjustDirection, num, offset int) {

View File

@ -445,3 +445,23 @@ func TestAdjustCols(t *testing.T) {
assert.NoError(t, f.Close())
}
func TestAdjustFormula(t *testing.T) {
f := NewFile()
formulaType, ref := STCellFormulaTypeShared, "C1:C5"
assert.NoError(t, f.SetCellFormula("Sheet1", "C1", "=A1+B1", FormulaOpts{Ref: &ref, Type: &formulaType}))
assert.NoError(t, f.DuplicateRowTo("Sheet1", 1, 10))
assert.NoError(t, f.InsertCols("Sheet1", "B", 1))
assert.NoError(t, f.InsertRows("Sheet1", 1, 1))
for cell, expected := range map[string]string{"D2": "=A1+B1", "D3": "=A2+B2", "D11": "=A1+B1"} {
formula, err := f.GetCellFormula("Sheet1", cell)
assert.NoError(t, err)
assert.Equal(t, expected, formula)
}
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAdjustFormula.xlsx")))
assert.NoError(t, f.Close())
assert.NoError(t, f.adjustFormula(nil, rows, 0, false))
assert.Equal(t, f.adjustFormula(&xlsxF{Ref: "-"}, rows, 0, false), ErrParameterInvalid)
assert.Equal(t, f.adjustFormula(&xlsxF{Ref: "XFD1:XFD1"}, columns, 1, false), ErrColumnNumber)
}

View File

@ -662,7 +662,7 @@ func (f *File) DuplicateRowTo(sheet string, row, row2 int) error {
}
rowCopy.C = append(make([]xlsxC, 0, len(rowCopy.C)), rowCopy.C...)
f.adjustSingleRowDimensions(&rowCopy, row2)
f.adjustSingleRowDimensions(&rowCopy, row2, row2-row, true)
if idx2 != -1 {
ws.SheetData.Row[idx2] = rowCopy