From f05f799f8d33e24b3bbf6c030c9f22d2829e0748 Mon Sep 17 00:00:00 2001 From: Ri Xu Date: Wed, 13 Sep 2017 22:00:33 +0800 Subject: [PATCH] - API changed, use worksheet name instead of "sheet" + index, related issue #25, #43, #47, #51, #89, #101, #116 and #120. - go test updated --- README.md | 18 ++++---- cell.go | 2 +- col.go | 4 +- excelize.go | 14 ++++-- excelize_test.go | 114 ++++++++++++++++++++++++----------------------- file.go | 15 +++++-- picture.go | 14 +++--- rows.go | 19 +++----- sheet.go | 89 +++++++++++++++++++----------------- styles.go | 5 +-- table.go | 10 ++--- 11 files changed, 159 insertions(+), 145 deletions(-) diff --git a/README.md b/README.md index 3d6383b..58c275f 100644 --- a/README.md +++ b/README.md @@ -38,12 +38,12 @@ import ( func main() { xlsx := excelize.NewFile() // Create a new sheet. - xlsx.NewSheet(2, "Sheet2") + index := xlsx.NewSheet("Sheet2") // Set value of a cell. xlsx.SetCellValue("Sheet2", "A2", "Hello world.") xlsx.SetCellValue("Sheet1", "B2", 100) // Set active sheet of the workbook. - xlsx.SetActiveSheet(2) + xlsx.SetActiveSheet(index) // Save xlsx file by the given path. err := xlsx.SaveAs("./Workbook.xlsx") if err != nil { @@ -63,7 +63,6 @@ package main import ( "fmt" "os" - "strconv" "github.com/xuri/excelize" ) @@ -74,13 +73,11 @@ func main() { fmt.Println(err) 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") fmt.Println(cell) - // Get sheet index. - index := xlsx.GetSheetIndex("Sheet2") - // Get all the rows in a sheet. - rows := xlsx.GetRows("sheet" + strconv.Itoa(index)) + // Get all the rows in the Sheet1. + rows := xlsx.GetRows("Sheet1") for _, row := range rows { for _, colCell := range row { fmt.Print(colCell, "\t") @@ -88,11 +85,12 @@ func main() { fmt.Println() } } + ``` ### 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") @@ -152,7 +150,7 @@ func main() { if err != nil { 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}`) if err != nil { fmt.Println(err) diff --git a/cell.go b/cell.go index ca590a9..f3aa90b 100644 --- a/cell.go +++ b/cell.go @@ -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 // 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, // those merged cells that already exist will be removed. diff --git a/col.go b/col.go index 56fb6e8..d9c4390 100644 --- a/col.go +++ b/col.go @@ -225,7 +225,7 @@ func (f *File) getColWidth(sheet string, col int) int { 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. func (f *File) GetColWidth(sheet, column string) float64 { col := TitleToNumber(strings.ToUpper(column)) + 1 @@ -255,7 +255,7 @@ func (f *File) InsertCol(sheet, column string) { 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: // // xlsx.RemoveCol("Sheet1", "C") diff --git a/excelize.go b/excelize.go index 681759e..f06ecb0 100644 --- a/excelize.go +++ b/excelize.go @@ -14,6 +14,7 @@ import ( // File define a populated XLSX file struct. type File struct { checked map[string]bool + sheetMap map[string]string ContentTypes *xlsxTypes Path string SharedStrings *xlsxSST @@ -38,6 +39,8 @@ func OpenFile(filename string) (*File, error) { return nil, err } f.Path = filename + f.sheetMap = f.getSheetMap() + f.Styles = f.stylesReader() 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 // deserialization by given worksheet index. 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 { var xlsx xlsxWorksheet xml.Unmarshal([]byte(f.readXML(name)), &xlsx) @@ -159,8 +165,8 @@ func replaceWorkSheetsRelationshipsNameSpace(workbookMarshal string) string { // // func (f *File) UpdateLinkedValue() { - for i := 1; i <= f.SheetCount; i++ { - xlsx := f.workSheetReader("sheet" + strconv.Itoa(i)) + for _, name := range f.GetSheetMap() { + xlsx := f.workSheetReader(name) for indexR, row := range xlsx.SheetData.Row { for indexC, col := range row.C { 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 // 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 // row: Index number of the row we're inserting/deleting before // offset: Number of rows/column to insert/delete negative values indicate deletion diff --git a/excelize_test.go b/excelize_test.go index 2529870..8240dbb 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -18,9 +18,9 @@ func TestOpenFile(t *testing.T) { if err != nil { 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") - // Test get all the rows in a sheet. + // Test get all the rows in a worksheet. rows = xlsx.GetRows("Sheet2") for _, row := range rows { for _, cell := range row { @@ -29,21 +29,22 @@ func TestOpenFile(t *testing.T) { t.Log("\r\n") } 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, 64)) - xlsx.SetCellInt("SHEET2", "A1", 100) - xlsx.SetCellStr("SHEET2", "C11", "Knowns") + 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.SetCellInt("Sheet2", "A1", 100) + xlsx.SetCellStr("Sheet2", "C11", "Knowns") + // Test max characters in a cell. - xlsx.SetCellStr("SHEET2", "D11", strings.Repeat("c", 32769)) - xlsx.NewSheet(3, ":\\/?*[]Maximum 31 characters allowed in sheet title.") - // Test set sheet name with illegal name. + xlsx.SetCellStr("Sheet2", "D11", strings.Repeat("c", 32769)) + xlsx.NewSheet(":\\/?*[]Maximum 31 characters allowed in sheet title.") + // Test set worksheet name with illegal name. xlsx.SetSheetName("Maximum 31 characters allowed i", "[Rename]:\\/?* Maximum 31 characters allowed in sheet title.") xlsx.SetCellInt("Sheet3", "A23", 10) - xlsx.SetCellStr("SHEET3", "b230", "10") - xlsx.SetCellStr("SHEET10", "b230", "10") + xlsx.SetCellStr("Sheet3", "b230", "10") + xlsx.SetCellStr("Sheet10", "b230", "10") xlsx.SetActiveSheet(2) 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. // Test read cell value with given illegal rows number. xlsx.GetCellValue("Sheet2", "a-1") @@ -71,16 +72,16 @@ func TestOpenFile(t *testing.T) { xlsx.SetCellValue("Sheet2", "M2", nil) // Test read cell value with given axis large than exists row. 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()) - // Test get sheet index of XLSX by given worksheet name. + // Test get worksheet index of XLSX by given worksheet name. 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) - // Test get sheet map of XLSX. + // Test get worksheet map of XLSX. xlsx.GetSheetMap() 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() if err != nil { @@ -91,6 +92,7 @@ func TestOpenFile(t *testing.T) { if err != nil { t.Log(err) } + } func TestAddPicture(t *testing.T) { @@ -156,10 +158,10 @@ func TestBrokenFile(t *testing.T) { func TestNewFile(t *testing.T) { // Test create a XLSX file. xlsx := NewFile() - xlsx.NewSheet(2, "XLSXSheet2") - xlsx.NewSheet(3, "XLSXSheet3") - xlsx.SetCellInt("Sheet2", "A23", 56) - xlsx.SetCellStr("SHEET1", "B20", "42") + xlsx.NewSheet("XLSXSheet2") + xlsx.NewSheet("XLSXSheet3") + xlsx.SetCellInt("XLSXSheet2", "A23", 56) + xlsx.SetCellStr("Sheet1", "B20", "42") xlsx.SetActiveSheet(0) // Test add picture to sheet with scaling. 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) { xlsx := NewFile() - xlsx.SetColWidth("sheet1", "B", "A", 12) - xlsx.SetColWidth("sheet1", "A", "B", 12) - xlsx.GetColWidth("sheet1", "A") - xlsx.GetColWidth("sheet1", "C") + xlsx.SetColWidth("Sheet1", "B", "A", 12) + xlsx.SetColWidth("Sheet1", "A", "B", 12) + xlsx.GetColWidth("Sheet1", "A") + xlsx.GetColWidth("Sheet1", "C") err := xlsx.SaveAs("./test/Workbook_4.xlsx") if err != nil { t.Log(err) @@ -208,13 +210,13 @@ func TestSetCellHyperLink(t *testing.T) { t.Log(err) } // 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. - 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. - xlsx.SetCellHyperLink("sheet2", "D6", "Sheet1!D8", "Location") - xlsx.SetCellHyperLink("sheet2", "C3", "Sheet1!D8", "") - xlsx.SetCellHyperLink("sheet2", "", "Sheet1!D60", "Location") + xlsx.SetCellHyperLink("Sheet2", "D6", "Sheet1!D8", "Location") + xlsx.SetCellHyperLink("Sheet2", "C3", "Sheet1!D8", "") + xlsx.SetCellHyperLink("Sheet2", "", "Sheet1!D60", "Location") err = xlsx.Save() if err != nil { t.Log(err) @@ -241,8 +243,8 @@ func TestSetCellFormula(t *testing.T) { if err != nil { t.Log(err) } - xlsx.SetCellFormula("sheet1", "B19", "SUM(Sheet2!D2,Sheet2!D11)") - xlsx.SetCellFormula("sheet1", "C19", "SUM(Sheet2!D2,Sheet2!D9)") + xlsx.SetCellFormula("Sheet1", "B19", "SUM(Sheet2!D2,Sheet2!D11)") + xlsx.SetCellFormula("Sheet1", "C19", "SUM(Sheet2!D2,Sheet2!D9)") err = xlsx.Save() if err != nil { t.Log(err) @@ -254,19 +256,19 @@ func TestSetSheetBackground(t *testing.T) { if err != nil { t.Log(err) } - err = xlsx.SetSheetBackground("sheet2", "./test/images/background.png") + err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.png") if err != nil { t.Log(err) } - err = xlsx.SetSheetBackground("sheet2", "./test/Workbook1.xlsx") + err = xlsx.SetSheetBackground("Sheet2", "./test/Workbook1.xlsx") if err != nil { t.Log(err) } - err = xlsx.SetSheetBackground("sheet2", "./test/images/background.jpg") + err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.jpg") if err != nil { t.Log(err) } - err = xlsx.SetSheetBackground("sheet2", "./test/images/background.jpg") + err = xlsx.SetSheetBackground("Sheet2", "./test/images/background.jpg") if err != nil { t.Log(err) } @@ -674,8 +676,8 @@ func TestCopySheet(t *testing.T) { if err != nil { t.Log(err) } - xlsx.NewSheet(4, "CopySheet") - err = xlsx.CopySheet(1, 4) + idx := xlsx.NewSheet("CopySheet") + err = xlsx.CopySheet(1, idx) if err != nil { t.Log(err) } @@ -784,14 +786,14 @@ func TestAddChart(t *testing.T) { for k, v := range values { 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", "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", "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", "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", "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("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", "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", "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("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"}`) // Save xlsx file by the given path. err = xlsx.SaveAs("./test/Workbook_addchart.xlsx") if err != nil { @@ -808,7 +810,7 @@ func TestInsertCol(t *testing.T) { } } 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"}`) t.Log(err) 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", "C5", "https://github.com", "External") - xlsx.MergeCell("sheet1", "A1", "B1") - xlsx.MergeCell("sheet1", "A2", "B2") + xlsx.MergeCell("Sheet1", "A1", "B1") + xlsx.MergeCell("Sheet1", "A2", "B2") xlsx.RemoveCol("Sheet1", "A") xlsx.RemoveCol("Sheet1", "A") err := xlsx.SaveAs("./test/Workbook_removecol.xlsx") @@ -858,12 +860,12 @@ func TestInsertRow(t *testing.T) { func TestSetPane(t *testing.T) { xlsx := NewFile() xlsx.SetPanes("Sheet1", `{"freeze":false,"split":false}`) - xlsx.NewSheet(2, "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.NewSheet(3, "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.NewSheet(4, "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.NewSheet("Panes 2") + 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("Panes 3") + 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("Panes 4") + 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") if err != nil { t.Log(err) @@ -881,7 +883,7 @@ func TestRemoveRow(t *testing.T) { xlsx.SetCellHyperLink("Sheet1", "A5", "https://github.com/xuri/excelize", "External") xlsx.RemoveRow("Sheet1", -1) xlsx.RemoveRow("Sheet1", 4) - xlsx.MergeCell("sheet1", "B3", "B5") + xlsx.MergeCell("Sheet1", "B3", "B5") xlsx.RemoveRow("Sheet1", 2) xlsx.RemoveRow("Sheet1", 4) err := xlsx.AutoFilter("Sheet1", "A2", "A2", `{"column":"A","expression":"x != blanks"}`) diff --git a/file.go b/file.go index 4af636b..01e856d 100644 --- a/file.go +++ b/file.go @@ -24,10 +24,19 @@ func NewFile() *File { file["xl/styles.xml"] = XMLHeader + templateStyles file["xl/workbook.xml"] = XMLHeader + templateWorkbook file["[Content_Types].xml"] = XMLHeader + templateContentTypes - return &File{ - Sheet: make(map[string]*xlsxWorksheet), - XLSX: file, + f := &File{ + sheetMap: make(map[string]string), + Sheet: make(map[string]*xlsxWorksheet), + SheetCount: 1, + 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. diff --git a/picture.go b/picture.go index f221616..bc35b47 100644 --- a/picture.go +++ b/picture.go @@ -99,8 +99,8 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error { } // addSheetRelationships provides function to add -// xl/worksheets/_rels/sheet%d.xml.rels by given sheet name, relationship type -// and target. +// xl/worksheets/_rels/sheet%d.xml.rels by given worksheet name, relationship +// type and target. func (f *File) addSheetRelationships(sheet, relType, target, targetMode string) int { var rels = "xl/worksheets/_rels/" + strings.ToLower(sheet) + ".xml.rels" var sheetRels xlsxWorkbookRels @@ -128,7 +128,7 @@ func (f *File) addSheetRelationships(sheet, relType, target, targetMode string) } // 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. func (f *File) deleteSheetRelationships(sheet, rID string) { 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 -// 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) { xlsx := f.workSheetReader(sheet) xlsx.LegacyDrawing = &xlsxLegacyDrawing{ @@ -154,7 +154,7 @@ func (f *File) addSheetLegacyDrawing(sheet string, rID int) { } // 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) { xlsx := f.workSheetReader(sheet) xlsx.Drawing = &xlsxDrawing{ @@ -163,7 +163,7 @@ func (f *File) addSheetDrawing(sheet string, rID int) { } // 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) { xlsx := f.workSheetReader(sheet) xlsx.Picture = &xlsxPicture{ @@ -356,7 +356,7 @@ func (f *File) addContentTypePart(index int, contentType string) { } // 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. func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string { var rels = "xl/worksheets/_rels/" + strings.ToLower(sheet) + ".xml.rels" diff --git a/rows.go b/rows.go index c45b49f..39c6246 100644 --- a/rows.go +++ b/rows.go @@ -8,15 +8,10 @@ import ( "strings" ) -// GetRows return all the rows in a sheet by given "sheet" + index. For now you -// should use sheet_name like "sheet3" where "sheet" is a constant part and "3" -// 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: +// GetRows return all the rows in a sheet by given worksheet name (case +// sensitive). For example: // -// index := xlsx.GetSheetIndex("Sheet2") -// rows := xlsx.GetRows("sheet" + strconv.Itoa(index)) -// for _, row := range rows { +// for _, row := range xlsx.GetRows("Sheet1") { // for _, colCell := range row { // 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 -// sheet. +// worksheet. func (f *File) getTotalRowsCols(sheet string) (int, int) { name := "xl/worksheets/" + strings.ToLower(sheet) + ".xml" 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 -// 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) // @@ -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 -// 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: // // xlsx.GetRowVisible("Sheet1", 2) @@ -212,7 +207,7 @@ func (f *File) GetRowVisible(sheet string, rowIndex int) bool { 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: // // xlsx.RemoveRow("Sheet1", 2) diff --git a/sheet.go b/sheet.go index ac0969f..8a69f4a 100644 --- a/sheet.go +++ b/sheet.go @@ -14,19 +14,20 @@ import ( // 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 -// new file, you need to ensure that the index is continuous. -func (f *File) NewSheet(index int, name string) { +// new file. +func (f *File) NewSheet(name string) int { + f.SheetCount++ // Update docProps/app.xml f.setAppXML() // Update [Content_Types].xml - f.setContentTypes(index) + f.setContentTypes(f.SheetCount) // Create new sheet /xl/worksheets/sheet%d.xml - f.setSheet(index) + f.setSheet(f.SheetCount, name) // Update xl/_rels/workbook.xml.rels - rID := f.addXlsxWorkbookRels(index) + rID := f.addXlsxWorkbookRels(f.SheetCount) // Update xl/workbook.xml f.setWorkbook(name, rID) - f.SheetCount++ + return f.SheetCount } // 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. -func (f *File) setSheet(index int) { +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 } // setWorkbook update workbook property of XLSX. Maximum 31 characters are // allowed in sheet title. func (f *File) setWorkbook(name string, rid int) { - name = trimSheetName(name) content := f.workbookReader() content.Sheets.Sheet = append(content.Sheets.Sheet, xlsxSheet{ - Name: name, + Name: trimSheetName(name), SheetID: strconv.Itoa(rid), ID: "rId" + strconv.Itoa(rid), }) @@ -210,12 +211,10 @@ func (f *File) SetActiveSheet(index int) { ActiveTab: index, }) } - sheets := len(content.Sheets.Sheet) index++ - for i := 0; i < sheets; i++ { - sheetIndex := i + 1 - xlsx := f.workSheetReader("sheet" + strconv.Itoa(sheetIndex)) - if index == sheetIndex { + 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 { @@ -254,8 +253,8 @@ func (f *File) GetActiveSheetIndex() int { return 0 } -// SetSheetName provides function to set the sheet name be given old and new -// sheet name. Maximum 31 characters are allowed in sheet title and this +// SetSheetName provides function to set the worksheet name be given old and new +// 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 // name in the formula or reference associated with the cell. So there may be // problem formula error or reference missing. @@ -266,12 +265,15 @@ func (f *File) SetSheetName(oldName, newName string) { 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) } } } -// GetSheetName provides function to get sheet name of XLSX by given worksheet -// index. If given sheet index is invalid, will return an empty string. +// GetSheetName provides 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) string { content := f.workbookReader() 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 -// 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 { content := f.workbookReader() rels := f.workbookRelsReader() @@ -306,15 +309,16 @@ func (f *File) GetSheetIndex(name string) int { 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") // if err != nil { // fmt.Println(err) // os.Exit(1) // } -// for k, v := range xlsx.GetSheetMap() { -// fmt.Println(k, v) +// for index, name := range xlsx.GetSheetMap() { +// fmt.Println(index, name) // } // func (f *File) GetSheetMap() map[int]string { @@ -332,6 +336,16 @@ func (f *File) GetSheetMap() map[int]string { 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 // index. 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 -// 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 // 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) { content := f.workbookReader() 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 } 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" target := f.deleteSheetFromWorkbookRels(v.ID) f.deleteSheetFromContentTypes(target) - _, ok := f.XLSX[sheet] - if ok { - delete(f.XLSX, sheet) - } - _, ok = f.XLSX[rels] - if ok { - delete(f.XLSX, rels) - } - _, ok = f.Sheet[sheet] - if ok { - delete(f.Sheet, sheet) - } + delete(f.sheetMap, name) + delete(f.XLSX, sheet) + delete(f.XLSX, rels) + delete(f.Sheet, sheet) f.SheetCount-- } } @@ -416,8 +422,8 @@ func (f *File) deleteSheetFromContentTypes(target string) { // workbooks that contain tables, charts or pictures. For Example: // // // Sheet1 already exists... -// xlsx.NewSheet(2, "sheet2") -// err := xlsx.CopySheet(1, 2) +// index := xlsx.NewSheet("Sheet2") +// err := xlsx.CopySheet(1, index) // if err != nil { // fmt.Println(err) // 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 -// target worksheet index. +// target worksheet name. func (f *File) copySheet(from, to int) { sheet := f.workSheetReader("sheet" + strconv.Itoa(from)) worksheet := xlsxWorksheet{} @@ -484,8 +490,7 @@ func (f *File) SetSheetVisible(name string, visible bool) { } } for k, v := range content.Sheets.Sheet { - sheetIndex := k + 1 - xlsx := f.workSheetReader("sheet" + strconv.Itoa(sheetIndex)) + xlsx := f.workSheetReader(f.GetSheetMap()[k]) tabSelected := false if len(xlsx.SheetViews.SheetView) > 0 { 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 -// 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 // attribute are defined in the following table: diff --git a/styles.go b/styles.go index 225cfe5..ee0fbc2 100644 --- a/styles.go +++ b/styles.go @@ -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 -// worksheet sheet index, coordinate area and style ID. Note that diagonalDown -// and diagonalUp type border should be use same color in the same coordinate -// area. +// worksheet name, coordinate area and style ID. Note that diagonalDown and +// diagonalUp type border should be use same color in the same coordinate area. // // For example create a borders of cell H9 on Sheet1: // diff --git a/table.go b/table.go index b274c3b..68e686a 100644 --- a/table.go +++ b/table.go @@ -82,7 +82,7 @@ func (f *File) countTables() int { } // 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) { xlsx := f.workSheetReader(sheet) table := &xlsxTablePart{ @@ -95,8 +95,8 @@ func (f *File) addSheetTable(sheet string, rID int) { xlsx.TableParts.TableParts = append(xlsx.TableParts.TableParts, table) } -// addTable provides function to add table by given sheet index, coordinate area -// and format set. +// addTable provides function to add table by given worksheet name, coordinate +// area and format set. 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. 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 -// sheet index, coordinate area and settings. An autofilter in Excel is a way of -// filtering a 2D range of data based on some simple criteria. For example +// worksheet name, coordinate area and settings. An autofilter in Excel is a way +// 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: // // err = xlsx.AutoFilter("Sheet1", "A1", "D4", "")