Skip to content

Commit e2c7416

Browse files
authored
This closes #1565, support adjust formula when instering columns and rows (#1567)
1 parent 700af6a commit e2c7416

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

adjust.go

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ func (f *File) adjustColDimensions(ws *xlsxWorksheet, col, offset int) error {
131131
if cellCol, cellRow, _ := CellNameToCoordinates(v.R); col <= cellCol {
132132
if newCol := cellCol + offset; newCol > 0 {
133133
ws.SheetData.Row[rowIdx].C[colIdx].R, _ = CoordinatesToCellName(newCol, cellRow)
134+
_ = f.adjustFormula(ws.SheetData.Row[rowIdx].C[colIdx].F, columns, offset, false)
134135
}
135136
}
136137
}
@@ -152,21 +153,46 @@ func (f *File) adjustRowDimensions(ws *xlsxWorksheet, row, offset int) error {
152153
for i := 0; i < len(ws.SheetData.Row); i++ {
153154
r := &ws.SheetData.Row[i]
154155
if newRow := r.R + offset; r.R >= row && newRow > 0 {
155-
f.adjustSingleRowDimensions(r, newRow)
156+
f.adjustSingleRowDimensions(r, newRow, offset, false)
156157
}
157158
}
158159
return nil
159160
}
160161

161162
// adjustSingleRowDimensions provides a function to adjust single row dimensions.
162-
func (f *File) adjustSingleRowDimensions(r *xlsxRow, num int) {
163+
func (f *File) adjustSingleRowDimensions(r *xlsxRow, num, offset int, si bool) {
163164
r.R = num
164165
for i, col := range r.C {
165166
colName, _, _ := SplitCellName(col.R)
166167
r.C[i].R, _ = JoinCellName(colName, num)
168+
_ = f.adjustFormula(col.F, rows, offset, si)
167169
}
168170
}
169171

172+
// adjustFormula provides a function to adjust shared formula reference.
173+
func (f *File) adjustFormula(formula *xlsxF, dir adjustDirection, offset int, si bool) error {
174+
if formula != nil && formula.Ref != "" {
175+
coordinates, err := rangeRefToCoordinates(formula.Ref)
176+
if err != nil {
177+
return err
178+
}
179+
if dir == columns {
180+
coordinates[0] += offset
181+
coordinates[2] += offset
182+
} else {
183+
coordinates[1] += offset
184+
coordinates[3] += offset
185+
}
186+
if formula.Ref, err = f.coordinatesToRangeRef(coordinates); err != nil {
187+
return err
188+
}
189+
if si && formula.Si != nil {
190+
formula.Si = intPtr(*formula.Si + 1)
191+
}
192+
}
193+
return nil
194+
}
195+
170196
// adjustHyperlinks provides a function to update hyperlinks when inserting or
171197
// deleting rows or columns.
172198
func (f *File) adjustHyperlinks(ws *xlsxWorksheet, sheet string, dir adjustDirection, num, offset int) {

adjust_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,3 +445,23 @@ func TestAdjustCols(t *testing.T) {
445445

446446
assert.NoError(t, f.Close())
447447
}
448+
449+
func TestAdjustFormula(t *testing.T) {
450+
f := NewFile()
451+
formulaType, ref := STCellFormulaTypeShared, "C1:C5"
452+
assert.NoError(t, f.SetCellFormula("Sheet1", "C1", "=A1+B1", FormulaOpts{Ref: &ref, Type: &formulaType}))
453+
assert.NoError(t, f.DuplicateRowTo("Sheet1", 1, 10))
454+
assert.NoError(t, f.InsertCols("Sheet1", "B", 1))
455+
assert.NoError(t, f.InsertRows("Sheet1", 1, 1))
456+
for cell, expected := range map[string]string{"D2": "=A1+B1", "D3": "=A2+B2", "D11": "=A1+B1"} {
457+
formula, err := f.GetCellFormula("Sheet1", cell)
458+
assert.NoError(t, err)
459+
assert.Equal(t, expected, formula)
460+
}
461+
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAdjustFormula.xlsx")))
462+
assert.NoError(t, f.Close())
463+
464+
assert.NoError(t, f.adjustFormula(nil, rows, 0, false))
465+
assert.Equal(t, f.adjustFormula(&xlsxF{Ref: "-"}, rows, 0, false), ErrParameterInvalid)
466+
assert.Equal(t, f.adjustFormula(&xlsxF{Ref: "XFD1:XFD1"}, columns, 1, false), ErrColumnNumber)
467+
}

rows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ func (f *File) DuplicateRowTo(sheet string, row, row2 int) error {
662662
}
663663

664664
rowCopy.C = append(make([]xlsxC, 0, len(rowCopy.C)), rowCopy.C...)
665-
f.adjustSingleRowDimensions(&rowCopy, row2)
665+
f.adjustSingleRowDimensions(&rowCopy, row2, row2-row, true)
666666

667667
if idx2 != -1 {
668668
ws.SheetData.Row[idx2] = rowCopy

0 commit comments

Comments
 (0)