- 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() {
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)

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
// 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.

4
col.go
View File

@ -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")

View File

@ -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 {
// </row>
//
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

View File

@ -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"}`)

15
file.go
View File

@ -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.

View File

@ -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"

19
rows.go
View File

@ -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)

View File

@ -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:

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
// 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:
//

View File

@ -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", "")