summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--README_zh.md2
-rw-r--r--chart.go4
-rw-r--r--excelize_test.go12
-rw-r--r--picture.go11
-rw-r--r--rows.go100
-rw-r--r--rows_test.go42
-rw-r--r--shape.go4
-rw-r--r--sheet.go22
-rw-r--r--styles.go24
-rw-r--r--table.go35
-rw-r--r--xmlDrawing.go1
-rw-r--r--xmlTable.go1
13 files changed, 203 insertions, 57 deletions
diff --git a/README.md b/README.md
index 04c248a..d9c70df 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
## Introduction
-Excelize is a library written in pure Golang and providing a set of functions that allow you to write to and read from XLSX files. Support reads and writes XLSX file generated by Microsoft Excel™ 2007 and later. Support save file without losing original charts of XLSX. This library needs Go version 1.8 or later. The full API docs can be seen using go's built-in documentation tool, or online at [godoc.org](https://godoc.org/github.com/360EntSecGroup-Skylar/excelize).
+Excelize is a library written in pure Golang and providing a set of functions that allow you to write to and read from XLSX files. Support reads and writes XLSX file generated by Microsoft Excel™ 2007 and later. Support save file without losing original charts of XLSX. This library needs Go version 1.8 or later. The full API docs can be seen using go's built-in documentation tool, or online at [godoc.org](https://godoc.org/github.com/360EntSecGroup-Skylar/excelize) and [Chinese translation](https://xuri.me/excelize/zh_cn).
## Basic Usage
diff --git a/README_zh.md b/README_zh.md
index a657d8a..ef149b0 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -11,7 +11,7 @@
## 简介
-Excelize 是 Go 语言编写的用于操作 Office Excel 文档类库,基于 ECMA-376 Office OpenXML 标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的 XLSX 文档。相比较其他的开源类库,Excelize 支持写入原本带有图片(表)、透视表和切片器等复杂样式的文档,还支持向 Excel 文档中插入图片与图表,并且在保存后不会丢失文档原有样式,可以应用于各类报表系统中。使用本类库要求使用的 Go 语言为 1.8 或更高版本,完整的 API 使用文档请访问 [godoc.org](https://godoc.org/github.com/360EntSecGroup-Skylar/excelize)。
+Excelize 是 Go 语言编写的用于操作 Office Excel 文档类库,基于 ECMA-376 Office OpenXML 标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的 XLSX 文档。相比较其他的开源类库,Excelize 支持写入原本带有图片(表)、透视表和切片器等复杂样式的文档,还支持向 Excel 文档中插入图片与图表,并且在保存后不会丢失文档原有样式,可以应用于各类报表系统中。使用本类库要求使用的 Go 语言为 1.8 或更高版本,完整的 API 使用文档请访问 [godoc.org](https://godoc.org/github.com/360EntSecGroup-Skylar/excelize) 或查看 [中文翻译](https://xuri.me/excelize/zh_cn)。
## 快速上手
diff --git a/chart.go b/chart.go
index 5c5ac1d..6168553 100644
--- a/chart.go
+++ b/chart.go
@@ -261,7 +261,7 @@ func parseFormatChartSet(formatSet string) *formatChart {
// colStacked | 2D stacked column chart
// colPercentStacked | 2D 100% stacked column chart
// col3DClustered | 3D clustered column chart
-// col3D | 3D column column chart
+// col3D | 3D column chart
// col3DStacked | 3D stacked column chart
// col3DPercentStacked | 3D 100% stacked column chart
// doughnut | doughnut chart
@@ -1111,7 +1111,7 @@ func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rI
content.Xdr = NameSpaceDrawingMLSpreadSheet
cNvPrID := f.drawingParser(drawingXML, &content)
twoCellAnchor := xdrCellAnchor{}
- twoCellAnchor.EditAs = "oneCell"
+ twoCellAnchor.EditAs = formatSet.Positioning
from := xlsxFrom{}
from.Col = colStart
from.ColOff = formatSet.OffsetX * EMU
diff --git a/excelize_test.go b/excelize_test.go
index ade3baf..9587f33 100644
--- a/excelize_test.go
+++ b/excelize_test.go
@@ -137,8 +137,8 @@ func TestAddPicture(t *testing.T) {
if err != nil {
t.Log(err)
}
- // Test add picture to worksheet with offset and external hyperlink.
- err = xlsx.AddPicture("Sheet1", "F21", "./test/images/excel.png", `{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External"}`)
+ // Test add picture to worksheet with offset, external hyperlink and positioning.
+ err = xlsx.AddPicture("Sheet1", "F21", "./test/images/excel.png", `{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`)
if err != nil {
t.Log(err)
}
@@ -196,8 +196,8 @@ func TestNewFile(t *testing.T) {
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}`)
+ // Test add picture to sheet with scaling and positioning.
+ err := xlsx.AddPicture("Sheet1", "H2", "./test/images/excel.gif", `{"x_scale": 0.5, "y_scale": 0.5, "positioning": "absolute"}`)
if err != nil {
t.Log(err)
}
@@ -756,7 +756,7 @@ func TestAddTable(t *testing.T) {
t.Log(err)
}
xlsx.AddTable("Sheet1", "B26", "A21", ``)
- xlsx.AddTable("Sheet2", "A2", "B5", `{"table_style":"TableStyleMedium2", "show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true}`)
+ xlsx.AddTable("Sheet2", "A2", "B5", `{"table_name":"table","table_style":"TableStyleMedium2", "show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true}`)
xlsx.AddTable("Sheet2", "F1", "F1", `{"table_style":"TableStyleMedium8"}`)
err = xlsx.Save()
if err != nil {
@@ -860,7 +860,7 @@ func TestAddChart(t *testing.T) {
xlsx.AddChart("Sheet2", "X32", `{"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", "P48", `{"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 2D Clustered 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("Sheet2", "X48", `{"type":"barStacked","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 2D Stacked 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("Sheet2", "P64", `{"type":"barPercentStacked","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 2D Stacked 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("Sheet2", "P64", `{"type":"barPercentStacked","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 2D Stacked 100% 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("Sheet2", "X64", `{"type":"bar3DClustered","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 3D Clustered 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("Sheet2", "P80", `{"type":"bar3DStacked","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 3D Stacked 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","y_axis":{"maximum":7.5,"minimum":0.5}}`)
xlsx.AddChart("Sheet2", "X80", `{"type":"bar3DPercentStacked","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 3D 100% Stacked 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","x_axis":{"reverse_order":true,"maximum":0,"minimum":0},"y_axis":{"reverse_order":true,"maximum":0,"minimum":0}}`)
diff --git a/picture.go b/picture.go
index 1f556c4..a7f48d1 100644
--- a/picture.go
+++ b/picture.go
@@ -57,8 +57,8 @@ func parseFormatPictureSet(formatSet string) *formatPicture {
// if err != nil {
// fmt.Println(err)
// }
-// // Insert a picture offset in the cell with external hyperlink and printing support.
-// err = xlsx.AddPicture("Sheet1", "H2", "./image3.gif", `{"x_offset": 15, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "print_obj": true, "lock_aspect_ratio": false, "locked": false}`)
+// // Insert a picture offset in the cell with external hyperlink, printing and positioning support.
+// err = xlsx.AddPicture("Sheet1", "H2", "./image3.gif", `{"x_offset": 15, "y_offset": 10, "hyperlink": "https://github.com/360EntSecGroup-Skylar/excelize", "hyperlink_type": "External", "print_obj": true, "lock_aspect_ratio": false, "locked": false, "positioning": "oneCell"}`)
// if err != nil {
// fmt.Println(err)
// }
@@ -71,6 +71,11 @@ func parseFormatPictureSet(formatSet string) *formatPicture {
// LinkType defines two types of hyperlink "External" for web site or
// "Location" for moving to one of cell in this workbook. When the
// "hyperlink_type" is "Location", coordinates need to start with "#".
+//
+// Positioning defines two types of the position of a picture in an Excel
+// spreadsheet, "oneCell" (Move but don't size with cells) or "absolute"
+// (Don't move or size with cells). If you don't set this parameter, default
+// positioning is move and size with cells.
func (f *File) AddPicture(sheet, cell, picture, format string) error {
var err error
var drawingHyperlinkRID int
@@ -217,7 +222,7 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file string, width, he
content.Xdr = NameSpaceDrawingMLSpreadSheet
cNvPrID := f.drawingParser(drawingXML, &content)
twoCellAnchor := xdrCellAnchor{}
- twoCellAnchor.EditAs = "oneCell"
+ twoCellAnchor.EditAs = formatSet.Positioning
from := xlsxFrom{}
from.Col = colStart
from.ColOff = formatSet.OffsetX * EMU
diff --git a/rows.go b/rows.go
index 25a2049..02a6876 100644
--- a/rows.go
+++ b/rows.go
@@ -3,6 +3,8 @@ package excelize
import (
"bytes"
"encoding/xml"
+ "fmt"
+ "io"
"math"
"strconv"
"strings"
@@ -67,6 +69,100 @@ func (f *File) GetRows(sheet string) [][]string {
return rows
}
+// Rows defines an iterator to a sheet
+type Rows struct {
+ decoder *xml.Decoder
+ token xml.Token
+ err error
+ f *File
+}
+
+// Next will return true if find the next row element.
+func (rows *Rows) Next() bool {
+ for {
+ rows.token, rows.err = rows.decoder.Token()
+ if rows.err == io.EOF {
+ rows.err = nil
+ }
+ if rows.token == nil {
+ return false
+ }
+
+ switch startElement := rows.token.(type) {
+ case xml.StartElement:
+ inElement := startElement.Name.Local
+ if inElement == "row" {
+ return true
+ }
+ }
+ }
+}
+
+// Error will return the error when the find next row element
+func (rows *Rows) Error() error {
+ return rows.err
+}
+
+// Columns return the current row's column values
+func (rows *Rows) Columns() []string {
+ if rows.token == nil {
+ return []string{}
+ }
+
+ startElement := rows.token.(xml.StartElement)
+ r := xlsxRow{}
+ rows.decoder.DecodeElement(&r, &startElement)
+
+ d := rows.f.sharedStringsReader()
+ row := make([]string, len(r.C), len(r.C))
+ for _, colCell := range r.C {
+ c := TitleToNumber(strings.Map(letterOnlyMapF, colCell.R))
+ val, _ := colCell.getValueFrom(rows.f, d)
+ row[c] = val
+ }
+ return row
+}
+
+// ErrSheetNotExist defines an error of sheet is not exist
+type ErrSheetNotExist struct {
+ SheetName string
+}
+
+func (err ErrSheetNotExist) Error() string {
+ return fmt.Sprintf("Sheet %s is not exist", string(err.SheetName))
+}
+
+// Rows return a rows iterator. For example:
+//
+// rows, err := xlsx.GetRows("Sheet1")
+//
+// for rows.Next() {
+// for _, colCell := range rows.Columns() {
+// fmt.Print(colCell, "\t")
+// }
+// fmt.Println()
+// }
+//
+func (f *File) Rows(sheet string) (*Rows, error) {
+ xlsx := f.workSheetReader(sheet)
+ name, ok := f.sheetMap[trimSheetName(sheet)]
+ if !ok {
+ return nil, ErrSheetNotExist{sheet}
+ }
+ if xlsx != nil {
+ output, err := xml.Marshal(f.Sheet[name])
+ if err != nil {
+ return nil, err
+ }
+ f.saveFileList(name, replaceWorkSheetsRelationshipsNameSpace(string(output)))
+ }
+
+ return &Rows{
+ f: f,
+ decoder: xml.NewDecoder(strings.NewReader(f.readXML(name))),
+ }, nil
+}
+
// getTotalRowsCols provides a function to get total columns and rows in a
// worksheet.
func (f *File) getTotalRowsCols(name string) (int, int) {
@@ -182,7 +278,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 name and row index. For example, hide row 3 in Sheet1:
+// worksheet name and row index. For example, hide row 2 in Sheet1:
//
// xlsx.SetRowVisible("Sheet1", 2, false)
//
@@ -199,7 +295,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 name and row index. For example, get visible state of row 3 in
+// worksheet name and row index. For example, get visible state of row 2 in
// Sheet1:
//
// xlsx.GetRowVisible("Sheet1", 2)
diff --git a/rows_test.go b/rows_test.go
new file mode 100644
index 0000000..eadf077
--- /dev/null
+++ b/rows_test.go
@@ -0,0 +1,42 @@
+package excelize
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func trimSliceSpace(s []string) []string {
+ for {
+ if len(s) > 0 && s[len(s)-1] == "" {
+ s = s[:len(s)-1]
+ } else {
+ break
+ }
+ }
+ return s
+}
+
+func TestRows(t *testing.T) {
+ xlsx, err := OpenFile("./test/Book1.xlsx")
+ assert.NoError(t, err)
+
+ rows, err := xlsx.Rows("Sheet2")
+ assert.NoError(t, err)
+
+ rowStrs := make([][]string, 0)
+ var i = 0
+ for rows.Next() {
+ i++
+ columns := rows.Columns()
+ //fmt.Println(i, columns)
+ rowStrs = append(rowStrs, columns)
+ }
+ assert.NoError(t, rows.Error())
+
+ dstRows := xlsx.GetRows("Sheet2")
+ assert.EqualValues(t, len(dstRows), len(rowStrs))
+ for i := 0; i < len(rowStrs); i++ {
+ assert.EqualValues(t, trimSliceSpace(dstRows[i]), trimSliceSpace(rowStrs[i]))
+ }
+}
diff --git a/shape.go b/shape.go
index f93cce9..f1328f7 100644
--- a/shape.go
+++ b/shape.go
@@ -34,7 +34,7 @@ func parseFormatShapeSet(formatSet string) *formatShape {
//
// xlsx.AddShape("Sheet1", "G6", `{"type":"rect","color":{"line":"#4286F4","fill":"#8eb9ff"},"paragraph":[{"text":"Rectangle Shape","font":{"bold":true,"italic":true,"family":"Berlin Sans FB Demi","size":36,"color":"#777777","underline":"sng"}}],"width":180,"height": 90}`)
//
-// The following shows the type of chart supported by excelize:
+// The following shows the type of shape supported by excelize:
//
// accentBorderCallout1 (Callout 1 with Border and Accent Shape)
// accentBorderCallout2 (Callout 2 with Border and Accent Shape)
@@ -285,7 +285,7 @@ func (f *File) addDrawingShape(sheet, drawingXML, cell string, formatSet *format
content.Xdr = NameSpaceDrawingMLSpreadSheet
cNvPrID := f.drawingParser(drawingXML, &content)
twoCellAnchor := xdrCellAnchor{}
- twoCellAnchor.EditAs = "oneCell"
+ twoCellAnchor.EditAs = formatSet.Format.Positioning
from := xlsxFrom{}
from.Col = colStart
from.ColOff = formatSet.Format.OffsetX * EMU
diff --git a/sheet.go b/sheet.go
index bc7cb75..f42226b 100644
--- a/sheet.go
+++ b/sheet.go
@@ -12,9 +12,9 @@ import (
"unicode/utf8"
)
-// 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.
+// NewSheet provides function to create a new sheet by given worksheet name,
+// when creating a new XLSX file, the default sheet will be create, when you
+// create a new file.
func (f *File) NewSheet(name string) int {
// Check if the worksheet already exists
if f.GetSheetIndex(name) != 0 {
@@ -536,13 +536,9 @@ func parseFormatPanesSet(formatSet string) *formatPanes {
// | been applied, dividing the pane into right and left
// | regions. In that case, this value specifies the left pane
// |
-// | Top right pane, when both vertical and horizontal
+// topRight (Top Right Pane) | Top right pane, when both vertical and horizontal
// | splits are applied.
// |
-// topRight (Top Right Pane) | This value is also used when only a vertical split has
-// | splits are applied.
-// |
-// |
// | This value is also used when only a vertical split has
// | been applied, dividing the pane into right and left
// | regions. In that case, this value specifies the right
@@ -577,19 +573,19 @@ func parseFormatPanesSet(formatSet string) *formatPanes {
// set of ranges.
//
// An example of how to freeze column A in the Sheet1 and set the active cell on
-// Sheet1!A16:
+// Sheet1!K16:
//
-// xlsx.SetPanes("Sheet1", `{"freeze":true,"split":false,"x_split":1,"y_split":0,"topLeftCell":"B1","activePane":"topRight","panes":[{"sqref":"K16","active_cell":"K16","pane":"topRight"}]}`)
+// xlsx.SetPanes("Sheet1", `{"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"}]}`)
//
// An example of how to freeze rows 1 to 9 in the Sheet1 and set the active cell
-// on Sheet1!A11:
+// ranges on Sheet1!A11:XFD11:
//
-// xlsx.SetPanes("Sheet1", `{"freeze":true,"split":false,"x_split":0,"y_split":9,"topLeftCell":"A34","activePane":"bottomLeft","panes":[{"sqref":"A11:XFD11","active_cell":"A11","pane":"bottomLeft"}]}`)
+// xlsx.SetPanes("Sheet1", `{"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"}]}`)
//
// An example of how to create split panes in the Sheet1 and set the active cell
// on Sheet1!J60:
//
-// xlsx.SetPanes("Sheet1", `{"freeze":false,"split":true,"x_split":3270,"y_split":1800,"topLeftCell":"N57","activePane":"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("Sheet1", `{"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"}]}`)
//
// An example of how to unfreeze and remove all panes on Sheet1:
//
diff --git a/styles.go b/styles.go
index d1ef726..6ebb603 100644
--- a/styles.go
+++ b/styles.go
@@ -1236,13 +1236,13 @@ func parseFormatStyleSet(style string) (*formatStyle, error) {
// 55 | 4E0A5348/4E0B5348h"65F6"mm"5206
// 56 | 4E0A5348/4E0B5348h"65F6"mm"5206"ss"79D2
// 57 | yyyy"5E74"m"6708
-// 58 | m"6708"d"65E5"`,
+// 58 | m"6708"d"65E5"
//
// Number format code in ja-jp language:
//
// Index | Symbol
// -------+-------------------------------------------
-// 27 | [$-411]ge.m.
+// 27 | [$-411]ge.m.d
// 28 | [$-411]ggge"年"m"月"d"日
// 29 | [$-411]ggge"年"m"月"d"日
// 30 | m/d/y
@@ -1251,18 +1251,18 @@ func parseFormatStyleSet(style string) (*formatStyle, error) {
// 33 | h"時"mm"分"ss"秒
// 34 | yyyy"年"m"月
// 35 | m"月"d"日
-// 36 | [$-411]ge.m.
-// 50 | [$-411]ge.m.
+// 36 | [$-411]ge.m.d
+// 50 | [$-411]ge.m.d
// 51 | [$-411]ggge"年"m"月"d"日
// 52 | yyyy"年"m"月
// 53 | m"月"d"日
// 54 | [$-411]ggge"年"m"月"d"日
// 55 | yyyy"年"m"月
// 56 | m"月"d"日
-// 57 | [$-411]ge.m.
+// 57 | [$-411]ge.m.d
// 58 | [$-411]ggge"年"m"月"d"日"
//
-// Number format code in th-th language:
+// Number format code in ko-kr language:
//
// Index | Symbol
// -------+-------------------------------------------
@@ -1291,7 +1291,7 @@ func parseFormatStyleSet(style string) (*formatStyle, error) {
//
// Index | Symbol
// -------+-------------------------------------------
-// 27 | [$-411]ge.m.
+// 27 | [$-411]ge.m.d
// 28 | [$-411]ggge"5E74"m"6708"d"65E5
// 29 | [$-411]ggge"5E74"m"6708"d"65E5
// 30 | m/d/y
@@ -1300,15 +1300,15 @@ func parseFormatStyleSet(style string) (*formatStyle, error) {
// 33 | h"6642"mm"5206"ss"79D2
// 34 | yyyy"5E74"m"6708
// 35 | m"6708"d"65E5
-// 36 | [$-411]ge.m.
-// 50 | [$-411]ge.m.
+// 36 | [$-411]ge.m.d
+// 50 | [$-411]ge.m.d
// 51 | [$-411]ggge"5E74"m"6708"d"65E5
// 52 | yyyy"5E74"m"6708
// 53 | m"6708"d"65E5
// 54 | [$-411]ggge"5E74"m"6708"d"65E5
// 55 | yyyy"5E74"m"6708
// 56 | m"6708"d"65E5
-// 57 | [$-411]ge.m.
+// 57 | [$-411]ge.m.d
// 58 | [$-411]ggge"5E74"m"6708"d"65E5"
//
// Number format code with unicode values provided for language glyphs where
@@ -1336,7 +1336,7 @@ func parseFormatStyleSet(style string) (*formatStyle, error) {
// 57 | yyyy"5E74" mm"6708" dd"65E5
// 58 | mm-dd
//
-// Number format code in ko-kr language:
+// Number format code in th-th language:
//
// Index | Symbol
// -------+-------------------------------------------
@@ -2304,7 +2304,7 @@ func setCellXfs(style *xlsxStyleSheet, fontID, numFmtID, fillID, borderID int, a
//
// Hide and lock for cell H9 on Sheet1:
//
-// style, err := xlsx.NewStyle(`{"protection":{"hidden":true, "locked":true}`)
+// style, err := xlsx.NewStyle(`{"protection":{"hidden":true, "locked":true}}`)
// if err != nil {
// fmt.Println(err)
// }
diff --git a/table.go b/table.go
index 104202b..5c00a2d 100644
--- a/table.go
+++ b/table.go
@@ -28,10 +28,12 @@ func parseFormatTableSet(formatSet string) *formatTable {
//
// Create a table of F2:H6 on Sheet2 with format set:
//
-// xlsx.AddTable("Sheet2", "F2", "H6", `{"table_style":"TableStyleMedium2", "show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true}`)
+// xlsx.AddTable("Sheet2", "F2", "H6", `{"table_name":"table","table_style":"TableStyleMedium2", "show_first_column":true,"show_last_column":true,"show_row_stripes":false,"show_column_stripes":true}`)
//
-// Note that the table at least two lines include string type header. The two
-// chart coordinate areas can not have an intersection.
+// Note that the table at least two lines include string type header. Multiple
+// tables coordinate areas can't have an intersection.
+//
+// table_name: The name of the table, in the same worksheet name of the table should be unique
//
// table_style: The built-in table style names
//
@@ -122,7 +124,10 @@ func (f *File) addTable(sheet, tableXML string, hxAxis, hyAxis, vxAxis, vyAxis,
Name: name,
})
}
- name := "Table" + strconv.Itoa(i)
+ name := formatSet.TableName
+ if name == "" {
+ name = "Table" + strconv.Itoa(i)
+ }
t := xlsxTable{
XMLNS: NameSpaceSpreadSheet,
ID: i,
@@ -157,9 +162,9 @@ func parseAutoFilterSet(formatSet string) *formatAutoFilter {
}
// AutoFilter provides the method to add auto filter in a worksheet by given
-// 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:
+// 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 Sheet1:
//
// err = xlsx.AutoFilter("Sheet1", "A1", "D4", "")
//
@@ -170,15 +175,15 @@ func parseAutoFilterSet(formatSet string) *formatAutoFilter {
// column defines the filter columns in a autofilter range based on simple
// criteria
//
-// It isn't sufficient to just specify the filter condition. You must also hide
-// any rows that don't match the filter condition. Rows are hidden using the
-// SetRowVisible() method. Excelize can't filter rows automatically since this
-// isn't part of the file format.
+// It isn't sufficient to just specify the filter condition. You must also
+// hide any rows that don't match the filter condition. Rows are hidden using
+// the SetRowVisible() method. Excelize can't filter rows automatically since
+// this isn't part of the file format.
//
// Setting a filter criteria for a column:
//
-// expression defines the conditions, the following operators are available for
-// setting the filter criteria:
+// expression defines the conditions, the following operators are available
+// for setting the filter criteria:
//
// ==
// !=
@@ -189,8 +194,8 @@ func parseAutoFilterSet(formatSet string) *formatAutoFilter {
// and
// or
//
-// An expression can comprise a single statement or two statements separated by
-// the and and or operators. For example:
+// An expression can comprise a single statement or two statements separated
+// by the 'and' and 'or' operators. For example:
//
// x < 2000
// x > 2000
diff --git a/xmlDrawing.go b/xmlDrawing.go
index 600d83a..beb6bc9 100644
--- a/xmlDrawing.go
+++ b/xmlDrawing.go
@@ -360,6 +360,7 @@ type formatPicture struct {
YScale float64 `json:"y_scale"`
Hyperlink string `json:"hyperlink"`
HyperlinkType string `json:"hyperlink_type"`
+ Positioning string `json:"positioning"`
}
// formatShape directly maps the format settings of the shape.
diff --git a/xmlTable.go b/xmlTable.go
index 610950b..b238350 100644
--- a/xmlTable.go
+++ b/xmlTable.go
@@ -186,6 +186,7 @@ type xlsxTableStyleInfo struct {
// formatTable directly maps the format settings of the table.
type formatTable struct {
+ TableName string `json:"table_name"`
TableStyle string `json:"table_style"`
ShowFirstColumn bool `json:"show_first_column"`
ShowLastColumn bool `json:"show_last_column"`