summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Privezentsev <privezentsev@gmail.com>2022-08-30 19:02:48 +0300
committerGitHub <noreply@github.com>2022-08-31 00:02:48 +0800
commit18cd63a548afa1abcddc86a998fdefa3b4cc60c1 (patch)
tree20abe577307ce6d072900f0b98fee57e06133eea
parentbef49e40eec508a6413e80ee5df7df52f7827424 (diff)
This is a breaking change closes #1332 (#1333)
This use `InsertRows` instead of `InsertRow`, and using `InsertCols` instead of `InsertCol`
-rw-r--r--adjust.go19
-rw-r--r--adjust_test.go8
-rw-r--r--col.go19
-rw-r--r--col_test.go12
-rw-r--r--rows.go18
-rw-r--r--rows_test.go32
6 files changed, 73 insertions, 35 deletions
diff --git a/adjust.go b/adjust.go
index 99d2850..fd570bb 100644
--- a/adjust.go
+++ b/adjust.go
@@ -42,9 +42,12 @@ func (f *File) adjustHelper(sheet string, dir adjustDirection, num, offset int)
}
sheetID := f.getSheetID(sheet)
if dir == rows {
- f.adjustRowDimensions(ws, num, offset)
+ err = f.adjustRowDimensions(ws, num, offset)
} else {
- f.adjustColDimensions(ws, num, offset)
+ err = f.adjustColDimensions(ws, num, offset)
+ }
+ if err != nil {
+ return err
}
f.adjustHyperlinks(ws, sheet, dir, num, offset)
f.adjustTable(ws, sheet, dir, num, offset)
@@ -69,28 +72,36 @@ 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) {
+func (f *File) adjustColDimensions(ws *xlsxWorksheet, col, offset int) error {
for rowIdx := range ws.SheetData.Row {
for colIdx, v := range ws.SheetData.Row[rowIdx].C {
cellCol, cellRow, _ := CellNameToCoordinates(v.R)
if col <= cellCol {
if newCol := cellCol + offset; newCol > 0 {
+ if newCol > MaxColumns {
+ return ErrColumnNumber
+ }
ws.SheetData.Row[rowIdx].C[colIdx].R, _ = CoordinatesToCellName(newCol, cellRow)
}
}
}
}
+ return nil
}
// adjustRowDimensions provides a function to update row dimensions when
// inserting or deleting rows or columns.
-func (f *File) adjustRowDimensions(ws *xlsxWorksheet, row, offset int) {
+func (f *File) adjustRowDimensions(ws *xlsxWorksheet, row, offset int) error {
for i := range ws.SheetData.Row {
r := &ws.SheetData.Row[i]
if newRow := r.R + offset; r.R >= row && newRow > 0 {
+ if newRow >= TotalRows {
+ return ErrMaxRows
+ }
f.adjustSingleRowDimensions(r, newRow)
}
}
+ return nil
}
// adjustSingleRowDimensions provides a function to adjust single row dimensions.
diff --git a/adjust_test.go b/adjust_test.go
index c350101..aa374da 100644
--- a/adjust_test.go
+++ b/adjust_test.go
@@ -349,11 +349,11 @@ func TestAdjustCalcChain(t *testing.T) {
{R: "B2", I: 2}, {R: "B2", I: 1},
},
}
- assert.NoError(t, f.InsertCol("Sheet1", "A"))
- assert.NoError(t, f.InsertRow("Sheet1", 1))
+ assert.NoError(t, f.InsertCols("Sheet1", "A", 1))
+ assert.NoError(t, f.InsertRows("Sheet1", 1, 1))
f.CalcChain.C[1].R = "invalid coordinates"
- assert.EqualError(t, f.InsertCol("Sheet1", "A"), newCellNameToCoordinatesError("invalid coordinates", newInvalidCellNameError("invalid coordinates")).Error())
+ assert.EqualError(t, f.InsertCols("Sheet1", "A", 1), newCellNameToCoordinatesError("invalid coordinates", newInvalidCellNameError("invalid coordinates")).Error())
f.CalcChain = nil
- assert.NoError(t, f.InsertCol("Sheet1", "A"))
+ assert.NoError(t, f.InsertCols("Sheet1", "A", 1))
}
diff --git a/col.go b/col.go
index 248e22c..f51336d 100644
--- a/col.go
+++ b/col.go
@@ -657,16 +657,25 @@ func (f *File) GetColWidth(sheet, col string) (float64, error) {
return defaultColWidth, err
}
-// InsertCol provides a function to insert a new column before given column
-// index. For example, create a new column before column C in Sheet1:
+// InsertCols provides a function to insert new columns before the given column
+// name and number of columns. For example, create two columns before column
+// C in Sheet1:
//
-// err := f.InsertCol("Sheet1", "C")
-func (f *File) InsertCol(sheet, col string) error {
+// err := f.InsertCols("Sheet1", "C", 2)
+//
+// Use this method with caution, which will affect changes in references such
+// as formulas, charts, and so on. If there is any referenced value of the
+// worksheet, it will cause a file error when you open it. The excelize only
+// partially updates these references currently.
+func (f *File) InsertCols(sheet, col string, n int) error {
num, err := ColumnNameToNumber(col)
if err != nil {
return err
}
- return f.adjustHelper(sheet, columns, num, 1)
+ if n < 1 || n > MaxColumns {
+ return ErrColumnNumber
+ }
+ return f.adjustHelper(sheet, columns, num, n)
}
// RemoveCol provides a function to remove single column by given worksheet
diff --git a/col_test.go b/col_test.go
index eb97c12..b7d3823 100644
--- a/col_test.go
+++ b/col_test.go
@@ -339,7 +339,7 @@ func TestColWidth(t *testing.T) {
convertRowHeightToPixels(0)
}
-func TestInsertCol(t *testing.T) {
+func TestInsertCols(t *testing.T) {
f := NewFile()
sheet1 := f.GetSheetName(0)
@@ -349,12 +349,16 @@ func TestInsertCol(t *testing.T) {
assert.NoError(t, f.MergeCell(sheet1, "A1", "C3"))
assert.NoError(t, f.AutoFilter(sheet1, "A2", "B2", `{"column":"B","expression":"x != blanks"}`))
- assert.NoError(t, f.InsertCol(sheet1, "A"))
+ assert.NoError(t, f.InsertCols(sheet1, "A", 1))
// Test insert column with illegal cell coordinates.
- assert.EqualError(t, f.InsertCol("Sheet1", "*"), newInvalidColumnNameError("*").Error())
+ assert.EqualError(t, f.InsertCols(sheet1, "*", 1), newInvalidColumnNameError("*").Error())
- assert.NoError(t, f.SaveAs(filepath.Join("test", "TestInsertCol.xlsx")))
+ assert.EqualError(t, f.InsertCols(sheet1, "A", 0), ErrColumnNumber.Error())
+ assert.EqualError(t, f.InsertCols(sheet1, "A", MaxColumns), ErrColumnNumber.Error())
+ assert.EqualError(t, f.InsertCols(sheet1, "A", MaxColumns-10), ErrColumnNumber.Error())
+
+ assert.NoError(t, f.SaveAs(filepath.Join("test", "TestInsertCols.xlsx")))
}
func TestRemoveCol(t *testing.T) {
diff --git a/rows.go b/rows.go
index 7e2d677..9269ac6 100644
--- a/rows.go
+++ b/rows.go
@@ -622,21 +622,27 @@ func (f *File) RemoveRow(sheet string, row int) error {
return f.adjustHelper(sheet, rows, row, -1)
}
-// InsertRow provides a function to insert a new row after given Excel row
-// number starting from 1. For example, create a new row before row 3 in
-// Sheet1:
+// InsertRows provides a function to insert new rows after the given Excel row
+// number starting from 1 and number of rows. For example, create two rows
+// before row 3 in Sheet1:
//
-// err := f.InsertRow("Sheet1", 3)
+// err := f.InsertRows("Sheet1", 3, 2)
//
// Use this method with caution, which will affect changes in references such
// as formulas, charts, and so on. If there is any referenced value of the
// worksheet, it will cause a file error when you open it. The excelize only
// partially updates these references currently.
-func (f *File) InsertRow(sheet string, row int) error {
+func (f *File) InsertRows(sheet string, row, n int) error {
if row < 1 {
return newInvalidRowNumberError(row)
}
- return f.adjustHelper(sheet, rows, row, 1)
+ if row >= TotalRows || n >= TotalRows {
+ return ErrMaxRows
+ }
+ if n < 1 {
+ return ErrParameterInvalid
+ }
+ return f.adjustHelper(sheet, rows, row, n)
}
// DuplicateRow inserts a copy of specified row (by its Excel row number) below
diff --git a/rows_test.go b/rows_test.go
index cac142b..829a27a 100644
--- a/rows_test.go
+++ b/rows_test.go
@@ -318,7 +318,7 @@ func TestRemoveRow(t *testing.T) {
assert.EqualError(t, f.RemoveRow("SheetN", 1), `sheet SheetN does not exist`)
}
-func TestInsertRow(t *testing.T) {
+func TestInsertRows(t *testing.T) {
f := NewFile()
sheet1 := f.GetSheetName(0)
r, err := f.workSheetReader(sheet1)
@@ -331,36 +331,44 @@ func TestInsertRow(t *testing.T) {
assert.NoError(t, f.SetCellHyperLink(sheet1, "A5", "https://github.com/xuri/excelize", "External"))
- assert.EqualError(t, f.InsertRow(sheet1, -1), newInvalidRowNumberError(-1).Error())
-
- assert.EqualError(t, f.InsertRow(sheet1, 0), newInvalidRowNumberError(0).Error())
-
- assert.NoError(t, f.InsertRow(sheet1, 1))
+ assert.NoError(t, f.InsertRows(sheet1, 1, 1))
if !assert.Len(t, r.SheetData.Row, rowCount+1) {
t.FailNow()
}
- assert.NoError(t, f.InsertRow(sheet1, 4))
+ assert.NoError(t, f.InsertRows(sheet1, 4, 1))
if !assert.Len(t, r.SheetData.Row, rowCount+2) {
t.FailNow()
}
- assert.NoError(t, f.SaveAs(filepath.Join("test", "TestInsertRow.xlsx")))
+ assert.NoError(t, f.InsertRows(sheet1, 4, 2))
+ if !assert.Len(t, r.SheetData.Row, rowCount+4) {
+ t.FailNow()
+ }
+
+ assert.EqualError(t, f.InsertRows(sheet1, -1, 1), newInvalidRowNumberError(-1).Error())
+ assert.EqualError(t, f.InsertRows(sheet1, 0, 1), newInvalidRowNumberError(0).Error())
+ assert.EqualError(t, f.InsertRows(sheet1, 4, 0), ErrParameterInvalid.Error())
+ assert.EqualError(t, f.InsertRows(sheet1, 4, TotalRows), ErrMaxRows.Error())
+ assert.EqualError(t, f.InsertRows(sheet1, 4, TotalRows-5), ErrMaxRows.Error())
+ assert.EqualError(t, f.InsertRows(sheet1, TotalRows, 1), ErrMaxRows.Error())
+
+ assert.NoError(t, f.SaveAs(filepath.Join("test", "TestInsertRows.xlsx")))
}
// Test internal structure state after insert operations. It is important
// for insert workflow to be constant to avoid side effect with functions
// related to internal structure.
-func TestInsertRowInEmptyFile(t *testing.T) {
+func TestInsertRowsInEmptyFile(t *testing.T) {
f := NewFile()
sheet1 := f.GetSheetName(0)
r, err := f.workSheetReader(sheet1)
assert.NoError(t, err)
- assert.NoError(t, f.InsertRow(sheet1, 1))
+ assert.NoError(t, f.InsertRows(sheet1, 1, 1))
assert.Len(t, r.SheetData.Row, 0)
- assert.NoError(t, f.InsertRow(sheet1, 2))
+ assert.NoError(t, f.InsertRows(sheet1, 2, 1))
assert.Len(t, r.SheetData.Row, 0)
- assert.NoError(t, f.InsertRow(sheet1, 99))
+ assert.NoError(t, f.InsertRows(sheet1, 99, 1))
assert.Len(t, r.SheetData.Row, 0)
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestInsertRowInEmptyFile.xlsx")))
}