- API changed, use worksheet name instead of "sheet" + index, related issue #25, #43, #47, #51, #89, #101, #116 and #120.

- go test updated
This commit is contained in:
Ri Xu 2017-09-13 22:00:33 +08:00
parent 3e7192b6ab
commit f05f799f8d
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
11 changed files with 159 additions and 145 deletions

View File

@ -38,12 +38,12 @@ import (
func main() { func main() {
xlsx := excelize.NewFile() xlsx := excelize.NewFile()
// Create a new sheet. // Create a new sheet.
xlsx.NewSheet(2, "Sheet2") index := xlsx.NewSheet("Sheet2")
// Set value of a cell. // Set value of a cell.
xlsx.SetCellValue("Sheet2", "A2", "Hello world.") xlsx.SetCellValue("Sheet2", "A2", "Hello world.")
xlsx.SetCellValue("Sheet1", "B2", 100) xlsx.SetCellValue("Sheet1", "B2", 100)
// Set active sheet of the workbook. // Set active sheet of the workbook.
xlsx.SetActiveSheet(2) xlsx.SetActiveSheet(index)
// Save xlsx file by the given path. // Save xlsx file by the given path.
err := xlsx.SaveAs("./Workbook.xlsx") err := xlsx.SaveAs("./Workbook.xlsx")
if err != nil { if err != nil {
@ -63,7 +63,6 @@ package main
import ( import (
"fmt" "fmt"
"os" "os"
"strconv"
"github.com/xuri/excelize" "github.com/xuri/excelize"
) )
@ -74,13 +73,11 @@ func main() {
fmt.Println(err) fmt.Println(err)
os.Exit(1) os.Exit(1)
} }
// Get value from cell by given sheet index and axis. // Get value from cell by given worksheet name and axis.
cell := xlsx.GetCellValue("Sheet1", "B2") cell := xlsx.GetCellValue("Sheet1", "B2")
fmt.Println(cell) fmt.Println(cell)
// Get sheet index. // Get all the rows in the Sheet1.
index := xlsx.GetSheetIndex("Sheet2") rows := xlsx.GetRows("Sheet1")
// Get all the rows in a sheet.
rows := xlsx.GetRows("sheet" + strconv.Itoa(index))
for _, row := range rows { for _, row := range rows {
for _, colCell := range row { for _, colCell := range row {
fmt.Print(colCell, "\t") fmt.Print(colCell, "\t")
@ -88,11 +85,12 @@ func main() {
fmt.Println() fmt.Println()
} }
} }
``` ```
### Add chart to XLSX file ### Add chart to XLSX file
With Excelize chart generation and management is as easy as a few lines of code. You can build charts based off data in your worksheet or generate charts without any data in your sheet at all. With Excelize chart generation and management is as easy as a few lines of code. You can build charts based off data in your worksheet or generate charts without any data in your worksheet at all.
![Excelize](./test/images/chart.png "Excelize") ![Excelize](./test/images/chart.png "Excelize")
@ -152,7 +150,7 @@ func main() {
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} }
// Insert a picture to sheet with scaling. // Insert a picture to worksheet with scaling.
err = xlsx.AddPicture("Sheet1", "D2", "./image2.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`) err = xlsx.AddPicture("Sheet1", "D2", "./image2.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)

View File

@ -263,7 +263,7 @@ func (f *File) GetCellHyperLink(sheet, axis string) (bool, string) {
// MergeCell provides function to merge cells by given coordinate area and sheet // MergeCell provides function to merge cells by given coordinate area and sheet
// name. For example create a merged cell of D3:E9 on Sheet1: // name. For example create a merged cell of D3:E9 on Sheet1:
// //
// xlsx.MergeCell("sheet1", "D3", "E9") // xlsx.MergeCell("Sheet1", "D3", "E9")
// //
// If you create a merged cell that overlaps with another existing merged cell, // If you create a merged cell that overlaps with another existing merged cell,
// those merged cells that already exist will be removed. // those merged cells that already exist will be removed.

4
col.go
View File

@ -225,7 +225,7 @@ func (f *File) getColWidth(sheet string, col int) int {
return int(defaultColWidthPixels) return int(defaultColWidthPixels)
} }
// GetColWidth provides function to get column width by given sheet name and // GetColWidth provides function to get column width by given worksheet name and
// column index. // column index.
func (f *File) GetColWidth(sheet, column string) float64 { func (f *File) GetColWidth(sheet, column string) float64 {
col := TitleToNumber(strings.ToUpper(column)) + 1 col := TitleToNumber(strings.ToUpper(column)) + 1
@ -255,7 +255,7 @@ func (f *File) InsertCol(sheet, column string) {
f.adjustHelper(sheet, col, -1, 1) f.adjustHelper(sheet, col, -1, 1)
} }
// RemoveCol provides function to remove single column by given worksheet index // RemoveCol provides function to remove single column by given worksheet name
// and column index. For example, remove column C in Sheet1: // and column index. For example, remove column C in Sheet1:
// //
// xlsx.RemoveCol("Sheet1", "C") // xlsx.RemoveCol("Sheet1", "C")

View File

@ -14,6 +14,7 @@ import (
// File define a populated XLSX file struct. // File define a populated XLSX file struct.
type File struct { type File struct {
checked map[string]bool checked map[string]bool
sheetMap map[string]string
ContentTypes *xlsxTypes ContentTypes *xlsxTypes
Path string Path string
SharedStrings *xlsxSST SharedStrings *xlsxSST
@ -38,6 +39,8 @@ func OpenFile(filename string) (*File, error) {
return nil, err return nil, err
} }
f.Path = filename f.Path = filename
f.sheetMap = f.getSheetMap()
f.Styles = f.stylesReader()
return f, nil return f, nil
} }
@ -77,7 +80,10 @@ func (f *File) setDefaultTimeStyle(sheet, axis string) {
// workSheetReader provides function to get the pointer to the structure after // workSheetReader provides function to get the pointer to the structure after
// deserialization by given worksheet index. // deserialization by given worksheet index.
func (f *File) workSheetReader(sheet string) *xlsxWorksheet { func (f *File) workSheetReader(sheet string) *xlsxWorksheet {
name := "xl/worksheets/" + strings.ToLower(sheet) + ".xml" name, ok := f.sheetMap[sheet]
if !ok {
name = "xl/worksheets/" + strings.ToLower(sheet) + ".xml"
}
if f.Sheet[name] == nil { if f.Sheet[name] == nil {
var xlsx xlsxWorksheet var xlsx xlsxWorksheet
xml.Unmarshal([]byte(f.readXML(name)), &xlsx) xml.Unmarshal([]byte(f.readXML(name)), &xlsx)
@ -159,8 +165,8 @@ func replaceWorkSheetsRelationshipsNameSpace(workbookMarshal string) string {
// </row> // </row>
// //
func (f *File) UpdateLinkedValue() { func (f *File) UpdateLinkedValue() {
for i := 1; i <= f.SheetCount; i++ { for _, name := range f.GetSheetMap() {
xlsx := f.workSheetReader("sheet" + strconv.Itoa(i)) xlsx := f.workSheetReader(name)
for indexR, row := range xlsx.SheetData.Row { for indexR, row := range xlsx.SheetData.Row {
for indexC, col := range row.C { for indexC, col := range row.C {
if col.F != nil && col.V != "" { if col.F != nil && col.V != "" {
@ -176,7 +182,7 @@ func (f *File) UpdateLinkedValue() {
// hyperlinks, merged cells and auto filter when inserting or deleting rows or // hyperlinks, merged cells and auto filter when inserting or deleting rows or
// columns. // columns.
// //
// sheet: Worksheet index that we're editing // sheet: Worksheet name that we're editing
// column: Index number of the column we're inserting/deleting before // column: Index number of the column we're inserting/deleting before
// row: Index number of the row we're inserting/deleting before // row: Index number of the row we're inserting/deleting before
// offset: Number of rows/column to insert/delete negative values indicate deletion // offset: Number of rows/column to insert/delete negative values indicate deletion

View File

@ -18,9 +18,9 @@ func TestOpenFile(t *testing.T) {
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
// Test get all the rows in a not exists sheet. // Test get all the rows in a not exists worksheet.
rows := xlsx.GetRows("Sheet4") rows := xlsx.GetRows("Sheet4")
// Test get all the rows in a sheet. // Test get all the rows in a worksheet.
rows = xlsx.GetRows("Sheet2") rows = xlsx.GetRows("Sheet2")
for _, row := range rows { for _, row := range rows {
for _, cell := range row { for _, cell := range row {
@ -29,21 +29,22 @@ func TestOpenFile(t *testing.T) {
t.Log("\r\n") t.Log("\r\n")
} }
xlsx.UpdateLinkedValue() xlsx.UpdateLinkedValue()
xlsx.SetCellDefault("SHEET2", "A1", strconv.FormatFloat(float64(100.1588), 'f', -1, 32)) xlsx.SetCellDefault("Sheet2", "A1", strconv.FormatFloat(float64(100.1588), 'f', -1, 32))
xlsx.SetCellDefault("SHEET2", "A1", strconv.FormatFloat(float64(-100.1588), 'f', -1, 64)) xlsx.SetCellDefault("Sheet2", "A1", strconv.FormatFloat(float64(-100.1588), 'f', -1, 64))
xlsx.SetCellInt("SHEET2", "A1", 100) xlsx.SetCellInt("Sheet2", "A1", 100)
xlsx.SetCellStr("SHEET2", "C11", "Knowns") xlsx.SetCellStr("Sheet2", "C11", "Knowns")
// Test max characters in a cell. // Test max characters in a cell.
xlsx.SetCellStr("SHEET2", "D11", strings.Repeat("c", 32769)) xlsx.SetCellStr("Sheet2", "D11", strings.Repeat("c", 32769))
xlsx.NewSheet(3, ":\\/?*[]Maximum 31 characters allowed in sheet title.") xlsx.NewSheet(":\\/?*[]Maximum 31 characters allowed in sheet title.")
// Test set sheet name with illegal name. // Test set worksheet name with illegal name.
xlsx.SetSheetName("Maximum 31 characters allowed i", "[Rename]:\\/?* Maximum 31 characters allowed in sheet title.") xlsx.SetSheetName("Maximum 31 characters allowed i", "[Rename]:\\/?* Maximum 31 characters allowed in sheet title.")
xlsx.SetCellInt("Sheet3", "A23", 10) xlsx.SetCellInt("Sheet3", "A23", 10)
xlsx.SetCellStr("SHEET3", "b230", "10") xlsx.SetCellStr("Sheet3", "b230", "10")
xlsx.SetCellStr("SHEET10", "b230", "10") xlsx.SetCellStr("Sheet10", "b230", "10")
xlsx.SetActiveSheet(2) xlsx.SetActiveSheet(2)
xlsx.GetCellFormula("Sheet1", "B19") // Test get cell formula with given rows number. xlsx.GetCellFormula("Sheet1", "B19") // Test get cell formula with given rows number.
xlsx.GetCellFormula("Sheet2", "B20") // Test get cell formula with illegal sheet index. xlsx.GetCellFormula("Sheet2", "B20") // Test get cell formula with illegal worksheet index.
xlsx.GetCellFormula("Sheet1", "B20") // Test get cell formula with illegal rows number. xlsx.GetCellFormula("Sheet1", "B20") // Test get cell formula with illegal rows number.
// Test read cell value with given illegal rows number. // Test read cell value with given illegal rows number.
xlsx.GetCellValue("Sheet2", "a-1") xlsx.GetCellValue("Sheet2", "a-1")
@ -71,16 +72,16 @@ func TestOpenFile(t *testing.T) {
xlsx.SetCellValue("Sheet2", "M2", nil) xlsx.SetCellValue("Sheet2", "M2", nil)
// Test read cell value with given axis large than exists row. // Test read cell value with given axis large than exists row.
xlsx.GetCellValue("Sheet2", "E231") xlsx.GetCellValue("Sheet2", "E231")
// Test get active sheet of XLSX and get sheet name of XLSX by given sheet index. // Test get active worksheet of XLSX and get worksheet name of XLSX by given worksheet index.
xlsx.GetSheetName(xlsx.GetActiveSheetIndex()) xlsx.GetSheetName(xlsx.GetActiveSheetIndex())
// Test get sheet index of XLSX by given worksheet name. // Test get worksheet index of XLSX by given worksheet name.
xlsx.GetSheetIndex("Sheet1") xlsx.GetSheetIndex("Sheet1")
// Test get sheet name of XLSX by given invalid sheet index. // Test get worksheet name of XLSX by given invalid worksheet index.
xlsx.GetSheetName(4) xlsx.GetSheetName(4)
// Test get sheet map of XLSX. // Test get worksheet map of XLSX.
xlsx.GetSheetMap() xlsx.GetSheetMap()
for i := 1; i <= 300; i++ { for i := 1; i <= 300; i++ {
xlsx.SetCellStr("SHEET3", "c"+strconv.Itoa(i), strconv.Itoa(i)) xlsx.SetCellStr("Sheet3", "c"+strconv.Itoa(i), strconv.Itoa(i))
} }
err = xlsx.Save() err = xlsx.Save()
if err != nil { if err != nil {
@ -91,6 +92,7 @@ func TestOpenFile(t *testing.T) {
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
} }
func TestAddPicture(t *testing.T) { func TestAddPicture(t *testing.T) {
@ -156,10 +158,10 @@ func TestBrokenFile(t *testing.T) {
func TestNewFile(t *testing.T) { func TestNewFile(t *testing.T) {
// Test create a XLSX file. // Test create a XLSX file.
xlsx := NewFile() xlsx := NewFile()
xlsx.NewSheet(2, "XLSXSheet2") xlsx.NewSheet("XLSXSheet2")
xlsx.NewSheet(3, "XLSXSheet3") xlsx.NewSheet("XLSXSheet3")
xlsx.SetCellInt("Sheet2", "A23", 56) xlsx.SetCellInt("XLSXSheet2", "A23", 56)
xlsx.SetCellStr("SHEET1", "B20", "42") xlsx.SetCellStr("Sheet1", "B20", "42")
xlsx.SetActiveSheet(0) xlsx.SetActiveSheet(0)
// Test add picture to sheet with scaling. // Test add picture to sheet with scaling.
err := xlsx.AddPicture("Sheet1", "H2", "./test/images/excel.gif", `{"x_scale": 0.5, "y_scale": 0.5}`) err := xlsx.AddPicture("Sheet1", "H2", "./test/images/excel.gif", `{"x_scale": 0.5, "y_scale": 0.5}`)
@ -178,10 +180,10 @@ func TestNewFile(t *testing.T) {
func TestColWidth(t *testing.T) { func TestColWidth(t *testing.T) {
xlsx := NewFile() xlsx := NewFile()
xlsx.SetColWidth("sheet1", "B", "A", 12) xlsx.SetColWidth("Sheet1", "B", "A", 12)
xlsx.SetColWidth("sheet1", "A", "B", 12) xlsx.SetColWidth("Sheet1", "A", "B", 12)
xlsx.GetColWidth("sheet1", "A") xlsx.GetColWidth("Sheet1", "A")
xlsx.GetColWidth("sheet1", "C") xlsx.GetColWidth("Sheet1", "C")
err := xlsx.SaveAs("./test/Workbook_4.xlsx") err := xlsx.SaveAs("./test/Workbook_4.xlsx")
if err != nil { if err != nil {
t.Log(err) t.Log(err)
@ -208,13 +210,13 @@ func TestSetCellHyperLink(t *testing.T) {
t.Log(err) t.Log(err)
} }
// Test set cell hyperlink in a work sheet already have hyperlinks. // Test set cell hyperlink in a work sheet already have hyperlinks.
xlsx.SetCellHyperLink("sheet1", "B19", "https://github.com/xuri/excelize", "External") xlsx.SetCellHyperLink("Sheet1", "B19", "https://github.com/xuri/excelize", "External")
// Test add first hyperlink in a work sheet. // Test add first hyperlink in a work sheet.
xlsx.SetCellHyperLink("sheet2", "C1", "https://github.com/xuri/excelize", "External") xlsx.SetCellHyperLink("Sheet2", "C1", "https://github.com/xuri/excelize", "External")
// Test add Location hyperlink in a work sheet. // Test add Location hyperlink in a work sheet.
xlsx.SetCellHyperLink("sheet2", "D6", "Sheet1!D8", "Location") xlsx.SetCellHyperLink("Sheet2", "D6", "Sheet1!D8", "Location")
xlsx.SetCellHyperLink("sheet2", "C3", "Sheet1!D8", "") xlsx.SetCellHyperLink("Sheet2", "C3", "Sheet1!D8", "")
xlsx.SetCellHyperLink("sheet2", "", "Sheet1!D60", "Location") xlsx.SetCellHyperLink("Sheet2", "", "Sheet1!D60", "Location")
err = xlsx.Save() err = xlsx.Save()
if err != nil { if err != nil {
t.Log(err) t.Log(err)
@ -241,8 +243,8 @@ func TestSetCellFormula(t *testing.T) {
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
xlsx.SetCellFormula("sheet1", "B19", "SUM(Sheet2!D2,Sheet2!D11)") xlsx.SetCellFormula("Sheet1", "B19", "SUM(Sheet2!D2,Sheet2!D11)")
xlsx.SetCellFormula("sheet1", "C19", "SUM(Sheet2!D2,Sheet2!D9)") xlsx.SetCellFormula("Sheet1", "C19", "SUM(Sheet2!D2,Sheet2!D9)")
err = xlsx.Save() err = xlsx.Save()
if err != nil { if err != nil {
t.Log(err) t.Log(err)
@ -254,19 +256,19 @@ func TestSetSheetBackground(t *testing.T) {
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
err = xlsx.SetSheetBackground("sheet2", "./test/images/background.png") err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.png")
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
err = xlsx.SetSheetBackground("sheet2", "./test/Workbook1.xlsx") err = xlsx.SetSheetBackground("Sheet2", "./test/Workbook1.xlsx")
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
err = xlsx.SetSheetBackground("sheet2", "./test/images/background.jpg") err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.jpg")
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
err = xlsx.SetSheetBackground("sheet2", "./test/images/background.jpg") err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.jpg")
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
@ -674,8 +676,8 @@ func TestCopySheet(t *testing.T) {
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
xlsx.NewSheet(4, "CopySheet") idx := xlsx.NewSheet("CopySheet")
err = xlsx.CopySheet(1, 4) err = xlsx.CopySheet(1, idx)
if err != nil { if err != nil {
t.Log(err) t.Log(err)
} }
@ -784,14 +786,14 @@ func TestAddChart(t *testing.T) {
for k, v := range values { for k, v := range values {
xlsx.SetCellValue("Sheet1", k, v) xlsx.SetCellValue("Sheet1", k, v)
} }
xlsx.AddChart("SHEET1", "P1", `{"type":"bar3D","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit 3D Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`) xlsx.AddChart("Sheet1", "P1", `{"type":"bar3D","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit 3D Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
xlsx.AddChart("SHEET1", "X1", `{"type":"bar","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`) xlsx.AddChart("Sheet1", "X1", `{"type":"bar","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"Fruit Bar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
xlsx.AddChart("SHEET1", "P16", `{"type":"doughnut","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"right","show_legend_key":false},"title":{"name":"Fruit Doughnut Chart"},"plotarea":{"show_bubble_size":false,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`) xlsx.AddChart("Sheet1", "P16", `{"type":"doughnut","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"right","show_legend_key":false},"title":{"name":"Fruit Doughnut Chart"},"plotarea":{"show_bubble_size":false,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`)
xlsx.AddChart("SHEET1", "X16", `{"type":"line","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"top","show_legend_key":false},"title":{"name":"Fruit Line Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`) xlsx.AddChart("Sheet1", "X16", `{"type":"line","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"top","show_legend_key":false},"title":{"name":"Fruit Line Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
xlsx.AddChart("SHEET1", "P30", `{"type":"pie3D","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit 3D Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`) xlsx.AddChart("Sheet1", "P30", `{"type":"pie3D","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit 3D Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"zero"}`)
xlsx.AddChart("SHEET1", "X30", `{"type":"pie","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"gap"}`) xlsx.AddChart("Sheet1", "X30", `{"type":"pie","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit Pie Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":false,"show_val":false},"show_blanks_as":"gap"}`)
xlsx.AddChart("SHEET2", "P1", `{"type":"radar","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"top_right","show_legend_key":false},"title":{"name":"Fruit Radar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"span"}`) xlsx.AddChart("Sheet2", "P1", `{"type":"radar","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"top_right","show_legend_key":false},"title":{"name":"Fruit Radar Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"span"}`)
xlsx.AddChart("SHEET2", "X1", `{"type":"scatter","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit Scatter Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`) xlsx.AddChart("Sheet2", "X1", `{"type":"scatter","series":[{"name":"=Sheet1!$A$30","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$30:$D$30"},{"name":"=Sheet1!$A$31","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$31:$D$31"},{"name":"=Sheet1!$A$32","categories":"=Sheet1!$B$29:$D$29","values":"=Sheet1!$B$32:$D$32"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"Fruit Scatter Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`)
// Save xlsx file by the given path. // Save xlsx file by the given path.
err = xlsx.SaveAs("./test/Workbook_addchart.xlsx") err = xlsx.SaveAs("./test/Workbook_addchart.xlsx")
if err != nil { if err != nil {
@ -808,7 +810,7 @@ func TestInsertCol(t *testing.T) {
} }
} }
xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External") xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External")
xlsx.MergeCell("sheet1", "A1", "C3") xlsx.MergeCell("Sheet1", "A1", "C3")
err := xlsx.AutoFilter("Sheet1", "A2", "B2", `{"column":"B","expression":"x != blanks"}`) err := xlsx.AutoFilter("Sheet1", "A2", "B2", `{"column":"B","expression":"x != blanks"}`)
t.Log(err) t.Log(err)
xlsx.InsertCol("Sheet1", "A") xlsx.InsertCol("Sheet1", "A")
@ -828,8 +830,8 @@ func TestRemoveCol(t *testing.T) {
} }
xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External") xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External")
xlsx.SetCellHyperLink("Sheet1", "C5", "https://github.com", "External") xlsx.SetCellHyperLink("Sheet1", "C5", "https://github.com", "External")
xlsx.MergeCell("sheet1", "A1", "B1") xlsx.MergeCell("Sheet1", "A1", "B1")
xlsx.MergeCell("sheet1", "A2", "B2") xlsx.MergeCell("Sheet1", "A2", "B2")
xlsx.RemoveCol("Sheet1", "A") xlsx.RemoveCol("Sheet1", "A")
xlsx.RemoveCol("Sheet1", "A") xlsx.RemoveCol("Sheet1", "A")
err := xlsx.SaveAs("./test/Workbook_removecol.xlsx") err := xlsx.SaveAs("./test/Workbook_removecol.xlsx")
@ -858,12 +860,12 @@ func TestInsertRow(t *testing.T) {
func TestSetPane(t *testing.T) { func TestSetPane(t *testing.T) {
xlsx := NewFile() xlsx := NewFile()
xlsx.SetPanes("Sheet1", `{"freeze":false,"split":false}`) xlsx.SetPanes("Sheet1", `{"freeze":false,"split":false}`)
xlsx.NewSheet(2, "Panes 2") xlsx.NewSheet("Panes 2")
xlsx.SetPanes("Sheet2", `{"freeze":true,"split":false,"x_split":1,"y_split":0,"top_left_cell":"B1","active_pane":"topRight","panes":[{"sqref":"K16","active_cell":"K16","pane":"topRight"}]}`) xlsx.SetPanes("Panes 2", `{"freeze":true,"split":false,"x_split":1,"y_split":0,"top_left_cell":"B1","active_pane":"topRight","panes":[{"sqref":"K16","active_cell":"K16","pane":"topRight"}]}`)
xlsx.NewSheet(3, "Panes 3") xlsx.NewSheet("Panes 3")
xlsx.SetPanes("Sheet3", `{"freeze":false,"split":true,"x_split":3270,"y_split":1800,"top_left_cell":"N57","active_pane":"bottomLeft","panes":[{"sqref":"I36","active_cell":"I36"},{"sqref":"G33","active_cell":"G33","pane":"topRight"},{"sqref":"J60","active_cell":"J60","pane":"bottomLeft"},{"sqref":"O60","active_cell":"O60","pane":"bottomRight"}]}`) xlsx.SetPanes("Panes 3", `{"freeze":false,"split":true,"x_split":3270,"y_split":1800,"top_left_cell":"N57","active_pane":"bottomLeft","panes":[{"sqref":"I36","active_cell":"I36"},{"sqref":"G33","active_cell":"G33","pane":"topRight"},{"sqref":"J60","active_cell":"J60","pane":"bottomLeft"},{"sqref":"O60","active_cell":"O60","pane":"bottomRight"}]}`)
xlsx.NewSheet(4, "Panes 4") xlsx.NewSheet("Panes 4")
xlsx.SetPanes("Sheet4", `{"freeze":true,"split":false,"x_split":0,"y_split":9,"top_left_cell":"A34","active_pane":"bottomLeft","panes":[{"sqref":"A11:XFD11","active_cell":"A11","pane":"bottomLeft"}]}`) xlsx.SetPanes("Panes 4", `{"freeze":true,"split":false,"x_split":0,"y_split":9,"top_left_cell":"A34","active_pane":"bottomLeft","panes":[{"sqref":"A11:XFD11","active_cell":"A11","pane":"bottomLeft"}]}`)
err := xlsx.SaveAs("./test/Workbook_set_panes.xlsx") err := xlsx.SaveAs("./test/Workbook_set_panes.xlsx")
if err != nil { if err != nil {
t.Log(err) t.Log(err)
@ -881,7 +883,7 @@ func TestRemoveRow(t *testing.T) {
xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External") xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External")
xlsx.RemoveRow("Sheet1", -1) xlsx.RemoveRow("Sheet1", -1)
xlsx.RemoveRow("Sheet1", 4) xlsx.RemoveRow("Sheet1", 4)
xlsx.MergeCell("sheet1", "B3", "B5") xlsx.MergeCell("Sheet1", "B3", "B5")
xlsx.RemoveRow("Sheet1", 2) xlsx.RemoveRow("Sheet1", 2)
xlsx.RemoveRow("Sheet1", 4) xlsx.RemoveRow("Sheet1", 4)
err := xlsx.AutoFilter("Sheet1", "A2", "A2", `{"column":"A","expression":"x != blanks"}`) err := xlsx.AutoFilter("Sheet1", "A2", "A2", `{"column":"A","expression":"x != blanks"}`)

11
file.go
View File

@ -24,10 +24,19 @@ func NewFile() *File {
file["xl/styles.xml"] = XMLHeader + templateStyles file["xl/styles.xml"] = XMLHeader + templateStyles
file["xl/workbook.xml"] = XMLHeader + templateWorkbook file["xl/workbook.xml"] = XMLHeader + templateWorkbook
file["[Content_Types].xml"] = XMLHeader + templateContentTypes file["[Content_Types].xml"] = XMLHeader + templateContentTypes
return &File{ f := &File{
sheetMap: make(map[string]string),
Sheet: make(map[string]*xlsxWorksheet), Sheet: make(map[string]*xlsxWorksheet),
SheetCount: 1,
XLSX: file, XLSX: file,
} }
f.ContentTypes = f.contentTypesReader()
f.Styles = f.stylesReader()
f.WorkBook = f.workbookReader()
f.WorkBookRels = f.workbookRelsReader()
f.Sheet["xl/worksheets/sheet1.xml"] = f.workSheetReader("Sheet1")
f.sheetMap["Sheet1"] = "xl/worksheets/sheet1.xml"
return f
} }
// Save provides function to override the xlsx file with origin path. // Save provides function to override the xlsx file with origin path.

View File

@ -99,8 +99,8 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
} }
// addSheetRelationships provides function to add // addSheetRelationships provides function to add
// xl/worksheets/_rels/sheet%d.xml.rels by given sheet name, relationship type // xl/worksheets/_rels/sheet%d.xml.rels by given worksheet name, relationship
// and target. // type and target.
func (f *File) addSheetRelationships(sheet, relType, target, targetMode string) int { func (f *File) addSheetRelationships(sheet, relType, target, targetMode string) int {
var rels = "xl/worksheets/_rels/" + strings.ToLower(sheet) + ".xml.rels" var rels = "xl/worksheets/_rels/" + strings.ToLower(sheet) + ".xml.rels"
var sheetRels xlsxWorkbookRels var sheetRels xlsxWorkbookRels
@ -128,7 +128,7 @@ func (f *File) addSheetRelationships(sheet, relType, target, targetMode string)
} }
// deleteSheetRelationships provides function to delete relationships in // deleteSheetRelationships provides function to delete relationships in
// xl/worksheets/_rels/sheet%d.xml.rels by given sheet name and relationship // xl/worksheets/_rels/sheet%d.xml.rels by given worksheet name and relationship
// index. // index.
func (f *File) deleteSheetRelationships(sheet, rID string) { func (f *File) deleteSheetRelationships(sheet, rID string) {
var rels = "xl/worksheets/_rels/" + strings.ToLower(sheet) + ".xml.rels" var rels = "xl/worksheets/_rels/" + strings.ToLower(sheet) + ".xml.rels"
@ -145,7 +145,7 @@ func (f *File) deleteSheetRelationships(sheet, rID string) {
} }
// addSheetLegacyDrawing provides function to add legacy drawing element to // addSheetLegacyDrawing provides function to add legacy drawing element to
// xl/worksheets/sheet%d.xml by given sheet name and relationship index. // xl/worksheets/sheet%d.xml by given worksheet name and relationship index.
func (f *File) addSheetLegacyDrawing(sheet string, rID int) { func (f *File) addSheetLegacyDrawing(sheet string, rID int) {
xlsx := f.workSheetReader(sheet) xlsx := f.workSheetReader(sheet)
xlsx.LegacyDrawing = &xlsxLegacyDrawing{ xlsx.LegacyDrawing = &xlsxLegacyDrawing{
@ -154,7 +154,7 @@ func (f *File) addSheetLegacyDrawing(sheet string, rID int) {
} }
// addSheetDrawing provides function to add drawing element to // addSheetDrawing provides function to add drawing element to
// xl/worksheets/sheet%d.xml by given sheet name and relationship index. // xl/worksheets/sheet%d.xml by given worksheet name and relationship index.
func (f *File) addSheetDrawing(sheet string, rID int) { func (f *File) addSheetDrawing(sheet string, rID int) {
xlsx := f.workSheetReader(sheet) xlsx := f.workSheetReader(sheet)
xlsx.Drawing = &xlsxDrawing{ xlsx.Drawing = &xlsxDrawing{
@ -163,7 +163,7 @@ func (f *File) addSheetDrawing(sheet string, rID int) {
} }
// addSheetPicture provides function to add picture element to // addSheetPicture provides function to add picture element to
// xl/worksheets/sheet%d.xml by given sheet name and relationship index. // xl/worksheets/sheet%d.xml by given worksheet name and relationship index.
func (f *File) addSheetPicture(sheet string, rID int) { func (f *File) addSheetPicture(sheet string, rID int) {
xlsx := f.workSheetReader(sheet) xlsx := f.workSheetReader(sheet)
xlsx.Picture = &xlsxPicture{ xlsx.Picture = &xlsxPicture{
@ -356,7 +356,7 @@ func (f *File) addContentTypePart(index int, contentType string) {
} }
// getSheetRelationshipsTargetByID provides function to get Target attribute // getSheetRelationshipsTargetByID provides function to get Target attribute
// value in xl/worksheets/_rels/sheet%d.xml.rels by given sheet name and // value in xl/worksheets/_rels/sheet%d.xml.rels by given worksheet name and
// relationship index. // relationship index.
func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string { func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
var rels = "xl/worksheets/_rels/" + strings.ToLower(sheet) + ".xml.rels" var rels = "xl/worksheets/_rels/" + strings.ToLower(sheet) + ".xml.rels"

19
rows.go
View File

@ -8,15 +8,10 @@ import (
"strings" "strings"
) )
// GetRows return all the rows in a sheet by given "sheet" + index. For now you // GetRows return all the rows in a sheet by given worksheet name (case
// should use sheet_name like "sheet3" where "sheet" is a constant part and "3" // sensitive). For example:
// is a sheet number. For example, if sheet named as "SomeUniqueData" and it is
// second if spreadsheet program interface - you should use "sheet2" here. For
// example:
// //
// index := xlsx.GetSheetIndex("Sheet2") // for _, row := range xlsx.GetRows("Sheet1") {
// rows := xlsx.GetRows("sheet" + strconv.Itoa(index))
// for _, row := range rows {
// for _, colCell := range row { // for _, colCell := range row {
// fmt.Print(colCell, "\t") // fmt.Print(colCell, "\t")
// } // }
@ -70,7 +65,7 @@ func (f *File) GetRows(sheet string) [][]string {
} }
// getTotalRowsCols provides a function to get total columns and rows in a // getTotalRowsCols provides a function to get total columns and rows in a
// sheet. // worksheet.
func (f *File) getTotalRowsCols(sheet string) (int, int) { func (f *File) getTotalRowsCols(sheet string) (int, int) {
name := "xl/worksheets/" + strings.ToLower(sheet) + ".xml" name := "xl/worksheets/" + strings.ToLower(sheet) + ".xml"
decoder := xml.NewDecoder(strings.NewReader(f.readXML(name))) decoder := xml.NewDecoder(strings.NewReader(f.readXML(name)))
@ -182,7 +177,7 @@ func (xlsx *xlsxC) getValueFrom(f *File, d *xlsxSST) (string, error) {
} }
// SetRowVisible provides a function to set visible of a single row by given // SetRowVisible provides a function to set visible of a single row by given
// worksheet index and row index. For example, hide row 3 in Sheet1: // worksheet name and row index. For example, hide row 3 in Sheet1:
// //
// xlsx.SetRowVisible("Sheet1", 2, false) // xlsx.SetRowVisible("Sheet1", 2, false)
// //
@ -199,7 +194,7 @@ func (f *File) SetRowVisible(sheet string, rowIndex int, visible bool) {
} }
// GetRowVisible provides a function to get visible of a single row by given // GetRowVisible provides a function to get visible of a single row by given
// worksheet index and row index. For example, get visible state of row 3 in // worksheet name and row index. For example, get visible state of row 3 in
// Sheet1: // Sheet1:
// //
// xlsx.GetRowVisible("Sheet1", 2) // xlsx.GetRowVisible("Sheet1", 2)
@ -212,7 +207,7 @@ func (f *File) GetRowVisible(sheet string, rowIndex int) bool {
return !xlsx.SheetData.Row[rowIndex].Hidden return !xlsx.SheetData.Row[rowIndex].Hidden
} }
// RemoveRow provides function to remove single row by given worksheet index and // RemoveRow provides function to remove single row by given worksheet name and
// row index. For example, remove row 3 in Sheet1: // row index. For example, remove row 3 in Sheet1:
// //
// xlsx.RemoveRow("Sheet1", 2) // xlsx.RemoveRow("Sheet1", 2)

View File

@ -14,19 +14,20 @@ import (
// NewSheet provides function to create a new sheet by given index, when // NewSheet provides function to create a new sheet by given index, when
// creating a new XLSX file, the default sheet will be create, when you create a // creating a new XLSX file, the default sheet will be create, when you create a
// new file, you need to ensure that the index is continuous. // new file.
func (f *File) NewSheet(index int, name string) { func (f *File) NewSheet(name string) int {
f.SheetCount++
// Update docProps/app.xml // Update docProps/app.xml
f.setAppXML() f.setAppXML()
// Update [Content_Types].xml // Update [Content_Types].xml
f.setContentTypes(index) f.setContentTypes(f.SheetCount)
// Create new sheet /xl/worksheets/sheet%d.xml // Create new sheet /xl/worksheets/sheet%d.xml
f.setSheet(index) f.setSheet(f.SheetCount, name)
// Update xl/_rels/workbook.xml.rels // Update xl/_rels/workbook.xml.rels
rID := f.addXlsxWorkbookRels(index) rID := f.addXlsxWorkbookRels(f.SheetCount)
// Update xl/workbook.xml // Update xl/workbook.xml
f.setWorkbook(name, rID) f.setWorkbook(name, rID)
f.SheetCount++ return f.SheetCount
} }
// contentTypesReader provides function to get the pointer to the // contentTypesReader provides function to get the pointer to the
@ -109,23 +110,23 @@ func (f *File) setContentTypes(index int) {
} }
// Update sheet property by given index. // Update sheet property by given index.
func (f *File) setSheet(index int) { func (f *File) setSheet(index int, name string) {
var xlsx xlsxWorksheet var xlsx xlsxWorksheet
xlsx.Dimension.Ref = "A1" xlsx.Dimension.Ref = "A1"
xlsx.SheetViews.SheetView = append(xlsx.SheetViews.SheetView, xlsxSheetView{ xlsx.SheetViews.SheetView = append(xlsx.SheetViews.SheetView, xlsxSheetView{
WorkbookViewID: 0, WorkbookViewID: 0,
}) })
path := "xl/worksheets/sheet" + strconv.Itoa(index) + ".xml" path := "xl/worksheets/sheet" + strconv.Itoa(index) + ".xml"
f.sheetMap[trimSheetName(name)] = path
f.Sheet[path] = &xlsx f.Sheet[path] = &xlsx
} }
// setWorkbook update workbook property of XLSX. Maximum 31 characters are // setWorkbook update workbook property of XLSX. Maximum 31 characters are
// allowed in sheet title. // allowed in sheet title.
func (f *File) setWorkbook(name string, rid int) { func (f *File) setWorkbook(name string, rid int) {
name = trimSheetName(name)
content := f.workbookReader() content := f.workbookReader()
content.Sheets.Sheet = append(content.Sheets.Sheet, xlsxSheet{ content.Sheets.Sheet = append(content.Sheets.Sheet, xlsxSheet{
Name: name, Name: trimSheetName(name),
SheetID: strconv.Itoa(rid), SheetID: strconv.Itoa(rid),
ID: "rId" + strconv.Itoa(rid), ID: "rId" + strconv.Itoa(rid),
}) })
@ -210,12 +211,10 @@ func (f *File) SetActiveSheet(index int) {
ActiveTab: index, ActiveTab: index,
}) })
} }
sheets := len(content.Sheets.Sheet)
index++ index++
for i := 0; i < sheets; i++ { for idx, name := range f.GetSheetMap() {
sheetIndex := i + 1 xlsx := f.workSheetReader(name)
xlsx := f.workSheetReader("sheet" + strconv.Itoa(sheetIndex)) if index == idx {
if index == sheetIndex {
if len(xlsx.SheetViews.SheetView) > 0 { if len(xlsx.SheetViews.SheetView) > 0 {
xlsx.SheetViews.SheetView[0].TabSelected = true xlsx.SheetViews.SheetView[0].TabSelected = true
} else { } else {
@ -254,8 +253,8 @@ func (f *File) GetActiveSheetIndex() int {
return 0 return 0
} }
// SetSheetName provides function to set the sheet name be given old and new // SetSheetName provides function to set the worksheet name be given old and new
// sheet name. Maximum 31 characters are allowed in sheet title and this // worksheet name. Maximum 31 characters are allowed in sheet title and this
// function only changes the name of the sheet and will not update the sheet // function only changes the name of the sheet and will not update the sheet
// name in the formula or reference associated with the cell. So there may be // name in the formula or reference associated with the cell. So there may be
// problem formula error or reference missing. // problem formula error or reference missing.
@ -266,12 +265,15 @@ func (f *File) SetSheetName(oldName, newName string) {
for k, v := range content.Sheets.Sheet { for k, v := range content.Sheets.Sheet {
if v.Name == oldName { if v.Name == oldName {
content.Sheets.Sheet[k].Name = newName content.Sheets.Sheet[k].Name = newName
f.sheetMap[newName] = f.sheetMap[oldName]
delete(f.sheetMap, oldName)
} }
} }
} }
// GetSheetName provides function to get sheet name of XLSX by given worksheet // GetSheetName provides function to get worksheet name of XLSX by given
// index. If given sheet index is invalid, will return an empty string. // worksheet index. If given sheet index is invalid, will return an empty
// string.
func (f *File) GetSheetName(index int) string { func (f *File) GetSheetName(index int) string {
content := f.workbookReader() content := f.workbookReader()
rels := f.workbookRelsReader() rels := f.workbookRelsReader()
@ -289,7 +291,8 @@ func (f *File) GetSheetName(index int) string {
} }
// GetSheetIndex provides function to get worksheet index of XLSX by given sheet // GetSheetIndex provides function to get worksheet index of XLSX by given sheet
// name. If given sheet name is invalid, will return an integer type value 0. // name. If given worksheet name is invalid, will return an integer type value
// 0.
func (f *File) GetSheetIndex(name string) int { func (f *File) GetSheetIndex(name string) int {
content := f.workbookReader() content := f.workbookReader()
rels := f.workbookRelsReader() rels := f.workbookRelsReader()
@ -306,15 +309,16 @@ func (f *File) GetSheetIndex(name string) int {
return 0 return 0
} }
// GetSheetMap provides function to get sheet map of XLSX. For example: // GetSheetMap provides function to get worksheet name and index map of XLSX.
// For example:
// //
// xlsx, err := excelize.OpenFile("./Workbook.xlsx") // xlsx, err := excelize.OpenFile("./Workbook.xlsx")
// if err != nil { // if err != nil {
// fmt.Println(err) // fmt.Println(err)
// os.Exit(1) // os.Exit(1)
// } // }
// for k, v := range xlsx.GetSheetMap() { // for index, name := range xlsx.GetSheetMap() {
// fmt.Println(k, v) // fmt.Println(index, name)
// } // }
// //
func (f *File) GetSheetMap() map[int]string { func (f *File) GetSheetMap() map[int]string {
@ -332,6 +336,16 @@ func (f *File) GetSheetMap() map[int]string {
return sheetMap return sheetMap
} }
// getSheetMap provides function to get worksheet name and XML file path map of
// XLSX.
func (f *File) getSheetMap() map[string]string {
maps := make(map[string]string)
for idx, name := range f.GetSheetMap() {
maps[name] = "xl/worksheets/sheet" + strconv.Itoa(idx) + ".xml"
}
return maps
}
// SetSheetBackground provides function to set background picture by given sheet // SetSheetBackground provides function to set background picture by given sheet
// index. // index.
func (f *File) SetSheetBackground(sheet, picture string) error { func (f *File) SetSheetBackground(sheet, picture string) error {
@ -353,14 +367,14 @@ func (f *File) SetSheetBackground(sheet, picture string) error {
} }
// DeleteSheet provides function to delete worksheet in a workbook by given // DeleteSheet provides function to delete worksheet in a workbook by given
// sheet name. Use this method with caution, which will affect changes in // worksheet name. Use this method with caution, which will affect changes in
// references such as formulas, charts, and so on. If there is any referenced // references such as formulas, charts, and so on. If there is any referenced
// 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) {
content := f.workbookReader() content := f.workbookReader()
for k, v := range content.Sheets.Sheet { for k, v := range content.Sheets.Sheet {
if v.Name != name || len(content.Sheets.Sheet) < 2 { if v.Name != trimSheetName(name) || len(content.Sheets.Sheet) < 2 {
continue continue
} }
content.Sheets.Sheet = append(content.Sheets.Sheet[:k], content.Sheets.Sheet[k+1:]...) content.Sheets.Sheet = append(content.Sheets.Sheet[:k], content.Sheets.Sheet[k+1:]...)
@ -368,18 +382,10 @@ func (f *File) DeleteSheet(name string) {
rels := "xl/worksheets/_rels/sheet" + strings.TrimPrefix(v.ID, "rId") + ".xml.rels" rels := "xl/worksheets/_rels/sheet" + strings.TrimPrefix(v.ID, "rId") + ".xml.rels"
target := f.deleteSheetFromWorkbookRels(v.ID) target := f.deleteSheetFromWorkbookRels(v.ID)
f.deleteSheetFromContentTypes(target) f.deleteSheetFromContentTypes(target)
_, ok := f.XLSX[sheet] delete(f.sheetMap, name)
if ok {
delete(f.XLSX, sheet) delete(f.XLSX, sheet)
}
_, ok = f.XLSX[rels]
if ok {
delete(f.XLSX, rels) delete(f.XLSX, rels)
}
_, ok = f.Sheet[sheet]
if ok {
delete(f.Sheet, sheet) delete(f.Sheet, sheet)
}
f.SheetCount-- f.SheetCount--
} }
} }
@ -416,8 +422,8 @@ func (f *File) deleteSheetFromContentTypes(target string) {
// workbooks that contain tables, charts or pictures. For Example: // workbooks that contain tables, charts or pictures. For Example:
// //
// // Sheet1 already exists... // // Sheet1 already exists...
// xlsx.NewSheet(2, "sheet2") // index := xlsx.NewSheet("Sheet2")
// err := xlsx.CopySheet(1, 2) // err := xlsx.CopySheet(1, index)
// if err != nil { // if err != nil {
// fmt.Println(err) // fmt.Println(err)
// os.Exit(1) // os.Exit(1)
@ -432,7 +438,7 @@ func (f *File) CopySheet(from, to int) error {
} }
// copySheet provides function to duplicate a worksheet by gave source and // copySheet provides function to duplicate a worksheet by gave source and
// target worksheet index. // target worksheet name.
func (f *File) copySheet(from, to int) { func (f *File) copySheet(from, to int) {
sheet := f.workSheetReader("sheet" + strconv.Itoa(from)) sheet := f.workSheetReader("sheet" + strconv.Itoa(from))
worksheet := xlsxWorksheet{} worksheet := xlsxWorksheet{}
@ -484,8 +490,7 @@ func (f *File) SetSheetVisible(name string, visible bool) {
} }
} }
for k, v := range content.Sheets.Sheet { for k, v := range content.Sheets.Sheet {
sheetIndex := k + 1 xlsx := f.workSheetReader(f.GetSheetMap()[k])
xlsx := f.workSheetReader("sheet" + strconv.Itoa(sheetIndex))
tabSelected := false tabSelected := false
if len(xlsx.SheetViews.SheetView) > 0 { if len(xlsx.SheetViews.SheetView) > 0 {
tabSelected = xlsx.SheetViews.SheetView[0].TabSelected tabSelected = xlsx.SheetViews.SheetView[0].TabSelected
@ -504,7 +509,7 @@ func parseFormatPanesSet(formatSet string) *formatPanes {
} }
// SetPanes provides function to create and remove freeze panes and split panes // SetPanes provides function to create and remove freeze panes and split panes
// by given worksheet index and panes format set. // by given worksheet name and panes format set.
// //
// activePane defines the pane that is active. The possible values for this // activePane defines the pane that is active. The possible values for this
// attribute are defined in the following table: // attribute are defined in the following table:

View File

@ -2218,9 +2218,8 @@ func setCellXfs(style *xlsxStyleSheet, fontID, numFmtID, fillID, borderID int, a
} }
// SetCellStyle provides function to add style attribute for cells by given // SetCellStyle provides function to add style attribute for cells by given
// worksheet sheet index, coordinate area and style ID. Note that diagonalDown // worksheet name, coordinate area and style ID. Note that diagonalDown and
// and diagonalUp type border should be use same color in the same coordinate // diagonalUp type border should be use same color in the same coordinate area.
// area.
// //
// For example create a borders of cell H9 on Sheet1: // For example create a borders of cell H9 on Sheet1:
// //

View File

@ -82,7 +82,7 @@ func (f *File) countTables() int {
} }
// addSheetTable provides function to add tablePart element to // addSheetTable provides function to add tablePart element to
// xl/worksheets/sheet%d.xml by given sheet name and relationship index. // xl/worksheets/sheet%d.xml by given worksheet name and relationship index.
func (f *File) addSheetTable(sheet string, rID int) { func (f *File) addSheetTable(sheet string, rID int) {
xlsx := f.workSheetReader(sheet) xlsx := f.workSheetReader(sheet)
table := &xlsxTablePart{ table := &xlsxTablePart{
@ -95,8 +95,8 @@ func (f *File) addSheetTable(sheet string, rID int) {
xlsx.TableParts.TableParts = append(xlsx.TableParts.TableParts, table) xlsx.TableParts.TableParts = append(xlsx.TableParts.TableParts, table)
} }
// addTable provides function to add table by given sheet index, coordinate area // addTable provides function to add table by given worksheet name, coordinate
// and format set. // area and format set.
func (f *File) addTable(sheet, tableXML string, hxAxis, hyAxis, vxAxis, vyAxis, i int, formatSet *formatTable) { func (f *File) addTable(sheet, tableXML string, hxAxis, hyAxis, vxAxis, vyAxis, i int, formatSet *formatTable) {
// Correct the minimum number of rows, the table at least two lines. // Correct the minimum number of rows, the table at least two lines.
if hyAxis == vyAxis { if hyAxis == vyAxis {
@ -157,8 +157,8 @@ func parseAutoFilterSet(formatSet string) *formatAutoFilter {
} }
// AutoFilter provides the method to add auto filter in a worksheet by given // AutoFilter provides the method to add auto filter in a worksheet by given
// sheet index, coordinate area and settings. An autofilter in Excel is a way of // worksheet name, coordinate area and settings. An autofilter in Excel is a way
// filtering a 2D range of data based on some simple criteria. For example // of filtering a 2D range of data based on some simple criteria. For example
// applying an autofilter to a cell range A1:D4 in the worksheet 1: // applying an autofilter to a cell range A1:D4 in the worksheet 1:
// //
// err = xlsx.AutoFilter("Sheet1", "A1", "D4", "") // err = xlsx.AutoFilter("Sheet1", "A1", "D4", "")