summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2020-04-10 00:04:23 +0800
committerxuri <xuri.me@gmail.com>2020-04-10 00:08:17 +0800
commit10115b5d889bb229d8707803b9413b20fe798588 (patch)
tree5ab719ea216a95580556c957a1568eb93f0ef43f
parente36650f4ffd3e305d2c3834620f97ec382cf6faf (diff)
- Resolve #611, fix failure BenchmarkSetCellValue
- Allow empty filter, data, and rows in the pivot table - Add more test case for pivot table
-rw-r--r--cell_test.go5
-rw-r--r--pivotTable.go68
-rw-r--r--pivotTable_test.go40
3 files changed, 89 insertions, 24 deletions
diff --git a/cell_test.go b/cell_test.go
index f46b4b9..45e2f24 100644
--- a/cell_test.go
+++ b/cell_test.go
@@ -3,6 +3,7 @@ package excelize
import (
"fmt"
"path/filepath"
+ "strconv"
"testing"
"time"
@@ -122,9 +123,9 @@ func BenchmarkSetCellValue(b *testing.B) {
cols := []string{"A", "B", "C", "D", "E", "F"}
f := NewFile()
b.ResetTimer()
- for i := 0; i < b.N; i++ {
+ for i := 1; i <= b.N; i++ {
for j := 0; j < len(values); j++ {
- if err := f.SetCellValue("Sheet1", fmt.Sprint(cols[j], i), values[j]); err != nil {
+ if err := f.SetCellValue("Sheet1", cols[j]+strconv.Itoa(i), values[j]); err != nil {
b.Error(err)
}
}
diff --git a/pivotTable.go b/pivotTable.go
index 7061bfe..cf04381 100644
--- a/pivotTable.go
+++ b/pivotTable.go
@@ -21,7 +21,6 @@ import (
type PivotTableOption struct {
DataRange string
PivotTableRange string
- Page []PivotTableField
Rows []PivotTableField
Columns []PivotTableField
Data []PivotTableField
@@ -194,7 +193,6 @@ func (f *File) adjustRange(rangeStr string) (string, []int, error) {
// fields.
func (f *File) getPivotFieldsOrder(dataRange string) ([]string, error) {
order := []string{}
- // data range has been checked
dataSheet, coordinates, err := f.adjustRange(dataRange)
if err != nil {
return order, fmt.Errorf("parameter 'DataRange' parsing error: %s", err.Error())
@@ -217,10 +215,8 @@ func (f *File) addPivotCache(pivotCacheID int, pivotCacheXML string, opt *PivotT
if err != nil {
return fmt.Errorf("parameter 'DataRange' parsing error: %s", err.Error())
}
- order, err := f.getPivotFieldsOrder(opt.DataRange)
- if err != nil {
- return err
- }
+ // data range has been checked
+ order, _ := f.getPivotFieldsOrder(opt.DataRange)
hcell, _ := CoordinatesToCellName(coordinates[0], coordinates[1])
vcell, _ := CoordinatesToCellName(coordinates[2], coordinates[3])
pc := xlsxPivotCacheDefinition{
@@ -272,7 +268,6 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
FirstHeaderRow: 1,
},
PivotFields: &xlsxPivotFields{},
- RowFields: &xlsxRowFields{},
RowItems: &xlsxRowItems{
Count: 1,
I: []*xlsxI{
@@ -285,8 +280,6 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
Count: 1,
I: []*xlsxI{{}},
},
- PageFields: &xlsxPageFields{},
- DataFields: &xlsxDataFields{},
PivotTableStyleInfo: &xlsxPivotTableStyleInfo{
Name: "PivotStyleLight16",
ShowRowHeaders: true,
@@ -296,33 +289,49 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
}
// pivot fields
- err = f.addPivotFields(&pt, opt)
- if err != nil {
- return err
- }
+ _ = f.addPivotFields(&pt, opt)
// count pivot fields
pt.PivotFields.Count = len(pt.PivotFields.PivotField)
+ // data range has been checked
+ _ = f.addPivotRowFields(&pt, opt)
+ _ = f.addPivotColFields(&pt, opt)
+ _ = f.addPivotPageFields(&pt, opt)
+ _ = f.addPivotDataFields(&pt, opt)
+
+ pivotTable, err := xml.Marshal(pt)
+ f.saveFileList(pivotTableXML, pivotTable)
+ return err
+}
+
+// addPivotRowFields provides a method to add row fields for pivot table by
+// given pivot table options.
+func (f *File) addPivotRowFields(pt *xlsxPivotTableDefinition, opt *PivotTableOption) error {
// row fields
rowFieldsIndex, err := f.getPivotFieldsIndex(opt.Rows, opt)
if err != nil {
return err
}
for _, fieldIdx := range rowFieldsIndex {
+ if pt.RowFields == nil {
+ pt.RowFields = &xlsxRowFields{}
+ }
pt.RowFields.Field = append(pt.RowFields.Field, &xlsxField{
X: fieldIdx,
})
}
// count row fields
- pt.RowFields.Count = len(pt.RowFields.Field)
-
- err = f.addPivotColFields(&pt, opt)
- if err != nil {
- return err
+ if pt.RowFields != nil {
+ pt.RowFields.Count = len(pt.RowFields.Field)
}
+ return err
+}
+// addPivotPageFields provides a method to add page fields for pivot table by
+// given pivot table options.
+func (f *File) addPivotPageFields(pt *xlsxPivotTableDefinition, opt *PivotTableOption) error {
// page fields
pageFieldsIndex, err := f.getPivotFieldsIndex(opt.Filter, opt)
if err != nil {
@@ -330,12 +339,25 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
}
pageFieldsName := f.getPivotTableFieldsName(opt.Filter)
for idx, pageField := range pageFieldsIndex {
+ if pt.PageFields == nil {
+ pt.PageFields = &xlsxPageFields{}
+ }
pt.PageFields.PageField = append(pt.PageFields.PageField, &xlsxPageField{
Name: pageFieldsName[idx],
Fld: pageField,
})
}
+ // count page fields
+ if pt.PageFields != nil {
+ pt.PageFields.Count = len(pt.PageFields.PageField)
+ }
+ return err
+}
+
+// addPivotDataFields provides a method to add data fields for pivot table by
+// given pivot table options.
+func (f *File) addPivotDataFields(pt *xlsxPivotTableDefinition, opt *PivotTableOption) error {
// data fields
dataFieldsIndex, err := f.getPivotFieldsIndex(opt.Data, opt)
if err != nil {
@@ -344,6 +366,9 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
dataFieldsSubtotals := f.getPivotTableFieldsSubtotal(opt.Data)
dataFieldsName := f.getPivotTableFieldsName(opt.Data)
for idx, dataField := range dataFieldsIndex {
+ if pt.DataFields == nil {
+ pt.DataFields = &xlsxDataFields{}
+ }
pt.DataFields.DataField = append(pt.DataFields.DataField, &xlsxDataField{
Name: dataFieldsName[idx],
Fld: dataField,
@@ -352,10 +377,9 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
}
// count data fields
- pt.DataFields.Count = len(pt.DataFields.DataField)
-
- pivotTable, err := xml.Marshal(pt)
- f.saveFileList(pivotTableXML, pivotTable)
+ if pt.DataFields != nil {
+ pt.DataFields.Count = len(pt.DataFields.DataField)
+ }
return err
}
diff --git a/pivotTable_test.go b/pivotTable_test.go
index 767206b..cc80835 100644
--- a/pivotTable_test.go
+++ b/pivotTable_test.go
@@ -179,6 +179,46 @@ func TestAddPivotTable(t *testing.T) {
assert.EqualError(t, err, `parameter 'DataRange' parsing error: parameter is required`)
}
+func TestAddPivotRowFields(t *testing.T) {
+ f := NewFile()
+ // Test invalid data range
+ assert.EqualError(t, f.addPivotRowFields(&xlsxPivotTableDefinition{}, &PivotTableOption{
+ DataRange: "Sheet1!$A$1:$A$1",
+ }), `parameter 'DataRange' parsing error: parameter is invalid`)
+}
+
+func TestAddPivotPageFields(t *testing.T) {
+ f := NewFile()
+ // Test invalid data range
+ assert.EqualError(t, f.addPivotPageFields(&xlsxPivotTableDefinition{}, &PivotTableOption{
+ DataRange: "Sheet1!$A$1:$A$1",
+ }), `parameter 'DataRange' parsing error: parameter is invalid`)
+}
+
+func TestAddPivotDataFields(t *testing.T) {
+ f := NewFile()
+ // Test invalid data range
+ assert.EqualError(t, f.addPivotDataFields(&xlsxPivotTableDefinition{}, &PivotTableOption{
+ DataRange: "Sheet1!$A$1:$A$1",
+ }), `parameter 'DataRange' parsing error: parameter is invalid`)
+}
+
+func TestAddPivotColFields(t *testing.T) {
+ f := NewFile()
+ // Test invalid data range
+ assert.EqualError(t, f.addPivotColFields(&xlsxPivotTableDefinition{}, &PivotTableOption{
+ DataRange: "Sheet1!$A$1:$A$1",
+ Columns: []PivotTableField{{Data: "Type"}},
+ }), `parameter 'DataRange' parsing error: parameter is invalid`)
+}
+
+func TestGetPivotFieldsOrder(t *testing.T) {
+ f := NewFile()
+ // Test get pivot fields order with not exist worksheet
+ _, err := f.getPivotFieldsOrder("SheetN!$A$1:$E$31")
+ assert.EqualError(t, err, "sheet SheetN is not exist")
+}
+
func TestInStrSlice(t *testing.T) {
assert.EqualValues(t, -1, inStrSlice([]string{}, ""))
}