This closes #1076, add new function MoveSheet to support changing sheet order in the workbook (#1996)
- Add unit tests
This commit is contained in:
parent
bebb802069
commit
b23e5a26df
43
sheet.go
43
sheet.go
|
@ -600,6 +600,49 @@ func (f *File) DeleteSheet(sheet string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
// MoveSheet moves a sheet to a specified position in the workbook. The function
|
||||
// moves the source sheet before the target sheet. After moving, other sheets
|
||||
// will be shifted to the left or right. If the sheet is already at the target
|
||||
// position, the function will not perform any action. Not that this function
|
||||
// will be ungroup all sheets after moving. For example, move Sheet2 before
|
||||
// Sheet1:
|
||||
//
|
||||
// err := f.MoveSheet("Sheet2", "Sheet1")
|
||||
func (f *File) MoveSheet(source, target string) error {
|
||||
if strings.EqualFold(source, target) {
|
||||
return nil
|
||||
}
|
||||
wb, err := f.workbookReader()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sourceIdx, err := f.GetSheetIndex(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
targetIdx, err := f.GetSheetIndex(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if sourceIdx < 0 {
|
||||
return ErrSheetNotExist{source}
|
||||
}
|
||||
if targetIdx < 0 {
|
||||
return ErrSheetNotExist{target}
|
||||
}
|
||||
_ = f.UngroupSheets()
|
||||
activeSheetName := f.GetSheetName(f.GetActiveSheetIndex())
|
||||
sourceSheet := wb.Sheets.Sheet[sourceIdx]
|
||||
wb.Sheets.Sheet = append(wb.Sheets.Sheet[:sourceIdx], wb.Sheets.Sheet[sourceIdx+1:]...)
|
||||
if targetIdx > sourceIdx {
|
||||
targetIdx--
|
||||
}
|
||||
wb.Sheets.Sheet = append(wb.Sheets.Sheet[:targetIdx], append([]xlsxSheet{sourceSheet}, wb.Sheets.Sheet[targetIdx:]...)...)
|
||||
activeSheetIdx, _ := f.GetSheetIndex(activeSheetName)
|
||||
f.SetActiveSheet(activeSheetIdx)
|
||||
return err
|
||||
}
|
||||
|
||||
// deleteAndAdjustDefinedNames delete and adjust defined name in the workbook
|
||||
// by given worksheet ID.
|
||||
func deleteAndAdjustDefinedNames(wb *xlsxWorkbook, deleteLocalSheetID int) {
|
||||
|
|
|
@ -547,6 +547,43 @@ func TestDeleteSheet(t *testing.T) {
|
|||
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestDeleteSheet2.xlsx")))
|
||||
}
|
||||
|
||||
func TestMoveSheet(t *testing.T) {
|
||||
f := NewFile()
|
||||
defer f.Close()
|
||||
for i := 2; i < 6; i++ {
|
||||
_, err := f.NewSheet("Sheet" + strconv.Itoa(i))
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
assert.Equal(t, []string{"Sheet1", "Sheet2", "Sheet3", "Sheet4", "Sheet5"}, f.GetSheetList())
|
||||
|
||||
// Move target to first position
|
||||
assert.NoError(t, f.MoveSheet("Sheet2", "Sheet1"))
|
||||
assert.Equal(t, []string{"Sheet2", "Sheet1", "Sheet3", "Sheet4", "Sheet5"}, f.GetSheetList())
|
||||
assert.Equal(t, "Sheet1", f.GetSheetName(f.GetActiveSheetIndex()))
|
||||
|
||||
// Move target to last position
|
||||
assert.NoError(t, f.MoveSheet("Sheet2", "Sheet5"))
|
||||
assert.NoError(t, f.MoveSheet("Sheet5", "Sheet2"))
|
||||
assert.Equal(t, []string{"Sheet1", "Sheet3", "Sheet4", "Sheet5", "Sheet2"}, f.GetSheetList())
|
||||
|
||||
// Move target to same position
|
||||
assert.NoError(t, f.MoveSheet("Sheet1", "Sheet1"))
|
||||
assert.Equal(t, []string{"Sheet1", "Sheet3", "Sheet4", "Sheet5", "Sheet2"}, f.GetSheetList())
|
||||
|
||||
// Test move sheet with invalid sheet name
|
||||
assert.Equal(t, ErrSheetNameBlank, f.MoveSheet("", "Sheet2"))
|
||||
assert.Equal(t, ErrSheetNameBlank, f.MoveSheet("Sheet1", ""))
|
||||
|
||||
// Test move sheet on not exists worksheet
|
||||
assert.Equal(t, ErrSheetNotExist{"SheetN"}, f.MoveSheet("SheetN", "Sheet2"))
|
||||
assert.Equal(t, ErrSheetNotExist{"SheetN"}, f.MoveSheet("Sheet1", "SheetN"))
|
||||
|
||||
// Test move sheet with unsupported workbook charset
|
||||
f.WorkBook = nil
|
||||
f.Pkg.Store("xl/workbook.xml", MacintoshCyrillicCharset)
|
||||
assert.EqualError(t, f.MoveSheet("Sheet2", "Sheet1"), "XML syntax error on line 1: invalid UTF-8")
|
||||
}
|
||||
|
||||
func TestDeleteAndAdjustDefinedNames(t *testing.T) {
|
||||
deleteAndAdjustDefinedNames(nil, 0)
|
||||
deleteAndAdjustDefinedNames(&xlsxWorkbook{}, 0)
|
||||
|
|
Loading…
Reference in New Issue