- Resolve #485 use sheet index instead of ID

-  added 3 internal function: getSheetID, getActiveSheetID, getSheetNameByID
formula
xuri 5 years ago
parent 10115b5d88
commit 1fe660df64
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7

@ -13,8 +13,7 @@
## Introduction ## Introduction
Excelize is a library written in pure Go providing a set of functions that allow you to write to and read from XLSX files. Supports reading and writing XLSX file generated by Microsoft Excel™ 2007 and later. Excelize is a library written in pure Go providing a set of functions that allow you to write to and read from XLSX / XLSM / XLTM files. Supports reading and writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. Supports complex components by high compatibility, and provided streaming API for generating or reading data from a worksheet with huge amounts of data. This library needs Go version 1.10 or later. The full API docs can be seen using go's built-in documentation tool, or online at [go.dev](https://pkg.go.dev/github.com/360EntSecGroup-Skylar/excelize/v2?tab=doc) and [docs reference](https://xuri.me/excelize/).
Supports saving a file without losing original charts of XLSX. This library needs Go version 1.10 or later. The full API docs can be seen using go's built-in documentation tool, or online at [go.dev](https://pkg.go.dev/github.com/360EntSecGroup-Skylar/excelize/v2?tab=doc) and [docs reference](https://xuri.me/excelize/).
## Basic Usage ## Basic Usage
@ -24,6 +23,12 @@ Supports saving a file without losing original charts of XLSX. This library need
go get github.com/360EntSecGroup-Skylar/excelize go get github.com/360EntSecGroup-Skylar/excelize
``` ```
- If your package management with [Go Modules](https://blog.golang.org/using-go-modules), please install with following command.
```bash
go get github.com/360EntSecGroup-Skylar/excelize/v2
```
### Create XLSX file ### Create XLSX file
Here is a minimal example usage that will create XLSX file. Here is a minimal example usage that will create XLSX file.

@ -13,7 +13,7 @@
## 简介 ## 简介
Excelize 是 Go 语言编写的用于操作 Office Excel 文档类库,基于 ECMA-376 Office OpenXML 标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的 XLSX 文档。相比较其他的开源类库Excelize 支持写入原本带有图片(表)、透视表和切片器等复杂样式的文档,还支持向 Excel 文档中插入图片与图表,并且在保存后不会丢失文档原有样式,可以应用于各类报表系统中。使用本类库要求使用的 Go 语言为 1.10 或更高版本,完整的 API 使用文档请访问 [go.dev](https://pkg.go.dev/github.com/360EntSecGroup-Skylar/excelize/v2?tab=doc) 或查看 [参考文档](https://xuri.me/excelize/)。 Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档。支持 XLSX / XLSM / XLTM 等多种文档格式,高度兼容带有样式、图片(表)、透视表、切片器等复杂组件的文档,并提供流式读写 API用于处理包含大规模数据的工作簿。可应用于各类报表平台、云计算、边缘计算等系统。使用本类库要求使用的 Go 语言为 1.10 或更高版本,完整的 API 使用文档请访问 [go.dev](https://pkg.go.dev/github.com/360EntSecGroup-Skylar/excelize/v2?tab=doc) 或查看 [参考文档](https://xuri.me/excelize/)。
## 快速上手 ## 快速上手
@ -23,6 +23,12 @@ Excelize 是 Go 语言编写的用于操作 Office Excel 文档类库,基于 E
go get github.com/360EntSecGroup-Skylar/excelize go get github.com/360EntSecGroup-Skylar/excelize
``` ```
- 如果您使用 [Go Modules](https://blog.golang.org/using-go-modules) 管理软件包,请使用下面的命令来安装最新版本。
```bash
go get github.com/360EntSecGroup-Skylar/excelize/v2
```
### 创建 Excel 文档 ### 创建 Excel 文档
下面是一个创建 Excel 文档的简单例子: 下面是一个创建 Excel 文档的简单例子:

@ -337,7 +337,7 @@ func (f *File) SetCellFormula(sheet, axis, formula string, opts ...FormulaOpts)
} }
if formula == "" { if formula == "" {
cellData.F = nil cellData.F = nil
f.deleteCalcChain(f.GetSheetIndex(sheet), axis) f.deleteCalcChain(f.getSheetID(sheet), axis)
return err return err
} }

@ -762,7 +762,7 @@ func (f *File) AddChart(sheet, cell, format string, combo ...string) error {
// a chart. // a chart.
func (f *File) AddChartSheet(sheet, format string, combo ...string) error { func (f *File) AddChartSheet(sheet, format string, combo ...string) error {
// Check if the worksheet already exists // Check if the worksheet already exists
if f.GetSheetIndex(sheet) != 0 { if f.GetSheetIndex(sheet) != -1 {
return errors.New("the same name worksheet already exists") return errors.New("the same name worksheet already exists")
} }
formatSet, comboCharts, err := f.getFormatChart(format, combo) formatSet, comboCharts, err := f.getFormatChart(format, combo)

@ -12,7 +12,7 @@ import (
func TestChartSize(t *testing.T) { func TestChartSize(t *testing.T) {
xlsx := NewFile() xlsx := NewFile()
sheet1 := xlsx.GetSheetName(1) sheet1 := xlsx.GetSheetName(0)
categories := map[string]string{ categories := map[string]string{
"A2": "Small", "A2": "Small",
@ -220,14 +220,14 @@ func TestAddChartSheet(t *testing.T) {
} }
assert.NoError(t, f.AddChartSheet("Chart1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`)) assert.NoError(t, f.AddChartSheet("Chart1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`))
// Test set the chartsheet as active sheet // Test set the chartsheet as active sheet
var sheetID int var sheetIdx int
for idx, sheetName := range f.GetSheetMap() { for idx, sheetName := range f.GetSheetList() {
if sheetName != "Chart1" { if sheetName != "Chart1" {
continue continue
} }
sheetID = idx sheetIdx = idx
} }
f.SetActiveSheet(sheetID) f.SetActiveSheet(sheetIdx)
// Test cell value on chartsheet // Test cell value on chartsheet
assert.EqualError(t, f.SetCellValue("Chart1", "A1", true), "sheet Chart1 is chart sheet") assert.EqualError(t, f.SetCellValue("Chart1", "A1", true), "sheet Chart1 is chart sheet")

@ -170,7 +170,7 @@ func TestColWidth(t *testing.T) {
func TestInsertCol(t *testing.T) { func TestInsertCol(t *testing.T) {
f := NewFile() f := NewFile()
sheet1 := f.GetSheetName(1) sheet1 := f.GetSheetName(0)
fillCells(f, sheet1, 10, 10) fillCells(f, sheet1, 10, 10)
@ -188,7 +188,7 @@ func TestInsertCol(t *testing.T) {
func TestRemoveCol(t *testing.T) { func TestRemoveCol(t *testing.T) {
f := NewFile() f := NewFile()
sheet1 := f.GetSheetName(1) sheet1 := f.GetSheetName(0)
fillCells(f, sheet1, 10, 15) fillCells(f, sheet1, 10, 15)

@ -268,7 +268,7 @@ func (f *File) UpdateLinkedValue() error {
wb := f.workbookReader() wb := f.workbookReader()
// recalculate formulas // recalculate formulas
wb.CalcPr = nil wb.CalcPr = nil
for _, name := range f.GetSheetMap() { for _, name := range f.GetSheetList() {
xlsx, err := f.workSheetReader(name) xlsx, err := f.workSheetReader(name)
if err != nil { if err != nil {
return err return err

@ -239,7 +239,7 @@ func TestBrokenFile(t *testing.T) {
// Test set active sheet without BookViews and Sheets maps in xl/workbook.xml. // Test set active sheet without BookViews and Sheets maps in xl/workbook.xml.
f3, err := OpenFile(filepath.Join("test", "BadWorkbook.xlsx")) f3, err := OpenFile(filepath.Join("test", "BadWorkbook.xlsx"))
f3.GetActiveSheetIndex() f3.GetActiveSheetIndex()
f3.SetActiveSheet(2) f3.SetActiveSheet(1)
assert.NoError(t, err) assert.NoError(t, err)
}) })
@ -908,7 +908,7 @@ func TestCopySheet(t *testing.T) {
} }
idx := f.NewSheet("CopySheet") idx := f.NewSheet("CopySheet")
assert.NoError(t, f.CopySheet(1, idx)) assert.NoError(t, f.CopySheet(0, idx))
assert.NoError(t, f.SetCellValue("CopySheet", "F1", "Hello")) assert.NoError(t, f.SetCellValue("CopySheet", "F1", "Hello"))
val, err := f.GetCellValue("Sheet1", "F1") val, err := f.GetCellValue("Sheet1", "F1")
@ -924,8 +924,8 @@ func TestCopySheetError(t *testing.T) {
t.FailNow() t.FailNow()
} }
assert.EqualError(t, f.copySheet(0, -1), "sheet is not exist") assert.EqualError(t, f.copySheet(-1, -2), "sheet is not exist")
if !assert.EqualError(t, f.CopySheet(0, -1), "invalid worksheet index") { if !assert.EqualError(t, f.CopySheet(-1, -2), "invalid worksheet index") {
t.FailNow() t.FailNow()
} }
@ -957,7 +957,7 @@ func TestSetSheetVisible(t *testing.T) {
func TestGetActiveSheetIndex(t *testing.T) { func TestGetActiveSheetIndex(t *testing.T) {
f := NewFile() f := NewFile()
f.WorkBook.BookViews = nil f.WorkBook.BookViews = nil
assert.Equal(t, 1, f.GetActiveSheetIndex()) assert.Equal(t, 0, f.GetActiveSheetIndex())
} }
func TestRelsWriter(t *testing.T) { func TestRelsWriter(t *testing.T) {
@ -974,7 +974,7 @@ func TestGetSheetView(t *testing.T) {
func TestConditionalFormat(t *testing.T) { func TestConditionalFormat(t *testing.T) {
f := NewFile() f := NewFile()
sheet1 := f.GetSheetName(1) sheet1 := f.GetSheetName(0)
fillCells(f, sheet1, 10, 15) fillCells(f, sheet1, 10, 15)
@ -1060,7 +1060,7 @@ func TestConditionalFormat(t *testing.T) {
func TestConditionalFormatError(t *testing.T) { func TestConditionalFormatError(t *testing.T) {
f := NewFile() f := NewFile()
sheet1 := f.GetSheetName(1) sheet1 := f.GetSheetName(0)
fillCells(f, sheet1, 10, 15) fillCells(f, sheet1, 10, 15)

@ -108,7 +108,7 @@ func TestGetMergeCells(t *testing.T) {
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
sheet1 := f.GetSheetName(1) sheet1 := f.GetSheetName(0)
mergeCells, err := f.GetMergeCells(sheet1) mergeCells, err := f.GetMergeCells(sheet1)
if !assert.Len(t, mergeCells, len(wants)) { if !assert.Len(t, mergeCells, len(wants)) {
@ -132,7 +132,7 @@ func TestUnmergeCell(t *testing.T) {
if !assert.NoError(t, err) { if !assert.NoError(t, err) {
t.FailNow() t.FailNow()
} }
sheet1 := f.GetSheetName(1) sheet1 := f.GetSheetName(0)
xlsx, err := f.workSheetReader(sheet1) xlsx, err := f.workSheetReader(sheet1)
assert.NoError(t, err) assert.NoError(t, err)

@ -92,7 +92,7 @@ func TestRowsError(t *testing.T) {
func TestRowHeight(t *testing.T) { func TestRowHeight(t *testing.T) {
xlsx := NewFile() xlsx := NewFile()
sheet1 := xlsx.GetSheetName(1) sheet1 := xlsx.GetSheetName(0)
assert.EqualError(t, xlsx.SetRowHeight(sheet1, 0, defaultRowHeightPixels+1.0), "invalid row number 0") assert.EqualError(t, xlsx.SetRowHeight(sheet1, 0, defaultRowHeightPixels+1.0), "invalid row number 0")
@ -199,7 +199,7 @@ func TestRowVisibility(t *testing.T) {
func TestRemoveRow(t *testing.T) { func TestRemoveRow(t *testing.T) {
f := NewFile() f := NewFile()
sheet1 := f.GetSheetName(1) sheet1 := f.GetSheetName(0)
r, err := f.workSheetReader(sheet1) r, err := f.workSheetReader(sheet1)
assert.NoError(t, err) assert.NoError(t, err)
const ( const (
@ -260,7 +260,7 @@ func TestRemoveRow(t *testing.T) {
func TestInsertRow(t *testing.T) { func TestInsertRow(t *testing.T) {
xlsx := NewFile() xlsx := NewFile()
sheet1 := xlsx.GetSheetName(1) sheet1 := xlsx.GetSheetName(0)
r, err := xlsx.workSheetReader(sheet1) r, err := xlsx.workSheetReader(sheet1)
assert.NoError(t, err) assert.NoError(t, err)
const ( const (
@ -292,7 +292,7 @@ func TestInsertRow(t *testing.T) {
// It is important for insert workflow to be constant to avoid side effect with functions related to internal structure. // 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 TestInsertRowInEmptyFile(t *testing.T) {
xlsx := NewFile() xlsx := NewFile()
sheet1 := xlsx.GetSheetName(1) sheet1 := xlsx.GetSheetName(0)
r, err := xlsx.workSheetReader(sheet1) r, err := xlsx.workSheetReader(sheet1)
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, xlsx.InsertRow(sheet1, 1)) assert.NoError(t, xlsx.InsertRow(sheet1, 1))

@ -34,7 +34,7 @@ import (
// the number of sheets in the workbook (file) after appending the new sheet. // the number of sheets in the workbook (file) after appending the new sheet.
func (f *File) NewSheet(name string) int { func (f *File) NewSheet(name string) int {
// Check if the worksheet already exists // Check if the worksheet already exists
if f.GetSheetIndex(name) != 0 { if f.GetSheetIndex(name) != -1 {
return f.SheetCount return f.SheetCount
} }
f.DeleteSheet(name) f.DeleteSheet(name)
@ -57,7 +57,7 @@ func (f *File) NewSheet(name string) int {
rID := f.addRels("xl/_rels/workbook.xml.rels", SourceRelationshipWorkSheet, fmt.Sprintf("worksheets/sheet%d.xml", sheetID), "") rID := f.addRels("xl/_rels/workbook.xml.rels", SourceRelationshipWorkSheet, fmt.Sprintf("worksheets/sheet%d.xml", sheetID), "")
// Update xl/workbook.xml // Update xl/workbook.xml
f.setWorkbook(name, sheetID, rID) f.setWorkbook(name, sheetID, rID)
return sheetID return f.GetSheetIndex(name)
} }
// contentTypesReader provides a function to get the pointer to the // contentTypesReader provides a function to get the pointer to the
@ -213,15 +213,15 @@ func replaceRelationshipsBytes(content []byte) []byte {
// SetActiveSheet provides function to set default active worksheet of XLSX by // SetActiveSheet provides function to set default active worksheet of XLSX by
// given index. Note that active index is different from the index returned by // given index. Note that active index is different from the index returned by
// function GetSheetMap(). It should be greater than 0 and less than total // function GetSheetMap(). It should be greater or equal to 0 and less than
// worksheet numbers. // total worksheet numbers.
func (f *File) SetActiveSheet(index int) { func (f *File) SetActiveSheet(index int) {
if index < 1 { if index < 0 {
index = 1 index = 0
} }
wb := f.workbookReader() wb := f.workbookReader()
for activeTab, sheet := range wb.Sheets.Sheet { for activeTab := range wb.Sheets.Sheet {
if sheet.SheetID == index { if activeTab == index {
if wb.BookViews == nil { if wb.BookViews == nil {
wb.BookViews = &xlsxBookViews{} wb.BookViews = &xlsxBookViews{}
} }
@ -234,7 +234,7 @@ func (f *File) SetActiveSheet(index int) {
} }
} }
} }
for idx, name := range f.GetSheetMap() { for idx, name := range f.GetSheetList() {
xlsx, err := f.workSheetReader(name) xlsx, err := f.workSheetReader(name)
if err != nil { if err != nil {
// Chartsheet // Chartsheet
@ -262,7 +262,22 @@ func (f *File) SetActiveSheet(index int) {
// GetActiveSheetIndex provides a function to get active sheet index of the // GetActiveSheetIndex provides a function to get active sheet index of the
// XLSX. If not found the active sheet will be return integer 0. // XLSX. If not found the active sheet will be return integer 0.
func (f *File) GetActiveSheetIndex() int { func (f *File) GetActiveSheetIndex() (index int) {
var sheetID = f.getActiveSheetID()
wb := f.workbookReader()
if wb != nil {
for idx, sheet := range wb.Sheets.Sheet {
if sheet.SheetID == sheetID {
index = idx
}
}
}
return
}
// getActiveSheetID provides a function to get active sheet index of the
// XLSX. If not found the active sheet will be return integer 0.
func (f *File) getActiveSheetID() int {
wb := f.workbookReader() wb := f.workbookReader()
if wb != nil { if wb != nil {
if wb.BookViews != nil && len(wb.BookViews.WorkBookView) > 0 { if wb.BookViews != nil && len(wb.BookViews.WorkBookView) > 0 {
@ -296,39 +311,62 @@ func (f *File) SetSheetName(oldName, newName string) {
} }
} }
// GetSheetName provides a function to get worksheet name of XLSX by given // getSheetNameByID provides a function to get worksheet name of XLSX by given
// worksheet index. If given sheet index is invalid, will return an empty // worksheet ID. If given sheet ID is invalid, will return an empty
// string. // string.
func (f *File) GetSheetName(index int) string { func (f *File) getSheetNameByID(ID int) string {
wb := f.workbookReader() wb := f.workbookReader()
if wb == nil || index < 1 { if wb == nil || ID < 1 {
return "" return ""
} }
for _, sheet := range wb.Sheets.Sheet { for _, sheet := range wb.Sheets.Sheet {
if index == sheet.SheetID { if ID == sheet.SheetID {
return sheet.Name return sheet.Name
} }
} }
return "" return ""
} }
// GetSheetName provides a function to get worksheet name of XLSX by given
// worksheet index. If given sheet index is invalid, will return an empty
// string.
func (f *File) GetSheetName(index int) (name string) {
for idx, sheet := range f.GetSheetList() {
if idx == index {
name = sheet
}
}
return
}
// getSheetID provides a function to get worksheet ID of XLSX by given
// sheet name. If given worksheet name is invalid, will return an integer type
// value -1.
func (f *File) getSheetID(name string) int {
var ID = -1
for sheetID, sheet := range f.GetSheetMap() {
if sheet == trimSheetName(name) {
ID = sheetID
}
}
return ID
}
// GetSheetIndex provides a function to get worksheet index of XLSX by given // GetSheetIndex provides a function to get worksheet index of XLSX by given
// sheet name. If given worksheet name is invalid, will return an integer type // sheet name. If given worksheet name is invalid, will return an integer type
// value 0. // value -1.
func (f *File) GetSheetIndex(name string) int { func (f *File) GetSheetIndex(name string) int {
wb := f.workbookReader() var idx = -1
if wb != nil { for index, sheet := range f.GetSheetList() {
for _, sheet := range wb.Sheets.Sheet { if sheet == trimSheetName(name) {
if sheet.Name == trimSheetName(name) { idx = index
return sheet.SheetID
}
} }
} }
return 0 return idx
} }
// GetSheetMap provides a function to get worksheet and chartsheet name and // GetSheetMap provides a function to get worksheet and chartsheet name and
// index map of XLSX. For example: // ID map of XLSX. For example:
// //
// f, err := excelize.OpenFile("Book1.xlsx") // f, err := excelize.OpenFile("Book1.xlsx")
// if err != nil { // if err != nil {
@ -349,8 +387,20 @@ func (f *File) GetSheetMap() map[int]string {
return sheetMap return sheetMap
} }
// getSheetMap provides a function to get worksheet and chartsheet name and // GetSheetList provides a function to get worksheet and chartsheet name list
// XML file path map of XLSX. // of workbook.
func (f *File) GetSheetList() (list []string) {
wb := f.workbookReader()
if wb != nil {
for _, sheet := range wb.Sheets.Sheet {
list = append(list, sheet.Name)
}
}
return
}
// getSheetMap provides a function to get worksheet name and XML file path map
// of XLSX.
func (f *File) getSheetMap() map[string]string { func (f *File) getSheetMap() map[string]string {
content := f.workbookReader() content := f.workbookReader()
rels := f.relsReader("xl/_rels/workbook.xml.rels") rels := f.relsReader("xl/_rels/workbook.xml.rels")
@ -397,7 +447,7 @@ func (f *File) SetSheetBackground(sheet, picture string) error {
// value of the deleted worksheet, it will cause a file error when you open it. // value of the deleted worksheet, it will cause a file error when you open it.
// This function will be invalid when only the one worksheet is left. // This function will be invalid when only the one worksheet is left.
func (f *File) DeleteSheet(name string) { func (f *File) DeleteSheet(name string) {
if f.SheetCount == 1 || f.GetSheetIndex(name) == 0 { if f.SheetCount == 1 || f.GetSheetIndex(name) == -1 {
return return
} }
sheetName := trimSheetName(name) sheetName := trimSheetName(name)
@ -474,7 +524,7 @@ func (f *File) deleteSheetFromContentTypes(target string) {
// return err // return err
// //
func (f *File) CopySheet(from, to int) error { func (f *File) CopySheet(from, to int) error {
if from < 1 || to < 1 || from == to || f.GetSheetName(from) == "" || f.GetSheetName(to) == "" { if from < 0 || to < 0 || from == to || f.GetSheetName(from) == "" || f.GetSheetName(to) == "" {
return errors.New("invalid worksheet index") return errors.New("invalid worksheet index")
} }
return f.copySheet(from, to) return f.copySheet(from, to)
@ -483,12 +533,14 @@ func (f *File) CopySheet(from, to int) error {
// copySheet provides a function to duplicate a worksheet by gave source and // copySheet provides a function to duplicate a worksheet by gave source and
// target worksheet name. // target worksheet name.
func (f *File) copySheet(from, to int) error { func (f *File) copySheet(from, to int) error {
sheet, err := f.workSheetReader(f.GetSheetName(from)) fromSheet := f.GetSheetName(from)
sheet, err := f.workSheetReader(fromSheet)
if err != nil { if err != nil {
return err return err
} }
worksheet := deepcopy.Copy(sheet).(*xlsxWorksheet) worksheet := deepcopy.Copy(sheet).(*xlsxWorksheet)
path := "xl/worksheets/sheet" + strconv.Itoa(to) + ".xml" toSheetID := strconv.Itoa(f.getSheetID(f.GetSheetName(to)))
path := "xl/worksheets/sheet" + toSheetID + ".xml"
if len(worksheet.SheetViews.SheetView) > 0 { if len(worksheet.SheetViews.SheetView) > 0 {
worksheet.SheetViews.SheetView[0].TabSelected = false worksheet.SheetViews.SheetView[0].TabSelected = false
} }
@ -496,8 +548,8 @@ func (f *File) copySheet(from, to int) error {
worksheet.TableParts = nil worksheet.TableParts = nil
worksheet.PageSetUp = nil worksheet.PageSetUp = nil
f.Sheet[path] = worksheet f.Sheet[path] = worksheet
toRels := "xl/worksheets/_rels/sheet" + strconv.Itoa(to) + ".xml.rels" toRels := "xl/worksheets/_rels/sheet" + toSheetID + ".xml.rels"
fromRels := "xl/worksheets/_rels/sheet" + strconv.Itoa(from) + ".xml.rels" fromRels := "xl/worksheets/_rels/sheet" + strconv.Itoa(f.getSheetID(fromSheet)) + ".xml.rels"
_, ok := f.XLSX[fromRels] _, ok := f.XLSX[fromRels]
if ok { if ok {
f.XLSX[toRels] = f.XLSX[fromRels] f.XLSX[toRels] = f.XLSX[fromRels]
@ -1303,7 +1355,7 @@ func (f *File) SetDefinedName(definedName *DefinedName) error {
Data: definedName.RefersTo, Data: definedName.RefersTo,
} }
if definedName.Scope != "" { if definedName.Scope != "" {
if sheetID := f.GetSheetIndex(definedName.Scope); sheetID != 0 { if sheetID := f.getSheetID(definedName.Scope); sheetID != 0 {
sheetID-- sheetID--
d.LocalSheetID = &sheetID d.LocalSheetID = &sheetID
} }
@ -1312,7 +1364,7 @@ func (f *File) SetDefinedName(definedName *DefinedName) error {
for _, dn := range wb.DefinedNames.DefinedName { for _, dn := range wb.DefinedNames.DefinedName {
var scope string var scope string
if dn.LocalSheetID != nil { if dn.LocalSheetID != nil {
scope = f.GetSheetName(*dn.LocalSheetID + 1) scope = f.getSheetNameByID(*dn.LocalSheetID + 1)
} }
if scope == definedName.Scope && dn.Name == definedName.Name { if scope == definedName.Scope && dn.Name == definedName.Name {
return errors.New("the same name already exists on the scope") return errors.New("the same name already exists on the scope")
@ -1342,7 +1394,7 @@ func (f *File) DeleteDefinedName(definedName *DefinedName) error {
for idx, dn := range wb.DefinedNames.DefinedName { for idx, dn := range wb.DefinedNames.DefinedName {
var scope string var scope string
if dn.LocalSheetID != nil { if dn.LocalSheetID != nil {
scope = f.GetSheetName(*dn.LocalSheetID + 1) scope = f.getSheetNameByID(*dn.LocalSheetID + 1)
} }
if scope == definedName.Scope && dn.Name == definedName.Name { if scope == definedName.Scope && dn.Name == definedName.Name {
wb.DefinedNames.DefinedName = append(wb.DefinedNames.DefinedName[:idx], wb.DefinedNames.DefinedName[idx+1:]...) wb.DefinedNames.DefinedName = append(wb.DefinedNames.DefinedName[:idx], wb.DefinedNames.DefinedName[idx+1:]...)
@ -1367,7 +1419,7 @@ func (f *File) GetDefinedName() []DefinedName {
Scope: "Workbook", Scope: "Workbook",
} }
if dn.LocalSheetID != nil { if dn.LocalSheetID != nil {
definedName.Scope = f.GetSheetName(*dn.LocalSheetID + 1) definedName.Scope = f.getSheetNameByID(*dn.LocalSheetID + 1)
} }
definedNames = append(definedNames, definedName) definedNames = append(definedNames, definedName)
} }
@ -1381,7 +1433,7 @@ func (f *File) GroupSheets(sheets []string) error {
// check an active worksheet in group worksheets // check an active worksheet in group worksheets
var inActiveSheet bool var inActiveSheet bool
activeSheet := f.GetActiveSheetIndex() activeSheet := f.GetActiveSheetIndex()
sheetMap := f.GetSheetMap() sheetMap := f.GetSheetList()
for idx, sheetName := range sheetMap { for idx, sheetName := range sheetMap {
for _, s := range sheets { for _, s := range sheets {
if s == sheetName && idx == activeSheet { if s == sheetName && idx == activeSheet {
@ -1416,16 +1468,15 @@ func (f *File) GroupSheets(sheets []string) error {
// UngroupSheets provides a function to ungroup worksheets. // UngroupSheets provides a function to ungroup worksheets.
func (f *File) UngroupSheets() error { func (f *File) UngroupSheets() error {
activeSheet := f.GetActiveSheetIndex() activeSheet := f.GetActiveSheetIndex()
sheetMap := f.GetSheetMap() for index, sheet := range f.GetSheetList() {
for sheetID, sheet := range sheetMap { if activeSheet == index {
if activeSheet == sheetID {
continue continue
} }
xlsx, _ := f.workSheetReader(sheet) ws, _ := f.workSheetReader(sheet)
sheetViews := xlsx.SheetViews.SheetView sheetViews := ws.SheetViews.SheetView
if len(sheetViews) > 0 { if len(sheetViews) > 0 {
for idx := range sheetViews { for idx := range sheetViews {
xlsx.SheetViews.SheetView[idx].TabSelected = false ws.SheetViews.SheetView[idx].TabSelected = false
} }
} }
} }

@ -303,10 +303,10 @@ func TestRemovePageBreak(t *testing.T) {
func TestGetSheetName(t *testing.T) { func TestGetSheetName(t *testing.T) {
f, _ := excelize.OpenFile(filepath.Join("test", "Book1.xlsx")) f, _ := excelize.OpenFile(filepath.Join("test", "Book1.xlsx"))
assert.Equal(t, "Sheet1", f.GetSheetName(1)) assert.Equal(t, "Sheet1", f.GetSheetName(0))
assert.Equal(t, "Sheet2", f.GetSheetName(2)) assert.Equal(t, "Sheet2", f.GetSheetName(1))
assert.Equal(t, "", f.GetSheetName(0)) assert.Equal(t, "", f.GetSheetName(-1))
assert.Equal(t, "", f.GetSheetName(3)) assert.Equal(t, "", f.GetSheetName(2))
} }
func TestGetSheetMap(t *testing.T) { func TestGetSheetMap(t *testing.T) {

@ -69,7 +69,7 @@ type StreamWriter struct {
// } // }
// //
func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) { func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
sheetID := f.GetSheetIndex(sheet) sheetID := f.getSheetID(sheet)
if sheetID == 0 { if sheetID == 0 {
return nil, fmt.Errorf("sheet %s is not exist", sheet) return nil, fmt.Errorf("sheet %s is not exist", sheet)
} }

Loading…
Cancel
Save