diff options
author | Kostya Privezentsev <privezentsev@gmail.com> | 2022-08-30 19:02:48 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-31 00:02:48 +0800 |
commit | 18cd63a548afa1abcddc86a998fdefa3b4cc60c1 (patch) | |
tree | 20abe577307ce6d072900f0b98fee57e06133eea | |
parent | bef49e40eec508a6413e80ee5df7df52f7827424 (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.go | 19 | ||||
-rw-r--r-- | adjust_test.go | 8 | ||||
-rw-r--r-- | col.go | 19 | ||||
-rw-r--r-- | col_test.go | 12 | ||||
-rw-r--r-- | rows.go | 18 | ||||
-rw-r--r-- | rows_test.go | 32 |
6 files changed, 73 insertions, 35 deletions
@@ -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)) } @@ -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) { @@ -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"))) } |