This is a breaking change closes #1332 (#1333)

This use `InsertRows` instead of `InsertRow`, and using `InsertCols` instead of `InsertCol`
This commit is contained in:
Kostya Privezentsev 2022-08-30 19:02:48 +03:00 committed by GitHub
parent bef49e40ee
commit 18cd63a548
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 35 deletions

View File

@ -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.

View File

@ -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))
}

19
col.go
View File

@ -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

View File

@ -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) {

18
rows.go
View File

@ -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

View File

@ -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")))
}