summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2019-12-29 16:02:31 +0800
committerxuri <xuri.me@gmail.com>2019-12-29 16:02:31 +0800
commit09485b3f9f0aefc58d51462aed65c2416205c591 (patch)
treef5fbe1830e03875d4c5422110f42ad665b91b14f
parent5c87effc7e6c97fff36a56dea1afac8a2f06fb37 (diff)
Improve code coverage unit tests
-rw-r--r--LICENSE4
-rw-r--r--README.md70
-rw-r--r--README_zh.md71
-rw-r--r--adjust.go4
-rw-r--r--adjust_test.go4
-rw-r--r--calcchain.go2
-rw-r--r--cell.go2
-rw-r--r--cellmerged.go18
-rw-r--r--chart.go4
-rw-r--r--col.go2
-rw-r--r--comment.go2
-rw-r--r--comment_test.go2
-rw-r--r--datavalidation.go2
-rw-r--r--datavalidation_test.go2
-rw-r--r--date.go2
-rw-r--r--docProps.go2
-rw-r--r--docProps_test.go2
-rw-r--r--errors.go2
-rw-r--r--excelize.go2
-rw-r--r--excelize_test.go113
-rw-r--r--file.go2
-rw-r--r--lib.go2
-rw-r--r--picture.go2
-rw-r--r--pivotTable.go2
-rw-r--r--rows.go2
-rw-r--r--shape.go2
-rw-r--r--shape_test.go28
-rw-r--r--sheet.go2
-rw-r--r--sheetpr.go2
-rw-r--r--sheetview.go2
-rw-r--r--sparkline.go2
-rw-r--r--stream.go127
-rw-r--r--stream_test.go49
-rw-r--r--styles.go2
-rw-r--r--styles_test.go4
-rw-r--r--table.go2
-rw-r--r--table_test.go125
-rw-r--r--templates.go2
-rw-r--r--vmlDrawing.go2
-rw-r--r--xmlApp.go2
-rw-r--r--xmlCalcChain.go2
-rw-r--r--xmlChart.go2
-rw-r--r--xmlComments.go2
-rw-r--r--xmlContentTypes.go2
-rw-r--r--xmlCore.go2
-rw-r--r--xmlDecodeDrawing.go2
-rw-r--r--xmlDrawing.go2
-rw-r--r--xmlPivotTable.go2
-rw-r--r--xmlSharedStrings.go2
-rw-r--r--xmlStyles.go2
-rw-r--r--xmlTable.go2
-rw-r--r--xmlTheme.go2
-rw-r--r--xmlWorkbook.go2
-rw-r--r--xmlWorksheet.go2
54 files changed, 383 insertions, 320 deletions
diff --git a/LICENSE b/LICENSE
index 1962b4a..51ec1fb 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
BSD 3-Clause License
-Copyright (c) 2016-2019, 360 Enterprise Security Group, Endpoint Security, Inc.
-Copyright (c) 2011-2017, Geoffrey J. Teale (complying with the tealeg/xlsx license)
+Copyright (c) 2016-2020, 360 Enterprise Security Group, Endpoint Security, Inc.
+Copyright (c) 2011-2017, Geoffrey J. Teale
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/README.md b/README.md
index 03e33ae..d7f696c 100644
--- a/README.md
+++ b/README.md
@@ -31,11 +31,7 @@ Here is a minimal example usage that will create XLSX file.
```go
package main
-import (
- "fmt"
-
- "github.com/360EntSecGroup-Skylar/excelize"
-)
+import "github.com/360EntSecGroup-Skylar/excelize"
func main() {
f := excelize.NewFile()
@@ -47,9 +43,8 @@ func main() {
// Set active sheet of the workbook.
f.SetActiveSheet(index)
// Save xlsx file by the given path.
- err := f.SaveAs("./Book1.xlsx")
- if err != nil {
- fmt.Println(err)
+ if err := f.SaveAs("Book1.xlsx"); err != nil {
+ println(err.Error())
}
}
```
@@ -61,32 +56,28 @@ The following constitutes the bare to read a XLSX document.
```go
package main
-import (
- "fmt"
-
- "github.com/360EntSecGroup-Skylar/excelize"
-)
+import "github.com/360EntSecGroup-Skylar/excelize"
func main() {
- f, err := excelize.OpenFile("./Book1.xlsx")
+ f, err := excelize.OpenFile("Book1.xlsx")
if err != nil {
- fmt.Println(err)
+ println(err.Error())
return
}
// Get value from cell by given worksheet name and axis.
cell, err := f.GetCellValue("Sheet1", "B2")
if err != nil {
- fmt.Println(err)
+ println(err.Error())
return
}
- fmt.Println(cell)
+ println(cell)
// Get all the rows in the Sheet1.
rows, err := f.GetRows("Sheet1")
for _, row := range rows {
for _, colCell := range row {
- fmt.Print(colCell, "\t")
+ print(colCell, "\t")
}
- fmt.Println()
+ println()
}
}
```
@@ -100,11 +91,7 @@ With Excelize chart generation and management is as easy as a few lines of code.
```go
package main
-import (
- "fmt"
-
- "github.com/360EntSecGroup-Skylar/excelize"
-)
+import "github.com/360EntSecGroup-Skylar/excelize"
func main() {
categories := map[string]string{"A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"}
@@ -116,15 +103,13 @@ func main() {
for k, v := range values {
f.SetCellValue("Sheet1", k, v)
}
- err := f.AddChart("Sheet1", "E1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`)
- if err != nil {
- fmt.Println(err)
+ if err := f.AddChart("Sheet1", "E1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`); err != nil {
+ println(err.Error())
return
}
// Save xlsx file by the given path.
- err = f.SaveAs("./Book1.xlsx")
- if err != nil {
- fmt.Println(err)
+ if err := f.SaveAs("Book1.xlsx"); err != nil {
+ println(err.Error())
}
}
```
@@ -135,7 +120,6 @@ func main() {
package main
import (
- "fmt"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
@@ -144,30 +128,26 @@ import (
)
func main() {
- f, err := excelize.OpenFile("./Book1.xlsx")
+ f, err := excelize.OpenFile("Book1.xlsx")
if err != nil {
- fmt.Println(err)
+ println(err.Error())
return
}
// Insert a picture.
- err = f.AddPicture("Sheet1", "A2", "./image1.png", "")
- if err != nil {
- fmt.Println(err)
+ if err := f.AddPicture("Sheet1", "A2", "image.png", ""); err != nil {
+ println(err.Error())
}
// Insert a picture to worksheet with scaling.
- err = f.AddPicture("Sheet1", "D2", "./image2.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`)
- if err != nil {
- fmt.Println(err)
+ if err := f.AddPicture("Sheet1", "D2", "image.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`); err != nil {
+ println(err.Error())
}
// Insert a picture offset in the cell with printing support.
- err = f.AddPicture("Sheet1", "H2", "./image3.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`)
- if err != nil {
- fmt.Println(err)
+ if err := f.AddPicture("Sheet1", "H2", "image.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`); err != nil {
+ println(err.Error())
}
// Save the xlsx file with the origin path.
- err = f.Save()
- if err != nil {
- fmt.Println(err)
+ if err = f.Save(); err != nil {
+ println(err.Error())
}
}
```
diff --git a/README_zh.md b/README_zh.md
index 57cd645..c1ee83e 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -30,11 +30,7 @@ go get github.com/360EntSecGroup-Skylar/excelize
```go
package main
-import (
- "fmt"
-
- "github.com/360EntSecGroup-Skylar/excelize"
-)
+import "github.com/360EntSecGroup-Skylar/excelize"
func main() {
f := excelize.NewFile()
@@ -46,9 +42,8 @@ func main() {
// 设置工作簿的默认工作表
f.SetActiveSheet(index)
// 根据指定路径保存文件
- err := f.SaveAs("./Book1.xlsx")
- if err != nil {
- fmt.Println(err)
+ if err := f.SaveAs("Book1.xlsx"); err != nil {
+ println(err.Error())
}
}
```
@@ -60,32 +55,28 @@ func main() {
```go
package main
-import (
- "fmt"
-
- "github.com/360EntSecGroup-Skylar/excelize"
-)
+import "github.com/360EntSecGroup-Skylar/excelize"
func main() {
- f, err := excelize.OpenFile("./Book1.xlsx")
+ f, err := excelize.OpenFile("Book1.xlsx")
if err != nil {
- fmt.Println(err)
+ println(err.Error())
return
}
// 获取工作表中指定单元格的值
cell, err := f.GetCellValue("Sheet1", "B2")
if err != nil {
- fmt.Println(err)
+ println(err.Error())
return
}
- fmt.Println(cell)
+ println(cell)
// 获取 Sheet1 上所有单元格
rows, err := f.GetRows("Sheet1")
for _, row := range rows {
for _, colCell := range row {
- fmt.Print(colCell, "\t")
+ print(colCell, "\t")
}
- fmt.Println()
+ println()
}
}
```
@@ -99,11 +90,7 @@ func main() {
```go
package main
-import (
- "fmt"
-
- "github.com/360EntSecGroup-Skylar/excelize"
-)
+import "github.com/360EntSecGroup-Skylar/excelize"
func main() {
categories := map[string]string{"A2": "Small", "A3": "Normal", "A4": "Large", "B1": "Apple", "C1": "Orange", "D1": "Pear"}
@@ -115,18 +102,15 @@ func main() {
for k, v := range values {
f.SetCellValue("Sheet1", k, v)
}
- err := f.AddChart("Sheet1", "E1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`)
- if err != nil {
- fmt.Println(err)
+ if err := f.AddChart("Sheet1", "E1", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$2","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$2:$D$2"},{"name":"Sheet1!$A$3","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$3:$D$3"},{"name":"Sheet1!$A$4","categories":"Sheet1!$B$1:$D$1","values":"Sheet1!$B$4:$D$4"}],"title":{"name":"Fruit 3D Clustered Column Chart"}}`); err != nil {
+ println(err.Error())
return
}
// 根据指定路径保存文件
- err = f.SaveAs("./Book1.xlsx")
- if err != nil {
- fmt.Println(err)
+ if err := f.SaveAs("Book1.xlsx"); err != nil {
+ println(err.Error())
}
}
-
```
### 向 Excel 文档中插入图片
@@ -135,7 +119,6 @@ func main() {
package main
import (
- "fmt"
_ "image/gif"
_ "image/jpeg"
_ "image/png"
@@ -144,30 +127,26 @@ import (
)
func main() {
- f, err := excelize.OpenFile("./Book1.xlsx")
+ f, err := excelize.OpenFile("Book1.xlsx")
if err != nil {
- fmt.Println(err)
+ println(err.Error())
return
}
// 插入图片
- err = f.AddPicture("Sheet1", "A2", "./image1.png", "")
- if err != nil {
- fmt.Println(err)
+ if err := f.AddPicture("Sheet1", "A2", "image.png", ""); err != nil {
+ println(err.Error())
}
// 在工作表中插入图片,并设置图片的缩放比例
- err = f.AddPicture("Sheet1", "D2", "./image2.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`)
- if err != nil {
- fmt.Println(err)
+ if err := f.AddPicture("Sheet1", "D2", "image.jpg", `{"x_scale": 0.5, "y_scale": 0.5}`); err != nil {
+ println(err.Error())
}
// 在工作表中插入图片,并设置图片的打印属性
- err = f.AddPicture("Sheet1", "H2", "./image3.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`)
- if err != nil {
- fmt.Println(err)
+ if err := f.AddPicture("Sheet1", "H2", "image.gif", `{"x_offset": 15, "y_offset": 10, "print_obj": true, "lock_aspect_ratio": false, "locked": false}`); err != nil {
+ println(err.Error())
}
// 保存文件
- err = f.Save()
- if err != nil {
- fmt.Println(err)
+ if err = f.Save(); err != nil {
+ println(err.Error())
}
}
```
diff --git a/adjust.go b/adjust.go
index 69ded1b..bedeec0 100644
--- a/adjust.go
+++ b/adjust.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
@@ -213,6 +213,8 @@ func areaRangeToCoordinates(firstCell, lastCell string) ([]int, error) {
return coordinates, err
}
+// sortCoordinates provides a function to correct the coordinate area, such
+// correct C1:B3 to B1:C3.
func sortCoordinates(coordinates []int) error {
if len(coordinates) != 4 {
return errors.New("coordinates length must be 4")
diff --git a/adjust_test.go b/adjust_test.go
index a0de844..13e47ff 100644
--- a/adjust_test.go
+++ b/adjust_test.go
@@ -114,3 +114,7 @@ func TestCoordinatesToAreaRef(t *testing.T) {
assert.NoError(t, err)
assert.EqualValues(t, ref, "A1:A1")
}
+
+func TestSortCoordinates(t *testing.T) {
+ assert.EqualError(t, sortCoordinates(make([]int, 3)), "coordinates length must be 4")
+}
diff --git a/calcchain.go b/calcchain.go
index a3d3820..f50fb1d 100644
--- a/calcchain.go
+++ b/calcchain.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/cell.go b/cell.go
index 1aeddc1..a659680 100644
--- a/cell.go
+++ b/cell.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/cellmerged.go b/cellmerged.go
index 5bea0bc..b952a1e 100644
--- a/cellmerged.go
+++ b/cellmerged.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
@@ -43,13 +43,7 @@ func (f *File) MergeCell(sheet, hcell, vcell string) error {
return err
}
// Correct the coordinate area, such correct C1:B3 to B1:C3.
- if rect1[2] < rect1[0] {
- rect1[0], rect1[2] = rect1[2], rect1[0]
- }
-
- if rect1[3] < rect1[1] {
- rect1[1], rect1[3] = rect1[3], rect1[1]
- }
+ _ = sortCoordinates(rect1)
hcell, _ = CoordinatesToCellName(rect1[0], rect1[1])
vcell, _ = CoordinatesToCellName(rect1[2], rect1[3])
@@ -123,12 +117,8 @@ func (f *File) UnmergeCell(sheet string, hcell, vcell string) error {
return err
}
- if rect1[2] < rect1[0] {
- rect1[0], rect1[2] = rect1[2], rect1[0]
- }
- if rect1[3] < rect1[1] {
- rect1[1], rect1[3] = rect1[3], rect1[1]
- }
+ // Correct the coordinate area, such correct C1:B3 to B1:C3.
+ _ = sortCoordinates(rect1)
// return nil since no MergeCells in the sheet
if xlsx.MergeCells == nil {
diff --git a/chart.go b/chart.go
index 8b38d22..b5ff3d1 100644
--- a/chart.go
+++ b/chart.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
@@ -657,6 +657,7 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
//
// major_grid_lines
// minor_grid_lines
+// tick_label_skip
// reverse_order
// maximum
// minimum
@@ -666,7 +667,6 @@ func parseFormatChartSet(formatSet string) (*formatChart, error) {
// major_grid_lines
// minor_grid_lines
// major_unit
-// tick_label_skip
// reverse_order
// maximum
// minimum
diff --git a/col.go b/col.go
index 5d4e764..f7e6bcd 100644
--- a/col.go
+++ b/col.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/comment.go b/comment.go
index 486a035..a5b6085 100644
--- a/comment.go
+++ b/comment.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/comment_test.go b/comment_test.go
index dd07951..5b83162 100644
--- a/comment_test.go
+++ b/comment_test.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/datavalidation.go b/datavalidation.go
index 2499035..8b95b40 100644
--- a/datavalidation.go
+++ b/datavalidation.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/datavalidation_test.go b/datavalidation_test.go
index 7e54d55..c245df3 100644
--- a/datavalidation_test.go
+++ b/datavalidation_test.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/date.go b/date.go
index 8f63702..dad39b5 100644
--- a/date.go
+++ b/date.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/docProps.go b/docProps.go
index 884eb63..a61ee71 100644
--- a/docProps.go
+++ b/docProps.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/docProps_test.go b/docProps_test.go
index 30c3149..ef930ae 100644
--- a/docProps_test.go
+++ b/docProps_test.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/errors.go b/errors.go
index 8520a01..4560497 100644
--- a/errors.go
+++ b/errors.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/excelize.go b/excelize.go
index 94f401c..8fbd315 100644
--- a/excelize.go
+++ b/excelize.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
diff --git a/excelize_test.go b/excelize_test.go
index c4b600d..ea82828 100644
--- a/excelize_test.go
+++ b/excelize_test.go
@@ -894,124 +894,11 @@ func TestCopySheetError(t *testing.T) {
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestCopySheetError.xlsx")))
}
-func TestAddTable(t *testing.T) {
- f, err := prepareTestBook1()
- if !assert.NoError(t, err) {
- t.FailNow()
- }
-
- err = f.AddTable("Sheet1", "B26", "A21", `{}`)
- if !assert.NoError(t, err) {
- t.FailNow()
- }
-
- err = f.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}`)
- if !assert.NoError(t, err) {
- t.FailNow()
- }
-
- err = f.AddTable("Sheet2", "F1", "F1", `{"table_style":"TableStyleMedium8"}`)
- if !assert.NoError(t, err) {
- t.FailNow()
- }
-
- // Test add table with illegal formatset.
- assert.EqualError(t, f.AddTable("Sheet1", "B26", "A21", `{x}`), "invalid character 'x' looking for beginning of object key string")
- // Test add table with illegal cell coordinates.
- assert.EqualError(t, f.AddTable("Sheet1", "A", "B1", `{}`), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
- assert.EqualError(t, f.AddTable("Sheet1", "A1", "B", `{}`), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
-
- assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddTable.xlsx")))
-
- // Test addTable with illegal cell coordinates.
- f = NewFile()
- assert.EqualError(t, f.addTable("sheet1", "", 0, 0, 0, 0, 0, nil), "invalid cell coordinates [0, 0]")
- assert.EqualError(t, f.addTable("sheet1", "", 1, 1, 0, 0, 0, nil), "invalid cell coordinates [0, 0]")
-}
-
-func TestAddShape(t *testing.T) {
- f, err := prepareTestBook1()
- if !assert.NoError(t, err) {
- t.FailNow()
- }
-
- assert.NoError(t, f.AddShape("Sheet1", "A30", `{"type":"rect","paragraph":[{"text":"Rectangle","font":{"color":"CD5C5C"}},{"text":"Shape","font":{"bold":true,"color":"2980B9"}}]}`))
- assert.NoError(t, f.AddShape("Sheet1", "B30", `{"type":"rect","paragraph":[{"text":"Rectangle"},{}]}`))
- assert.NoError(t, f.AddShape("Sheet1", "C30", `{"type":"rect","paragraph":[]}`))
- assert.EqualError(t, f.AddShape("Sheet3", "H1", `{"type":"ellipseRibbon", "color":{"line":"#4286f4","fill":"#8eb9ff"}, "paragraph":[{"font":{"bold":true,"italic":true,"family":"Times New Roman","size":36,"color":"#777777","underline":"single"}}], "height": 90}`), "sheet Sheet3 is not exist")
- assert.EqualError(t, f.AddShape("Sheet3", "H1", ""), "unexpected end of JSON input")
- assert.EqualError(t, f.AddShape("Sheet1", "A", `{"type":"rect","paragraph":[{"text":"Rectangle","font":{"color":"CD5C5C"}},{"text":"Shape","font":{"bold":true,"color":"2980B9"}}]}`), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
- assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddShape1.xlsx")))
-
- // Test add first shape for given sheet.
- f = NewFile()
- assert.NoError(t, f.AddShape("Sheet1", "A1", `{"type":"ellipseRibbon", "color":{"line":"#4286f4","fill":"#8eb9ff"}, "paragraph":[{"font":{"bold":true,"italic":true,"family":"Times New Roman","size":36,"color":"#777777","underline":"single"}}], "height": 90}`))
- assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddShape2.xlsx")))
-}
-
func TestGetSheetComments(t *testing.T) {
f := NewFile()
assert.Equal(t, "", f.getSheetComments(0))
}
-func TestAutoFilter(t *testing.T) {
- outFile := filepath.Join("test", "TestAutoFilter%d.xlsx")
-
- f, err := prepareTestBook1()
- if !assert.NoError(t, err) {
- t.FailNow()
- }
-
- formats := []string{
- ``,
- `{"column":"B","expression":"x != blanks"}`,
- `{"column":"B","expression":"x == blanks"}`,
- `{"column":"B","expression":"x != nonblanks"}`,
- `{"column":"B","expression":"x == nonblanks"}`,
- `{"column":"B","expression":"x <= 1 and x >= 2"}`,
- `{"column":"B","expression":"x == 1 or x == 2"}`,
- `{"column":"B","expression":"x == 1 or x == 2*"}`,
- }
-
- for i, format := range formats {
- t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
- err = f.AutoFilter("Sheet1", "D4", "B1", format)
- assert.NoError(t, err)
- assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, i+1)))
- })
- }
-
- // testing AutoFilter with illegal cell coordinates.
- assert.EqualError(t, f.AutoFilter("Sheet1", "A", "B1", ""), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
- assert.EqualError(t, f.AutoFilter("Sheet1", "A1", "B", ""), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
-}
-
-func TestAutoFilterError(t *testing.T) {
- outFile := filepath.Join("test", "TestAutoFilterError%d.xlsx")
-
- f, err := prepareTestBook1()
- if !assert.NoError(t, err) {
- t.FailNow()
- }
-
- formats := []string{
- `{"column":"B","expression":"x <= 1 and x >= blanks"}`,
- `{"column":"B","expression":"x -- y or x == *2*"}`,
- `{"column":"B","expression":"x != y or x ? *2"}`,
- `{"column":"B","expression":"x -- y o r x == *2"}`,
- `{"column":"B","expression":"x -- y"}`,
- `{"column":"A","expression":"x -- y"}`,
- }
- for i, format := range formats {
- t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
- err = f.AutoFilter("Sheet3", "D4", "B1", format)
- if assert.Error(t, err) {
- assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, i+1)))
- }
- })
- }
-}
-
func TestSetActiveSheet(t *testing.T) {
f := NewFile()
f.WorkBook.BookViews = nil
diff --git a/file.go b/file.go
index d8f10fa..6213bb1 100644
--- a/file.go
+++ b/file.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/lib.go b/lib.go
index 86f8d16..2d606fa 100644
--- a/lib.go
+++ b/lib.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/picture.go b/picture.go
index 01df849..80b0a52 100644
--- a/picture.go
+++ b/picture.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/pivotTable.go b/pivotTable.go
index 6045e41..8610280 100644
--- a/pivotTable.go
+++ b/pivotTable.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/rows.go b/rows.go
index 687828c..20b4379 100644
--- a/rows.go
+++ b/rows.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/shape.go b/shape.go
index 2ea66ea..e9bdb42 100644
--- a/shape.go
+++ b/shape.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/shape_test.go b/shape_test.go
new file mode 100644
index 0000000..61fb443
--- /dev/null
+++ b/shape_test.go
@@ -0,0 +1,28 @@
+package excelize
+
+import (
+ "path/filepath"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAddShape(t *testing.T) {
+ f, err := prepareTestBook1()
+ if !assert.NoError(t, err) {
+ t.FailNow()
+ }
+
+ assert.NoError(t, f.AddShape("Sheet1", "A30", `{"type":"rect","paragraph":[{"text":"Rectangle","font":{"color":"CD5C5C"}},{"text":"Shape","font":{"bold":true,"color":"2980B9"}}]}`))
+ assert.NoError(t, f.AddShape("Sheet1", "B30", `{"type":"rect","paragraph":[{"text":"Rectangle"},{}]}`))
+ assert.NoError(t, f.AddShape("Sheet1", "C30", `{"type":"rect","paragraph":[]}`))
+ assert.EqualError(t, f.AddShape("Sheet3", "H1", `{"type":"ellipseRibbon", "color":{"line":"#4286f4","fill":"#8eb9ff"}, "paragraph":[{"font":{"bold":true,"italic":true,"family":"Times New Roman","size":36,"color":"#777777","underline":"single"}}], "height": 90}`), "sheet Sheet3 is not exist")
+ assert.EqualError(t, f.AddShape("Sheet3", "H1", ""), "unexpected end of JSON input")
+ assert.EqualError(t, f.AddShape("Sheet1", "A", `{"type":"rect","paragraph":[{"text":"Rectangle","font":{"color":"CD5C5C"}},{"text":"Shape","font":{"bold":true,"color":"2980B9"}}]}`), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
+ assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddShape1.xlsx")))
+
+ // Test add first shape for given sheet.
+ f = NewFile()
+ assert.NoError(t, f.AddShape("Sheet1", "A1", `{"type":"ellipseRibbon", "color":{"line":"#4286f4","fill":"#8eb9ff"}, "paragraph":[{"font":{"bold":true,"italic":true,"family":"Times New Roman","size":36,"color":"#777777","underline":"single"}}], "height": 90}`))
+ assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddShape2.xlsx")))
+}
diff --git a/sheet.go b/sheet.go
index 954de5b..2654b8f 100644
--- a/sheet.go
+++ b/sheet.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/sheetpr.go b/sheetpr.go
index 086bd3a..350e189 100644
--- a/sheetpr.go
+++ b/sheetpr.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/sheetview.go b/sheetview.go
index 8a5091f..fa3cfdf 100644
--- a/sheetview.go
+++ b/sheetview.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/sparkline.go b/sparkline.go
index 47c8d5a..ef99da6 100644
--- a/sparkline.go
+++ b/sparkline.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/stream.go b/stream.go
index e981f78..9facf31 100644
--- a/stream.go
+++ b/stream.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
@@ -36,20 +36,27 @@ type StreamWriter struct {
// rows, you must call the 'Flush' method to end the streaming writing
// process and ensure that the order of line numbers is ascending. For
// example, set data for worksheet of size 102400 rows x 50 columns with
-// numbers:
+// numbers and style:
//
// file := excelize.NewFile()
// streamWriter, err := file.NewStreamWriter("Sheet1")
// if err != nil {
// panic(err)
// }
-// for rowID := 1; rowID <= 102400; rowID++ {
+// styleID, err := file.NewStyle(`{"font":{"color":"#777777"}}`)
+// if err != nil {
+// panic(err)
+// }
+// if err := streamWriter.SetRow("A1", []interface{}{excelize.Cell{StyleID: styleID, Value: "Data"}}); err != nil {
+// panic(err)
+// }
+// for rowID := 2; rowID <= 102400; rowID++ {
// row := make([]interface{}, 50)
// for colID := 0; colID < 50; colID++ {
// row[colID] = rand.Intn(640000)
// }
// cell, _ := excelize.CoordinatesToCellName(1, rowID)
-// if err := streamWriter.SetRow(cell, row, nil); err != nil {
+// if err := streamWriter.SetRow(cell, row); err != nil {
// panic(err)
// }
// }
@@ -107,7 +114,7 @@ func (sw *StreamWriter) AddTable(hcell, vcell, format string) error {
if err != nil {
return err
}
- sortCoordinates(coordinates)
+ _ = sortCoordinates(coordinates)
// Correct the minimum number of rows, the table at least two lines.
if coordinates[1] == coordinates[3] {
@@ -188,7 +195,7 @@ func (sw *StreamWriter) getRowValues(hrow, hcol, vcol int) (res []string, err er
return nil, err
}
- dec := xml.NewDecoder(r)
+ dec := sw.File.xmlNewDecoder(r)
for {
token, err := dec.Token()
if err == io.EOF {
@@ -248,7 +255,7 @@ func getRowElement(token xml.Token, hrow int) (startElement xml.StartElement, ok
// a value.
type Cell struct {
StyleID int
- Value interface{}
+ Value interface{}
}
// SetRow writes an array to stream rows by giving a worksheet name, starting
@@ -277,47 +284,8 @@ func (sw *StreamWriter) SetRow(axis string, values []interface{}) error {
c.S = v.StyleID
val = v.Value
}
- switch val := val.(type) {
- case int:
- c.T, c.V = setCellInt(val)
- case int8:
- c.T, c.V = setCellInt(int(val))
- case int16:
- c.T, c.V = setCellInt(int(val))
- case int32:
- c.T, c.V = setCellInt(int(val))
- case int64:
- c.T, c.V = setCellInt(int(val))
- case uint:
- c.T, c.V = setCellInt(int(val))
- case uint8:
- c.T, c.V = setCellInt(int(val))
- case uint16:
- c.T, c.V = setCellInt(int(val))
- case uint32:
- c.T, c.V = setCellInt(int(val))
- case uint64:
- c.T, c.V = setCellInt(int(val))
- case float32:
- c.T, c.V = setCellFloat(float64(val), -1, 32)
- case float64:
- c.T, c.V = setCellFloat(val, -1, 64)
- case string:
- c.T, c.V, c.XMLSpace = setCellStr(val)
- case []byte:
- c.T, c.V, c.XMLSpace = setCellStr(string(val))
- case time.Duration:
- c.T, c.V = setCellDuration(val)
- case time.Time:
- c.T, c.V, _, err = setCellTime(val)
- case bool:
- c.T, c.V = setCellBool(val)
- case nil:
- c.T, c.V, c.XMLSpace = setCellStr("")
- default:
- c.T, c.V, c.XMLSpace = setCellStr(fmt.Sprint(val))
- }
- if err != nil {
+ if err = setCellValFunc(&c, val); err != nil {
+ sw.rawData.WriteString(`</row>`)
return err
}
writeCell(&sw.rawData, c)
@@ -326,6 +294,61 @@ func (sw *StreamWriter) SetRow(axis string, values []interface{}) error {
return sw.rawData.Sync()
}
+// setCellValFunc provides a function to set value of a cell.
+func setCellValFunc(c *xlsxC, val interface{}) (err error) {
+ switch val := val.(type) {
+ case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
+ err = setCellIntFunc(c, val)
+ case float32:
+ c.T, c.V = setCellFloat(float64(val), -1, 32)
+ case float64:
+ c.T, c.V = setCellFloat(val, -1, 64)
+ case string:
+ c.T, c.V, c.XMLSpace = setCellStr(val)
+ case []byte:
+ c.T, c.V, c.XMLSpace = setCellStr(string(val))
+ case time.Duration:
+ c.T, c.V = setCellDuration(val)
+ case time.Time:
+ c.T, c.V, _, err = setCellTime(val)
+ case bool:
+ c.T, c.V = setCellBool(val)
+ case nil:
+ c.T, c.V, c.XMLSpace = setCellStr("")
+ default:
+ c.T, c.V, c.XMLSpace = setCellStr(fmt.Sprint(val))
+ }
+ return err
+}
+
+// setCellIntFunc is a wrapper of SetCellInt.
+func setCellIntFunc(c *xlsxC, val interface{}) (err error) {
+ switch val := val.(type) {
+ case int:
+ c.T, c.V = setCellInt(val)
+ case int8:
+ c.T, c.V = setCellInt(int(val))
+ case int16:
+ c.T, c.V = setCellInt(int(val))
+ case int32:
+ c.T, c.V = setCellInt(int(val))
+ case int64:
+ c.T, c.V = setCellInt(int(val))
+ case uint:
+ c.T, c.V = setCellInt(int(val))
+ case uint8:
+ c.T, c.V = setCellInt(int(val))
+ case uint16:
+ c.T, c.V = setCellInt(int(val))
+ case uint32:
+ c.T, c.V = setCellInt(int(val))
+ case uint64:
+ c.T, c.V = setCellInt(int(val))
+ default:
+ }
+ return
+}
+
func writeCell(buf *bufferedWriter, c xlsxC) {
buf.WriteString(`<c`)
if c.XMLSpace.Value != "" {
@@ -391,8 +414,8 @@ func bulkAppendOtherFields(w io.Writer, ws *xlsxWorksheet, skip ...string) {
// bufferedWriter uses a temp file to store an extended buffer. Writes are
// always made to an in-memory buffer, which will always succeed. The buffer
-// is written to the temp file with Sync, which may return an error. Therefore,
-// Sync should be periodically called and the error checked.
+// is written to the temp file with Sync, which may return an error.
+// Therefore, Sync should be periodically called and the error checked.
type bufferedWriter struct {
tmp *os.File
buf bytes.Buffer
@@ -454,8 +477,8 @@ func (bw *bufferedWriter) Bytes() ([]byte, error) {
return buf.Bytes(), err
}
-// Sync will write the in-memory buffer to a temp file, if the in-memory buffer
-// has grown large enough. Any error will be returned.
+// Sync will write the in-memory buffer to a temp file, if the in-memory
+// buffer has grown large enough. Any error will be returned.
func (bw *bufferedWriter) Sync() (err error) {
// Try to use local storage
const chunk = 1 << 24
diff --git a/stream_test.go b/stream_test.go
index 015f64b..8c5e7ea 100644
--- a/stream_test.go
+++ b/stream_test.go
@@ -3,10 +3,13 @@ package excelize
import (
"encoding/xml"
"fmt"
+ "io/ioutil"
"math/rand"
+ "os"
"path/filepath"
"strings"
"testing"
+ "time"
"github.com/stretchr/testify/assert"
)
@@ -49,6 +52,13 @@ func TestStreamWriter(t *testing.T) {
row[0] = []byte("Word")
assert.NoError(t, streamWriter.SetRow("A3", row))
+ // Test set cell with style.
+ styleID, err := file.NewStyle(`{"font":{"color":"#777777"}}`)
+ assert.NoError(t, err)
+ assert.NoError(t, streamWriter.SetRow("A4", []interface{}{Cell{StyleID: styleID}}))
+ assert.NoError(t, streamWriter.SetRow("A5", []interface{}{&Cell{StyleID: styleID, Value: "cell"}}))
+ assert.EqualError(t, streamWriter.SetRow("A6", []interface{}{time.Now()}), "only UTC time expected")
+
for rowID := 10; rowID <= 51200; rowID++ {
row := make([]interface{}, 50)
for colID := 0; colID < 50; colID++ {
@@ -62,7 +72,7 @@ func TestStreamWriter(t *testing.T) {
// Save xlsx file by the given path.
assert.NoError(t, file.SaveAs(filepath.Join("test", "TestStreamWriter.xlsx")))
- // Test close temporary file error
+ // Test close temporary file error.
file = NewFile()
streamWriter, err = file.NewStreamWriter("Sheet1")
assert.NoError(t, err)
@@ -76,6 +86,12 @@ func TestStreamWriter(t *testing.T) {
}
assert.NoError(t, streamWriter.rawData.Close())
assert.Error(t, streamWriter.Flush())
+
+ streamWriter.rawData.tmp, err = ioutil.TempFile(os.TempDir(), "excelize-")
+ assert.NoError(t, err)
+ _, err = streamWriter.rawData.Reader()
+ assert.NoError(t, err)
+ assert.NoError(t, os.Remove(streamWriter.rawData.tmp.Name()))
}
func TestStreamTable(t *testing.T) {
@@ -100,6 +116,14 @@ func TestStreamTable(t *testing.T) {
assert.Equal(t, "A", table.TableColumns.TableColumn[0].Name)
assert.Equal(t, "B", table.TableColumns.TableColumn[1].Name)
assert.Equal(t, "C", table.TableColumns.TableColumn[2].Name)
+
+ assert.NoError(t, streamWriter.AddTable("A1", "C1", ``))
+
+ // Test add table with illegal formatset.
+ assert.EqualError(t, streamWriter.AddTable("B26", "A21", `{x}`), "invalid character 'x' looking for beginning of object key string")
+ // Test add table with illegal cell coordinates.
+ assert.EqualError(t, streamWriter.AddTable("A", "B1", `{}`), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
+ assert.EqualError(t, streamWriter.AddTable("A1", "B", `{}`), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
}
func TestNewStreamWriter(t *testing.T) {
@@ -118,3 +142,26 @@ func TestSetRow(t *testing.T) {
assert.NoError(t, err)
assert.EqualError(t, streamWriter.SetRow("A", []interface{}{}), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
}
+
+func TestSetCellValFunc(t *testing.T) {
+ c := &xlsxC{}
+ assert.NoError(t, setCellValFunc(c, 128))
+ assert.NoError(t, setCellValFunc(c, int8(-128)))
+ assert.NoError(t, setCellValFunc(c, int16(-32768)))
+ assert.NoError(t, setCellValFunc(c, int32(-2147483648)))
+ assert.NoError(t, setCellValFunc(c, int64(-9223372036854775808)))
+ assert.NoError(t, setCellValFunc(c, uint(128)))
+ assert.NoError(t, setCellValFunc(c, uint8(255)))
+ assert.NoError(t, setCellValFunc(c, uint16(65535)))
+ assert.NoError(t, setCellValFunc(c, uint32(4294967295)))
+ assert.NoError(t, setCellValFunc(c, uint64(18446744073709551615)))
+ assert.NoError(t, setCellValFunc(c, float32(100.1588)))
+ assert.NoError(t, setCellValFunc(c, float64(100.1588)))
+ assert.NoError(t, setCellValFunc(c, " Hello"))
+ assert.NoError(t, setCellValFunc(c, []byte(" Hello")))
+ assert.NoError(t, setCellValFunc(c, time.Now().UTC()))
+ assert.NoError(t, setCellValFunc(c, time.Duration(1e13)))
+ assert.NoError(t, setCellValFunc(c, true))
+ assert.NoError(t, setCellValFunc(c, nil))
+ assert.NoError(t, setCellValFunc(c, complex64(5+10i)))
+}
diff --git a/styles.go b/styles.go
index 56c7196..272d728 100644
--- a/styles.go
+++ b/styles.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/styles_test.go b/styles_test.go
index e6faccb..a536700 100644
--- a/styles_test.go
+++ b/styles_test.go
@@ -169,9 +169,7 @@ func TestSetConditionalFormat(t *testing.T) {
func TestNewStyle(t *testing.T) {
f := NewFile()
styleID, err := f.NewStyle(`{"font":{"bold":true,"italic":true,"family":"Times New Roman","size":36,"color":"#777777"}}`)
- if err != nil {
- t.Fatal(err)
- }
+ assert.NoError(t, err)
styles := f.stylesReader()
fontID := styles.CellXfs.Xf[styleID].FontID
font := styles.Fonts.Font[fontID]
diff --git a/table.go b/table.go
index 3d76690..566238c 100644
--- a/table.go
+++ b/table.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/table_test.go b/table_test.go
new file mode 100644
index 0000000..89c03e2
--- /dev/null
+++ b/table_test.go
@@ -0,0 +1,125 @@
+package excelize
+
+import (
+ "fmt"
+ "path/filepath"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAddTable(t *testing.T) {
+ f, err := prepareTestBook1()
+ if !assert.NoError(t, err) {
+ t.FailNow()
+ }
+
+ err = f.AddTable("Sheet1", "B26", "A21", `{}`)
+ if !assert.NoError(t, err) {
+ t.FailNow()
+ }
+
+ err = f.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}`)
+ if !assert.NoError(t, err) {
+ t.FailNow()
+ }
+
+ err = f.AddTable("Sheet2", "F1", "F1", `{"table_style":"TableStyleMedium8"}`)
+ if !assert.NoError(t, err) {
+ t.FailNow()
+ }
+
+ // Test add table with illegal formatset.
+ assert.EqualError(t, f.AddTable("Sheet1", "B26", "A21", `{x}`), "invalid character 'x' looking for beginning of object key string")
+ // Test add table with illegal cell coordinates.
+ assert.EqualError(t, f.AddTable("Sheet1", "A", "B1", `{}`), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
+ assert.EqualError(t, f.AddTable("Sheet1", "A1", "B", `{}`), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
+
+ assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddTable.xlsx")))
+
+ // Test addTable with illegal cell coordinates.
+ f = NewFile()
+ assert.EqualError(t, f.addTable("sheet1", "", 0, 0, 0, 0, 0, nil), "invalid cell coordinates [0, 0]")
+ assert.EqualError(t, f.addTable("sheet1", "", 1, 1, 0, 0, 0, nil), "invalid cell coordinates [0, 0]")
+}
+
+func TestAutoFilter(t *testing.T) {
+ outFile := filepath.Join("test", "TestAutoFilter%d.xlsx")
+
+ f, err := prepareTestBook1()
+ if !assert.NoError(t, err) {
+ t.FailNow()
+ }
+
+ formats := []string{
+ ``,
+ `{"column":"B","expression":"x != blanks"}`,
+ `{"column":"B","expression":"x == blanks"}`,
+ `{"column":"B","expression":"x != nonblanks"}`,
+ `{"column":"B","expression":"x == nonblanks"}`,
+ `{"column":"B","expression":"x <= 1 and x >= 2"}`,
+ `{"column":"B","expression":"x == 1 or x == 2"}`,
+ `{"column":"B","expression":"x == 1 or x == 2*"}`,
+ }
+
+ for i, format := range formats {
+ t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
+ err = f.AutoFilter("Sheet1", "D4", "B1", format)
+ assert.NoError(t, err)
+ assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, i+1)))
+ })
+ }
+
+ // testing AutoFilter with illegal cell coordinates.
+ assert.EqualError(t, f.AutoFilter("Sheet1", "A", "B1", ""), `cannot convert cell "A" to coordinates: invalid cell name "A"`)
+ assert.EqualError(t, f.AutoFilter("Sheet1", "A1", "B", ""), `cannot convert cell "B" to coordinates: invalid cell name "B"`)
+}
+
+func TestAutoFilterError(t *testing.T) {
+ outFile := filepath.Join("test", "TestAutoFilterError%d.xlsx")
+
+ f, err := prepareTestBook1()
+ if !assert.NoError(t, err) {
+ t.FailNow()
+ }
+
+ formats := []string{
+ `{"column":"B","expression":"x <= 1 and x >= blanks"}`,
+ `{"column":"B","expression":"x -- y or x == *2*"}`,
+ `{"column":"B","expression":"x != y or x ? *2"}`,
+ `{"column":"B","expression":"x -- y o r x == *2"}`,
+ `{"column":"B","expression":"x -- y"}`,
+ `{"column":"A","expression":"x -- y"}`,
+ }
+ for i, format := range formats {
+ t.Run(fmt.Sprintf("Expression%d", i+1), func(t *testing.T) {
+ err = f.AutoFilter("Sheet3", "D4", "B1", format)
+ if assert.Error(t, err) {
+ assert.NoError(t, f.SaveAs(fmt.Sprintf(outFile, i+1)))
+ }
+ })
+ }
+
+ assert.EqualError(t, f.autoFilter("Sheet1", "A1", 1, 1, &formatAutoFilter{
+ Column: "-",
+ Expression: "-",
+ }), `invalid column name "-"`)
+ assert.EqualError(t, f.autoFilter("Sheet1", "A1", 1, 100, &formatAutoFilter{
+ Column: "A",
+ Expression: "-",
+ }), `incorrect index of column 'A'`)
+ assert.EqualError(t, f.autoFilter("Sheet1", "A1", 1, 1, &formatAutoFilter{
+ Column: "A",
+ Expression: "-",
+ }), `incorrect number of tokens in criteria '-'`)
+}
+
+func TestParseFilterTokens(t *testing.T) {
+ f := NewFile()
+ // Test with unknown operator.
+ _, _, err := f.parseFilterTokens("", []string{"", "!"})
+ assert.EqualError(t, err, "unknown operator: !")
+ // Test invalid operator in context.
+ _, _, err = f.parseFilterTokens("", []string{"", "<", "x != blanks"})
+ assert.EqualError(t, err, "the operator '<' in expression '' is not valid in relation to Blanks/NonBlanks'")
+}
diff --git a/templates.go b/templates.go
index 5b79b0c..a7972e6 100644
--- a/templates.go
+++ b/templates.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/vmlDrawing.go b/vmlDrawing.go
index 24b615f..f2d55f1 100644
--- a/vmlDrawing.go
+++ b/vmlDrawing.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlApp.go b/xmlApp.go
index 48450e3..5668cf6 100644
--- a/xmlApp.go
+++ b/xmlApp.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlCalcChain.go b/xmlCalcChain.go
index 343f15f..69d5d8c 100644
--- a/xmlCalcChain.go
+++ b/xmlCalcChain.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlChart.go b/xmlChart.go
index fc38dab..b6d041e 100644
--- a/xmlChart.go
+++ b/xmlChart.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlComments.go b/xmlComments.go
index f13d002..687c486 100644
--- a/xmlComments.go
+++ b/xmlComments.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlContentTypes.go b/xmlContentTypes.go
index fa4d347..7acfe08 100644
--- a/xmlContentTypes.go
+++ b/xmlContentTypes.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlCore.go b/xmlCore.go
index 96482fc..6f71a3e 100644
--- a/xmlCore.go
+++ b/xmlCore.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlDecodeDrawing.go b/xmlDecodeDrawing.go
index e11bb00..93e0e82 100644
--- a/xmlDecodeDrawing.go
+++ b/xmlDecodeDrawing.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlDrawing.go b/xmlDrawing.go
index 1c24f08..5bb5977 100644
--- a/xmlDrawing.go
+++ b/xmlDrawing.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlPivotTable.go b/xmlPivotTable.go
index 6e1dfb8..82bbf27 100644
--- a/xmlPivotTable.go
+++ b/xmlPivotTable.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlSharedStrings.go b/xmlSharedStrings.go
index 7983741..61e5727 100644
--- a/xmlSharedStrings.go
+++ b/xmlSharedStrings.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlStyles.go b/xmlStyles.go
index 16a89ab..0313008 100644
--- a/xmlStyles.go
+++ b/xmlStyles.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlTable.go b/xmlTable.go
index 017bda1..345337f 100644
--- a/xmlTable.go
+++ b/xmlTable.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlTheme.go b/xmlTheme.go
index f764c20..76f13b4 100644
--- a/xmlTheme.go
+++ b/xmlTheme.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlWorkbook.go b/xmlWorkbook.go
index 65606b0..bc59924 100644
--- a/xmlWorkbook.go
+++ b/xmlWorkbook.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//
diff --git a/xmlWorksheet.go b/xmlWorksheet.go
index c17d12f..ed304cc 100644
--- a/xmlWorksheet.go
+++ b/xmlWorksheet.go
@@ -1,4 +1,4 @@
-// Copyright 2016 - 2019 The excelize Authors. All rights reserved. Use of
+// Copyright 2016 - 2020 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in
// the LICENSE file.
//