فهرست منبع

- Resolve #485 use sheet index instead of ID
- added 3 internal function: getSheetID, getActiveSheetID, getSheetNameByID

xuri 5 سال پیش
والد
کامیت
1fe660df64
13فایلهای تغییر یافته به همراه136 افزوده شده و 74 حذف شده
  1. 7 2
      README.md
  2. 7 1
      README_zh.md
  3. 1 1
      cell.go
  4. 1 1
      chart.go
  5. 5 5
      chart_test.go
  6. 2 2
      col_test.go
  7. 1 1
      excelize.go
  8. 7 7
      excelize_test.go
  9. 2 2
      merge_test.go
  10. 4 4
      rows_test.go
  11. 94 43
      sheet.go
  12. 4 4
      sheet_test.go
  13. 1 1
      stream.go

+ 7 - 2
README.md

@@ -13,8 +13,7 @@
 
 ## 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.
-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/).
+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/).
 
 ## 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
 ```
 
+- 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
 
 Here is a minimal example usage that will create XLSX file.

+ 7 - 1
README_zh.md

@@ -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-376,ISO/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 Modules](https://blog.golang.org/using-go-modules) 管理软件包,请使用下面的命令来安装最新版本。
+
+```bash
+go get github.com/360EntSecGroup-Skylar/excelize/v2
+```
+
 ### 创建 Excel 文档
 
 下面是一个创建 Excel 文档的简单例子:

+ 1 - 1
cell.go

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

+ 1 - 1
chart.go

@@ -762,7 +762,7 @@ func (f *File) AddChart(sheet, cell, format string, combo ...string) error {
 // a chart.
 func (f *File) AddChartSheet(sheet, format string, combo ...string) error {
 	// 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")
 	}
 	formatSet, comboCharts, err := f.getFormatChart(format, combo)

+ 5 - 5
chart_test.go

@@ -12,7 +12,7 @@ import (
 
 func TestChartSize(t *testing.T) {
 	xlsx := NewFile()
-	sheet1 := xlsx.GetSheetName(1)
+	sheet1 := xlsx.GetSheetName(0)
 
 	categories := map[string]string{
 		"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"}}`))
 	// Test set the chartsheet as active sheet
