- Resolve #611, fix failure BenchmarkSetCellValue

- Allow empty filter, data, and rows in the pivot table
- Add more test case for pivot table
formula
xuri 5 years ago
parent e36650f4ff
commit 10115b5d88

@ -3,6 +3,7 @@ package excelize
import ( import (
"fmt" "fmt"
"path/filepath" "path/filepath"
"strconv"
"testing" "testing"
"time" "time"
@ -122,9 +123,9 @@ func BenchmarkSetCellValue(b *testing.B) {
cols := []string{"A", "B", "C", "D", "E", "F"} cols := []string{"A", "B", "C", "D", "E", "F"}
f := NewFile() f := NewFile()
b.ResetTimer() b.ResetTimer()
for i := 0; i < b.N; i++ { for i := 1; i <= b.N; i++ {
for j := 0; j < len(values); j++ { 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) b.Error(err)
} }
} }

@ -21,7 +21,6 @@ import (
type PivotTableOption struct { type PivotTableOption struct {
DataRange string DataRange string
PivotTableRange string PivotTableRange string
Page []PivotTableField
Rows []PivotTableField Rows []PivotTableField
Columns []PivotTableField Columns []PivotTableField
Data []PivotTableField Data []PivotTableField
@ -194,7 +193,6 @@ func (f *File) adjustRange(rangeStr string) (string, []int, error) {
// fields. // fields.
func (f *File) getPivotFieldsOrder(dataRange string) ([]string, error) { func (f *File) getPivotFieldsOrder(dataRange string) ([]string, error) {
order := []string{} order := []string{}
// data range has been checked
dataSheet, coordinates, err := f.adjustRange(dataRange) dataSheet, coordinates, err := f.adjustRange(dataRange)
if err != nil { if err != nil {
return order, fmt.Errorf("parameter 'DataRange' parsing error: %s", err.Error()) 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 { if err != nil {
return fmt.Errorf("parameter 'DataRange' parsing error: %s", err.Error()) return fmt.Errorf("parameter 'DataRange' parsing error: %s", err.Error())
} }
order, err := f.getPivotFieldsOrder(opt.DataRange) // data range has been checked
if err != nil { order, _ := f.getPivotFieldsOrder(opt.DataRange)
return err
}
hcell, _ := CoordinatesToCellName(coordinates[0], coordinates[1]) hcell, _ := CoordinatesToCellName(coordinates[0], coordinates[1])
vcell, _ := CoordinatesToCellName(coordinates[2], coordinates[3]) vcell, _ := CoordinatesToCellName(coordinates[2], coordinates[3])
pc := xlsxPivotCacheDefinition{ pc := xlsxPivotCacheDefinition{
@ -272,7 +268,6 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
FirstHeaderRow: 1, FirstHeaderRow: 1,
}, },
PivotFields: &xlsxPivotFields{}, PivotFields: &xlsxPivotFields{},
RowFields: &xlsxRowFields{},
RowItems: &xlsxRowItems{ RowItems: &xlsxRowItems{
Count: 1, Count: 1,
I: []*xlsxI{ I: []*xlsxI{
@ -285,8 +280,6 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
Count: 1, Count: 1,
I: []*xlsxI{{}}, I: []*xlsxI{{}},
}, },
PageFields: &xlsxPageFields{},
DataFields: &xlsxDataFields{},
PivotTableStyleInfo: &xlsxPivotTableStyleInfo{ PivotTableStyleInfo: &xlsxPivotTableStyleInfo{
Name: "PivotStyleLight16", Name: "PivotStyleLight16",
ShowRowHeaders: true, ShowRowHeaders: true,
@ -296,33 +289,49 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
} }
// pivot fields // pivot fields
err = f.addPivotFields(&pt, opt) _ = f.addPivotFields(&pt, opt)
if err != nil {
return err
}
// count pivot fields // count pivot fields
pt.PivotFields.Count = len(pt.PivotFields.PivotField) 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 // row fields
rowFieldsIndex, err := f.getPivotFieldsIndex(opt.Rows, opt) rowFieldsIndex, err := f.getPivotFieldsIndex(opt.Rows, opt)
if err != nil { if err != nil {
return err return err
} }
for _, fieldIdx := range rowFieldsIndex { for _, fieldIdx := range rowFieldsIndex {
if pt.RowFields == nil {
pt.RowFields = &xlsxRowFields{}
}
pt.RowFields.Field = append(pt.RowFields.Field, &xlsxField{ pt.RowFields.Field = append(pt.RowFields.Field, &xlsxField{
X: fieldIdx, X: fieldIdx,
}) })
} }
// count row fields // count row fields
pt.RowFields.Count = len(pt.RowFields.Field) if pt.RowFields != nil {
pt.RowFields.Count = len(pt.RowFields.Field)
err = f.addPivotColFields(&pt, opt)
if err != nil {
return err
} }
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 // page fields
pageFieldsIndex, err := f.getPivotFieldsIndex(opt.Filter, opt) pageFieldsIndex, err := f.getPivotFieldsIndex(opt.Filter, opt)
if err != nil { if err != nil {
@ -330,12 +339,25 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
} }
pageFieldsName := f.getPivotTableFieldsName(opt.Filter) pageFieldsName := f.getPivotTableFieldsName(opt.Filter)
for idx, pageField := range pageFieldsIndex { for idx, pageField := range pageFieldsIndex {
if pt.PageFields == nil {
pt.PageFields = &xlsxPageFields{}
}
pt.PageFields.PageField = append(pt.PageFields.PageField, &xlsxPageField{ pt.PageFields.PageField = append(pt.PageFields.PageField, &xlsxPageField{
Name: pageFieldsName[idx], Name: pageFieldsName[idx],
Fld: pageField, 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 // data fields
dataFieldsIndex, err := f.getPivotFieldsIndex(opt.Data, opt) dataFieldsIndex, err := f.getPivotFieldsIndex(opt.Data, opt)
if err != nil { if err != nil {
@ -344,6 +366,9 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
dataFieldsSubtotals := f.getPivotTableFieldsSubtotal(opt.Data) dataFieldsSubtotals := f.getPivotTableFieldsSubtotal(opt.Data)
dataFieldsName := f.getPivotTableFieldsName(opt.Data) dataFieldsName := f.getPivotTableFieldsName(opt.Data)
for idx, dataField := range dataFieldsIndex { for idx, dataField := range dataFieldsIndex {
if pt.DataFields == nil {
pt.DataFields = &xlsxDataFields{}
}
pt.DataFields.DataField = append(pt.DataFields.DataField, &xlsxDataField{ pt.DataFields.DataField = append(pt.DataFields.DataField, &xlsxDataField{
Name: dataFieldsName[idx], Name: dataFieldsName[idx],
Fld: dataField, Fld: dataField,
@ -352,10 +377,9 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
} }
// count data fields // count data fields
pt.DataFields.Count = len(pt.DataFields.DataField) if pt.DataFields != nil {
pt.DataFields.Count = len(pt.DataFields.DataField)
pivotTable, err := xml.Marshal(pt) }
f.saveFileList(pivotTableXML, pivotTable)
return err return err
} }

@ -179,6 +179,46 @@ func TestAddPivotTable(t *testing.T) {
assert.EqualError(t, err, `parameter 'DataRange' parsing error: parameter is required`) 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) { func TestInStrSlice(t *testing.T) {
assert.EqualValues(t, -1, inStrSlice([]string{}, "")) assert.EqualValues(t, -1, inStrSlice([]string{}, ""))
} }

Loading…
Cancel
Save