func (f *File) GetSheetIndex(name string) int {
	content := f.workbookReader()
	rels := f.workbookRelsReader()
	for _, v := range content.Sheets.Sheet {
		if v.Name == name {
			for _, rel := range rels.Relationships {
				if v.ID == rel.ID {
					rID, _ := strconv.Atoi(strings.TrimSuffix(strings.TrimPrefix(rel.Target, "worksheets/sheet"), ".xml"))
					return rID
				}
			}
		}
	}
	return 0
}
GetSheetIndex provides function to get worksheet index of XLSX by given sheet
name. If given worksheet name is invalid, will return an integer type value
0.
package excelize
import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"errors"
	"os"
	"path"
	"strconv"
	"strings"
	"unicode/utf8"
)
func (f *File) NewSheet(name string) int {
	if f.GetSheetIndex(name) != 0 {
		return f.SheetCount
	}
	f.SheetCount++
	f.setAppXML()
	f.setContentTypes(f.SheetCount)
	f.setSheet(f.SheetCount, name)
	rID := f.addXlsxWorkbookRels(f.SheetCount)
	f.setWorkbook(name, rID)
	return f.SheetCount
}
func (f *File) contentTypesReader() *xlsxTypes {
	if f.ContentTypes == nil {
		var content xlsxTypes
		xml.Unmarshal([]byte(f.readXML("[Content_Types].xml")), &content)
		f.ContentTypes = &content
	}
	return f.ContentTypes
}
func (f *File) contentTypesWriter() {
	if f.ContentTypes != nil {
		output, _ := xml.Marshal(f.ContentTypes)
		f.saveFileList("[Content_Types].xml", output)
	}
}
func (f *File) workbookReader() *xlsxWorkbook {
	if f.WorkBook == nil {
		var content xlsxWorkbook
		xml.Unmarshal([]byte(f.readXML("xl/workbook.xml")), &content)
		f.WorkBook = &content
	}
	return f.WorkBook
}
func (f *File) workbookWriter() {
	if f.WorkBook != nil {
		output, _ := xml.Marshal(f.WorkBook)
		f.saveFileList("xl/workbook.xml", replaceRelationshipsNameSpaceBytes(output))
	}
}
func (f *File) worksheetWriter() {
	for path, sheet := range f.Sheet {
		if sheet != nil {
			for k, v := range sheet.SheetData.Row {
				f.Sheet[path].SheetData.Row[k].C = trimCell(v.C)
			}
			output, _ := xml.Marshal(sheet)
			f.saveFileList(path, replaceWorkSheetsRelationshipsNameSpaceBytes(output))
			ok := f.checked[path]
			if ok {
				f.checked[path] = false
			}
		}
	}
}
func trimCell(column []xlsxC) []xlsxC {
	col := []xlsxC{}
	for _, c := range column {
		if c.S != 0 || c.V != "" || c.F != nil || c.T != "" {
			col = append(col, c)
		}
	}
	return col
}
func (f *File) setContentTypes(index int) {
	content := f.contentTypesReader()
	content.Overrides = append(content.Overrides, xlsxOverride{
		PartName:    "/xl/worksheets/sheet" + strconv.Itoa(index) + ".xml",
		ContentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
	})
}
func (f *File) setSheet(index int, name string) {
	var xlsx xlsxWorksheet
	xlsx.Dimension.Ref = "A1"
	xlsx.SheetViews.SheetView = append(xlsx.SheetViews.SheetView, xlsxSheetView{
		WorkbookViewID: 0,
	})
	path := "xl/worksheets/sheet" + strconv.Itoa(index) + ".xml"
	f.sheetMap[trimSheetName(name)] = path
	f.Sheet[path] = &xlsx
}
func (f *File) setWorkbook(name string, rid int) {
	content := f.workbookReader()
	content.Sheets.Sheet = append(content.Sheets.Sheet, xlsxSheet{
		Name:    trimSheetName(name),
		SheetID: strconv.Itoa(rid),
		ID:      "rId" + strconv.Itoa(rid),
	})
}
func (f *File) workbookRelsReader() *xlsxWorkbookRels {
	if f.WorkBookRels == nil {
		var content xlsxWorkbookRels
		xml.Unmarshal([]byte(f.readXML("xl/_rels/workbook.xml.rels")), &content)
		f.WorkBookRels = &content
	}
	return f.WorkBookRels
}
func (f *File) workbookRelsWriter() {
	if f.WorkBookRels != nil {
		output, _ := xml.Marshal(f.WorkBookRels)
		f.saveFileList("xl/_rels/workbook.xml.rels", output)
	}
}
func (f *File) addXlsxWorkbookRels(sheet int) int {
	content := f.workbookRelsReader()
	rID := 0
	for _, v := range content.Relationships {
		t, _ := strconv.Atoi(strings.TrimPrefix(v.ID, "rId"))
		if t > rID {
			rID = t
		}
	}
	rID++
	ID := bytes.Buffer{}
	ID.WriteString("rId")
	ID.WriteString(strconv.Itoa(rID))
	target := bytes.Buffer{}
	target.WriteString("worksheets/sheet")
	target.WriteString(strconv.Itoa(sheet))
	target.WriteString(".xml")
	content.Relationships = append(content.Relationships, xlsxWorkbookRelation{
		ID:     ID.String(),
		Target: target.String(),
		Type:   SourceRelationshipWorkSheet,
	})
	return rID
}
func (f *File) setAppXML() {
	f.saveFileList("docProps/app.xml", []byte(templateDocpropsApp))
}
func replaceRelationshipsNameSpace(workbookMarshal string) string {
	oldXmlns := `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`
	newXmlns := `<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">`
	return strings.Replace(workbookMarshal, oldXmlns, newXmlns, -1)
}
func replaceRelationshipsNameSpaceBytes(workbookMarshal []byte) []byte {
	oldXmlns := []byte(`<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`)
	newXmlns := []byte(`<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">`)
	return bytes.Replace(workbookMarshal, oldXmlns, newXmlns, -1)
}
func (f *File) SetActiveSheet(index int) {
	if index < 1 {
		index = 1
	}
	index--
	content := f.workbookReader()
	if len(content.BookViews.WorkBookView) > 0 {
		content.BookViews.WorkBookView[0].ActiveTab = index
	} else {
		content.BookViews.WorkBookView = append(content.BookViews.WorkBookView, xlsxWorkBookView{
			ActiveTab: index,
		})
	}
	index++
	for idx, name := range f.GetSheetMap() {
		xlsx := f.workSheetReader(name)
		if index == idx {
			if len(xlsx.SheetViews.SheetView) > 0 {
				xlsx.SheetViews.SheetView[0].TabSelected = true
			} else {
				xlsx.SheetViews.SheetView = append(xlsx.SheetViews.SheetView, xlsxSheetView{
					TabSelected: true,
				})
			}
		} else {
			if len(xlsx.SheetViews.SheetView) > 0 {
				xlsx.SheetViews.SheetView[0].TabSelected = false
			}
		}
	}
}
func (f *File) GetActiveSheetIndex() int {
	buffer := bytes.Buffer{}
	content := f.workbookReader()
	for _, v := range content.Sheets.Sheet {
		xlsx := xlsxWorksheet{}
		buffer.WriteString("xl/worksheets/sheet")
		buffer.WriteString(strings.TrimPrefix(v.ID, "rId"))
		buffer.WriteString(".xml")
		xml.Unmarshal([]byte(f.readXML(buffer.String())), &xlsx)
		for _, sheetView := range xlsx.SheetViews.SheetView {
			if sheetView.TabSelected {
				ID, _ := strconv.Atoi(strings.TrimPrefix(v.ID, "rId"))
				return ID
			}
		}
		buffer.Reset()
	}
	return 0
}
func (f *File) SetSheetName(oldName, newName string) {
	oldName = trimSheetName(oldName)
	newName = trimSheetName(newName)
	content := f.workbookReader()
	for k, v := range content.Sheets.Sheet {
		if v.Name == oldName {
			content.Sheets.Sheet[k].Name = newName
			f.sheetMap[newName] = f.sheetMap[oldName]
			delete(f.sheetMap, oldName)
		}
	}
}
func (f *File) GetSheetName(index int) string {
	content := f.workbookReader()
	rels := f.workbookRelsReader()
	for _, rel := range rels.Relationships {
		rID, _ := strconv.Atoi(strings.TrimSuffix(strings.TrimPrefix(rel.Target, "worksheets/sheet"), ".xml"))
		if rID == index {
			for _, v := range content.Sheets.Sheet {
				if v.ID == rel.ID {
					return v.Name
				}
			}
		}
	}
	return ""
}