-	var sheetID int
-	for idx, sheetName := range f.GetSheetMap() {
+	var sheetIdx int
+	for idx, sheetName := range f.GetSheetList() {
 		if sheetName != "Chart1" {
 			continue
 		}
-		sheetID = idx
+		sheetIdx = idx
 	}
-	f.SetActiveSheet(sheetID)
+	f.SetActiveSheet(sheetIdx)
 
 	// Test cell value on chartsheet
 	assert.EqualError(t, f.SetCellValue("Chart1", "A1", true), "sheet Chart1 is chart sheet")

+ 2 - 2
col_test.go

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

+ 1 - 1
excelize.go

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

+ 7 - 7
excelize_test.go

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

+ 2 - 2
merge_test.go

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

+ 4 - 4
rows_test.go

@@ -92,7 +92,7 @@ func TestRowsError(t *testing.T) {
 
 func TestRowHeight(t *testing.T) {
 	xlsx := NewFile()
-	sheet1 := xlsx.GetSheetName(1)
+	sheet1 := xlsx.GetSheetName(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) {
 	f := NewFile()
-	sheet1 := f.GetSheetName(1)
+	sheet1 := f.GetSheetName(0)
 	r, err := f.workSheetReader(sheet1)
 	assert.NoError(t, err)
 	const (
@@ -260,7 +260,7 @@ func TestRemoveRow(t *testing.T) {
 
 func TestInsertRow(t *testing.T) {
 	xlsx := NewFile()
-	sheet1 := xlsx.GetSheetName(1)
+	sheet1 := xlsx.GetSheetName(0)
 	r, err := xlsx.workSheetReader(sheet1)
 	assert.NoError(t, err)
 	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.
 func TestInsertRowInEmptyFile(t *testing.T) {
 	xlsx := NewFile()
-	sheet1 := xlsx.GetSheetName(1)
+	sheet1 := xlsx.GetSheetName(0)
 	r, err := xlsx.workSheetReader(sheet1)
 	assert.NoError(t, err)
 	assert.NoError(t, xlsx.InsertRow(sheet1, 1))

+ 94 - 43
sheet.go

@@ -34,7 +34,7 @@ import (
 // the number of sheets in the workbook (file) after appending the new sheet.
 func (f *File) NewSheet(name string) int {
 	// Check if the worksheet already exists
-	if f.GetSheetIndex(name) != 0 {
+	if f.GetSheetIndex(name) != -1 {
 		return f.SheetCount
 	}
 	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), "")
 	// Update xl/workbook.xml
 	f.setWorkbook(name, sheetID, rID)
-	return sheetID
+	return f.GetSheetIndex(name)
 }
 
 // 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
 // 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
-// worksheet numbers.
+// function GetSheetMap(). It should be greater or equal to 0 and less than
+// total worksheet numbers.
 func (f *File) SetActiveSheet(index int) {
-	if index < 1 {
-		index = 1
+	if index < 0 {
+		index = 0
 	}
 	wb := f.workbookReader()
-	for activeTab, sheet := range wb.Sheets.Sheet {
-		if sheet.SheetID == index {
+	for activeTab := range wb.Sheets.Sheet {
+		if activeTab == index {
 			if wb.BookViews == nil {
 				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)
 		if err != nil {
 			// Chartsheet
@@ -262,7 +262,22 @@ func (f *File) SetActiveSheet(index int) {
 
 // GetActiveSheetIndex 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) 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()
 	if wb != nil {
 		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
-// worksheet index. If given sheet index is invalid, will return an empty
+// getSheetNameByID provides a function to get worksheet name of XLSX by given
+// worksheet ID. If given sheet ID is invalid, will return an empty
 // string.
-func (f *File) GetSheetName(index int) string {
+func (f *File) getSheetNameByID(ID int) string {
 	wb := f.workbookReader()
-	if wb == nil || index < 1 {
+	if wb == nil || ID < 1 {
 		return ""
 	}
 	for _, sheet := range wb.Sheets.Sheet {
-		if index == sheet.SheetID {
+		if ID == sheet.SheetID {
 			return sheet.Name
 		}
 	}
 	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
 // sheet name. If given worksheet name is invalid, will return an integer type
-// value 0.
+// value -1.
 func (f *File) GetSheetIndex(name string) int {
-	wb := f.workbookReader()
-	if wb != nil {
-		for _, sheet := range wb.Sheets.Sheet {
-			if sheet.Name == trimSheetName(name) {
-				return sheet.SheetID
-			}
+	var idx = -1
+	for index, sheet := range f.GetSheetList() {
+		if sheet == trimSheetName(name) {
+			idx = index
 		}
 	}
-	return 0
+	return idx
 }
 
 // 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")
 //    if err != nil {
@@ -349,8 +387,20 @@ func (f *File) GetSheetMap() map[int]string {
 	return sheetMap
 }
 
-// getSheetMap provides a function to get worksheet and chartsheet name and
-// XML file path map of XLSX.
+// GetSheetList provides a function to get worksheet and chartsheet name list
+// 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 {
 	content := f.workbookReader()
 	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.
 // This function will be invalid when only the one worksheet is left.
 func (f *File) DeleteSheet(name string) {
-	if f.SheetCount == 1 || f.GetSheetIndex(name) == 0 {
+	if f.SheetCount == 1 || f.GetSheetIndex(name) == -1 {
 		return
 	}
 	sheetName := trimSheetName(name)
@@ -474,7 +524,7 @@ func (f *File) deleteSheetFromContentTypes(target string) {
 //    return err
 //
 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 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
 // target worksheet name.
 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 {
 		return err
 	}
 	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 {
 		worksheet.SheetViews.SheetView[0].TabSelected = false
 	}
@@ -496,8 +548,8 @@ func (f *File) copySheet(from, to int) error {
 	worksheet.TableParts = nil
 	worksheet.PageSetUp = nil
 	f.Sheet[path] = worksheet
-	toRels := "xl/worksheets/_rels/sheet" + strconv.Itoa(to) + ".xml.rels"
-	fromRels := "xl/worksheets/_rels/sheet" + strconv.Itoa(from) + ".xml.rels"
+	toRels := "xl/worksheets/_rels/sheet" + toSheetID + ".xml.rels"
+	fromRels := "xl/worksheets/_rels/sheet" + strconv.Itoa(f.getSheetID(fromSheet)) + ".xml.rels"
 	_, ok := f.XLSX[fromRels]
 	if ok {
 		f.XLSX[toRels] = f.XLSX[fromRels]
@@ -1303,7 +1355,7 @@ func (f *File) SetDefinedName(definedName *DefinedName) error {
 		Data:    definedName.RefersTo,
 	}
 	if definedName.Scope != "" {
-		if sheetID := f.GetSheetIndex(definedName.Scope); sheetID != 0 {
+		if sheetID := f.getSheetID(definedName.Scope); sheetID != 0 {
 			sheetID--
 			d.LocalSheetID = &sheetID
 		}
@@ -1312,7 +1364,7 @@ func (f *File) SetDefinedName(definedName *DefinedName) error {
 		for _, dn := range wb.DefinedNames.DefinedName {
 			var scope string
 			if dn.LocalSheetID != nil {
-				scope = f.GetSheetName(*dn.LocalSheetID + 1)
+				scope = f.getSheetNameByID(*dn.LocalSheetID + 1)
 			}
 			if scope == definedName.Scope && dn.Name == definedName.Name {
 				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 {
 			var scope string
 			if dn.LocalSheetID != nil {
-				scope = f.GetSheetName(*dn.LocalSheetID + 1)
+				scope = f.getSheetNameByID(*dn.LocalSheetID + 1)
 			}
 			if scope == definedName.Scope && dn.Name == definedName.Name {
 				wb.DefinedNames.DefinedName = append(wb.DefinedNames.DefinedName[:idx], wb.DefinedNames.DefinedName[idx+1:]...)
@@ -1367,7 +1419,7 @@ func (f *File) GetDefinedName() []DefinedName {
 				Scope:    "Workbook",
 			}
 			if dn.LocalSheetID != nil {
-				definedName.Scope = f.GetSheetName(*dn.LocalSheetID + 1)
+				definedName.Scope = f.getSheetNameByID(*dn.LocalSheetID + 1)
 			}
 			definedNames = append(definedNames, definedName)
 		}
@@ -1381,7 +1433,7 @@ func (f *File) GroupSheets(sheets []string) error {
 	// check an active worksheet in group worksheets
 	var inActiveSheet bool
 	activeSheet := f.GetActiveSheetIndex()
-	sheetMap := f.GetSheetMap()
+	sheetMap := f.GetSheetList()
 	for idx, sheetName := range sheetMap {
 		for _, s := range sheets {
 			if s == sheetName && idx == activeSheet {
@@ -1416,16 +1468,15 @@ func (f *File) GroupSheets(sheets []string) error {
 // UngroupSheets provides a function to ungroup worksheets.
 func (f *File) UngroupSheets() error {
 	activeSheet := f.GetActiveSheetIndex()
-	sheetMap := f.GetSheetMap()
-	for sheetID, sheet := range sheetMap {
-		if activeSheet == sheetID {
+	for index, sheet := range f.GetSheetList() {
+		if activeSheet == index {
 			continue
 		}
-		xlsx, _ := f.workSheetReader(sheet)
-		sheetViews := xlsx.SheetViews.SheetView
+		ws, _ := f.workSheetReader(sheet)
+		sheetViews := ws.SheetViews.SheetView
 		if len(sheetViews) > 0 {
 			for idx := range sheetViews {
-				xlsx.SheetViews.SheetView[idx].TabSelected = false
+				ws.SheetViews.SheetView[idx].TabSelected = false
 			}
 		}
 	}

+ 4 - 4
sheet_test.go

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

+ 1 - 1
stream.go

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