Extend pivot table funtionality (#692)

Add different pivot options
Add header options to pivot table opts
Add Style name options to pivot table opts
formula
Eugene Androsov 4 years ago committed by GitHub
parent 01afc6e03f
commit 97bffe608d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -21,12 +21,25 @@ import (
// PivotTableOption directly maps the format settings of the pivot table. // PivotTableOption directly maps the format settings of the pivot table.
type PivotTableOption struct { type PivotTableOption struct {
DataRange string DataRange string
PivotTableRange string PivotTableRange string
Rows []PivotTableField Rows []PivotTableField
Columns []PivotTableField Columns []PivotTableField
Data []PivotTableField Data []PivotTableField
Filter []PivotTableField Filter []PivotTableField
RowGrandTotals bool
ColGrandTotals bool
ShowDrill bool
UseAutoFormatting bool
PageOverThenDown bool
MergeItem bool
CompactData bool
ShowRowHeaders bool
ShowColHeaders bool
ShowRowStripes bool
ShowColStripes bool
ShowLastColumn bool
PivotTableStyleName string
} }
// PivotTableField directly maps the field settings of the pivot table. // PivotTableField directly maps the field settings of the pivot table.
@ -49,9 +62,10 @@ type PivotTableOption struct {
// Name specifies the name of the data field. Maximum 255 characters // Name specifies the name of the data field. Maximum 255 characters
// are allowed in data field name, excess characters will be truncated. // are allowed in data field name, excess characters will be truncated.
type PivotTableField struct { type PivotTableField struct {
Data string Data string
Name string Name string
Subtotal string Subtotal string
DefaultSubtotal bool
} }
// AddPivotTable provides the method to add pivot table by given pivot table // AddPivotTable provides the method to add pivot table by given pivot table
@ -233,12 +247,25 @@ func (f *File) addPivotCache(pivotCacheID int, pivotCacheXML string, opt *PivotT
}, },
CacheFields: &xlsxCacheFields{}, CacheFields: &xlsxCacheFields{},
} }
for _, name := range order { for _, name := range order {
defaultRowsSubtotal, rowOk := f.getPivotTableFieldNameDefaultSubtotal(name, opt.Rows)
defaultColumnsSubtotal, colOk := f.getPivotTableFieldNameDefaultSubtotal(name, opt.Columns)
sharedItems := xlsxSharedItems{
Count: 0,
}
s := xlsxString{}
if (rowOk && !defaultRowsSubtotal) || (colOk && !defaultColumnsSubtotal) {
s = xlsxString{
V: "",
}
sharedItems.Count++
sharedItems.S = &s
}
pc.CacheFields.CacheField = append(pc.CacheFields.CacheField, &xlsxCacheField{ pc.CacheFields.CacheField = append(pc.CacheFields.CacheField, &xlsxCacheField{
Name: name, Name: name,
SharedItems: &xlsxSharedItems{ SharedItems: &sharedItems,
Count: 0,
},
}) })
} }
pc.CacheFields.Count = len(pc.CacheFields.CacheField) pc.CacheFields.Count = len(pc.CacheFields.CacheField)
@ -259,10 +286,24 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
hcell, _ := CoordinatesToCellName(coordinates[0], coordinates[1]) hcell, _ := CoordinatesToCellName(coordinates[0], coordinates[1])
vcell, _ := CoordinatesToCellName(coordinates[2], coordinates[3]) vcell, _ := CoordinatesToCellName(coordinates[2], coordinates[3])
pivotTableStyle := func() string {
if opt.PivotTableStyleName == "" {
return "PivotStyleLight16"
} else {
return opt.PivotTableStyleName
}
}
pt := xlsxPivotTableDefinition{ pt := xlsxPivotTableDefinition{
Name: fmt.Sprintf("Pivot Table%d", pivotTableID), Name: fmt.Sprintf("Pivot Table%d", pivotTableID),
CacheID: cacheID, CacheID: cacheID,
DataCaption: "Values", RowGrandTotals: &opt.RowGrandTotals,
ColGrandTotals: &opt.ColGrandTotals,
ShowDrill: &opt.ShowDrill,
UseAutoFormatting: &opt.UseAutoFormatting,
PageOverThenDown: &opt.PageOverThenDown,
MergeItem: &opt.MergeItem,
CompactData: &opt.CompactData,
DataCaption: "Values",
Location: &xlsxLocation{ Location: &xlsxLocation{
Ref: hcell + ":" + vcell, Ref: hcell + ":" + vcell,
FirstDataCol: 1, FirstDataCol: 1,
@ -283,10 +324,12 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
I: []*xlsxI{{}}, I: []*xlsxI{{}},
}, },
PivotTableStyleInfo: &xlsxPivotTableStyleInfo{ PivotTableStyleInfo: &xlsxPivotTableStyleInfo{
Name: "PivotStyleLight16", Name: pivotTableStyle(),
ShowRowHeaders: true, ShowRowHeaders: opt.ShowRowHeaders,
ShowColHeaders: true, ShowColHeaders: opt.ShowColHeaders,
ShowLastColumn: true, ShowRowStripes: opt.ShowRowStripes,
ShowColStripes: opt.ShowColStripes,
ShowLastColumn: opt.ShowLastColumn,
}, },
} }
@ -440,17 +483,25 @@ func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opt *PivotTableOptio
if err != nil { if err != nil {
return err return err
} }
x := 0
for _, name := range order { for _, name := range order {
if inPivotTableField(opt.Rows, name) != -1 { if inPivotTableField(opt.Rows, name) != -1 {
defaultSubtotal, ok := f.getPivotTableFieldNameDefaultSubtotal(name, opt.Rows)
var items []*xlsxItem
if !ok || !defaultSubtotal {
items = append(items, &xlsxItem{X: &x})
} else {
items = append(items, &xlsxItem{T: "default"})
}
pt.PivotFields.PivotField = append(pt.PivotFields.PivotField, &xlsxPivotField{ pt.PivotFields.PivotField = append(pt.PivotFields.PivotField, &xlsxPivotField{
Axis: "axisRow", Axis: "axisRow",
Name: f.getPivotTableFieldName(name, opt.Rows), Name: f.getPivotTableFieldName(name, opt.Rows),
Items: &xlsxItems{ Items: &xlsxItems{
Count: 1, Count: len(items),
Item: []*xlsxItem{ Item: items,
{T: "default"},
},
}, },
DefaultSubtotal: &defaultSubtotal,
}) })
continue continue
} }
@ -468,15 +519,21 @@ func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opt *PivotTableOptio
continue continue
} }
if inPivotTableField(opt.Columns, name) != -1 { if inPivotTableField(opt.Columns, name) != -1 {
defaultSubtotal, ok := f.getPivotTableFieldNameDefaultSubtotal(name, opt.Columns)
var items []*xlsxItem
if !ok || !defaultSubtotal {
items = append(items, &xlsxItem{X: &x})
} else {
items = append(items, &xlsxItem{T: "default"})
}
pt.PivotFields.PivotField = append(pt.PivotFields.PivotField, &xlsxPivotField{ pt.PivotFields.PivotField = append(pt.PivotFields.PivotField, &xlsxPivotField{
Axis: "axisCol", Axis: "axisCol",
Name: f.getPivotTableFieldName(name, opt.Columns), Name: f.getPivotTableFieldName(name, opt.Columns),
Items: &xlsxItems{ Items: &xlsxItems{
Count: 1, Count: len(items),
Item: []*xlsxItem{ Item: items,
{T: "default"},
},
}, },
DefaultSubtotal: &defaultSubtotal,
}) })
continue continue
} }
@ -574,6 +631,15 @@ func (f *File) getPivotTableFieldName(name string, fields []PivotTableField) str
return "" return ""
} }
func (f *File) getPivotTableFieldNameDefaultSubtotal(name string, fields []PivotTableField) (bool, bool) {
for _, field := range fields {
if field.Data == name {
return field.DefaultSubtotal, true
}
}
return false, false
}
// addWorkbookPivotCache add the association ID of the pivot cache in xl/workbook.xml. // addWorkbookPivotCache add the association ID of the pivot cache in xl/workbook.xml.
func (f *File) addWorkbookPivotCache(RID int) int { func (f *File) addWorkbookPivotCache(RID int) int {
wb := f.workbookReader() wb := f.workbookReader()

@ -182,6 +182,20 @@ type xlsxError struct {
// xlsxString represents a character value in a PivotTable. // xlsxString represents a character value in a PivotTable.
type xlsxString struct { type xlsxString struct {
V string `xml:"v,attr"`
U bool `xml:"u,attr,omitempty"`
F bool `xml:"f,attr,omitempty"`
C string `xml:"c,attr,omitempty"`
Cp int `xml:"cp,attr,omitempty"`
In int `xml:"in,attr,omitempty"`
Bc string `xml:"bc,attr,omitempty"`
Fc string `xml:"fc,attr,omitempty"`
I bool `xml:"i,attr,omitempty"`
Un bool `xml:"un,attr,omitempty"`
St bool `xml:"st,attr,omitempty"`
B bool `xml:"b,attr,omitempty"`
Tpls *xlsxTuples `xml:"tpls"`
X *attrValInt `xml:"x"`
} }
// xlsxDateTime represents a date-time value in the PivotTable. // xlsxDateTime represents a date-time value in the PivotTable.

@ -48,7 +48,7 @@ type xlsxPivotTableDefinition struct {
VisualTotals bool `xml:"visualTotals,attr,omitempty"` VisualTotals bool `xml:"visualTotals,attr,omitempty"`
ShowMultipleLabel bool `xml:"showMultipleLabel,attr,omitempty"` ShowMultipleLabel bool `xml:"showMultipleLabel,attr,omitempty"`
ShowDataDropDown bool `xml:"showDataDropDown,attr,omitempty"` ShowDataDropDown bool `xml:"showDataDropDown,attr,omitempty"`
ShowDrill bool `xml:"showDrill,attr,omitempty"` ShowDrill *bool `xml:"showDrill,attr,omitempty"`
PrintDrill bool `xml:"printDrill,attr,omitempty"` PrintDrill bool `xml:"printDrill,attr,omitempty"`
ShowMemberPropertyTips bool `xml:"showMemberPropertyTips,attr,omitempty"` ShowMemberPropertyTips bool `xml:"showMemberPropertyTips,attr,omitempty"`
ShowDataTips bool `xml:"showDataTips,attr,omitempty"` ShowDataTips bool `xml:"showDataTips,attr,omitempty"`
@ -56,15 +56,15 @@ type xlsxPivotTableDefinition struct {
EnableDrill bool `xml:"enableDrill,attr,omitempty"` EnableDrill bool `xml:"enableDrill,attr,omitempty"`
EnableFieldProperties bool `xml:"enableFieldProperties,attr,omitempty"` EnableFieldProperties bool `xml:"enableFieldProperties,attr,omitempty"`
PreserveFormatting bool `xml:"preserveFormatting,attr,omitempty"` PreserveFormatting bool `xml:"preserveFormatting,attr,omitempty"`
UseAutoFormatting bool `xml:"useAutoFormatting,attr,omitempty"` UseAutoFormatting *bool `xml:"useAutoFormatting,attr,omitempty"`
PageWrap int `xml:"pageWrap,attr,omitempty"` PageWrap int `xml:"pageWrap,attr,omitempty"`
PageOverThenDown bool `xml:"pageOverThenDown,attr,omitempty"` PageOverThenDown *bool `xml:"pageOverThenDown,attr,omitempty"`
SubtotalHiddenItems bool `xml:"subtotalHiddenItems,attr,omitempty"` SubtotalHiddenItems bool `xml:"subtotalHiddenItems,attr,omitempty"`
RowGrandTotals bool `xml:"rowGrandTotals,attr,omitempty"` RowGrandTotals *bool `xml:"rowGrandTotals,attr,omitempty"`
ColGrandTotals bool `xml:"colGrandTotals,attr,omitempty"` ColGrandTotals *bool `xml:"colGrandTotals,attr,omitempty"`
FieldPrintTitles bool `xml:"fieldPrintTitles,attr,omitempty"` FieldPrintTitles bool `xml:"fieldPrintTitles,attr,omitempty"`
ItemPrintTitles bool `xml:"itemPrintTitles,attr,omitempty"` ItemPrintTitles bool `xml:"itemPrintTitles,attr,omitempty"`
MergeItem bool `xml:"mergeItem,attr,omitempty"` MergeItem *bool `xml:"mergeItem,attr,omitempty"`
ShowDropZones bool `xml:"showDropZones,attr,omitempty"` ShowDropZones bool `xml:"showDropZones,attr,omitempty"`
CreatedVersion int `xml:"createdVersion,attr,omitempty"` CreatedVersion int `xml:"createdVersion,attr,omitempty"`
Indent int `xml:"indent,attr,omitempty"` Indent int `xml:"indent,attr,omitempty"`
@ -74,7 +74,7 @@ type xlsxPivotTableDefinition struct {
Compact bool `xml:"compact,attr"` Compact bool `xml:"compact,attr"`
Outline bool `xml:"outline,attr"` Outline bool `xml:"outline,attr"`
OutlineData bool `xml:"outlineData,attr,omitempty"` OutlineData bool `xml:"outlineData,attr,omitempty"`
CompactData bool `xml:"compactData,attr,omitempty"` CompactData *bool `xml:"compactData,attr,omitempty"`
Published bool `xml:"published,attr,omitempty"` Published bool `xml:"published,attr,omitempty"`
GridDropZones bool `xml:"gridDropZones,attr,omitempty"` GridDropZones bool `xml:"gridDropZones,attr,omitempty"`
Immersive bool `xml:"immersive,attr,omitempty"` Immersive bool `xml:"immersive,attr,omitempty"`
@ -150,7 +150,7 @@ type xlsxPivotField struct {
DataSourceSort bool `xml:"dataSourceSort,attr,omitempty"` DataSourceSort bool `xml:"dataSourceSort,attr,omitempty"`
NonAutoSortDefault bool `xml:"nonAutoSortDefault,attr,omitempty"` NonAutoSortDefault bool `xml:"nonAutoSortDefault,attr,omitempty"`
RankBy int `xml:"rankBy,attr,omitempty"` RankBy int `xml:"rankBy,attr,omitempty"`
DefaultSubtotal bool `xml:"defaultSubtotal,attr,omitempty"` DefaultSubtotal *bool `xml:"defaultSubtotal,attr,omitempty"`
SumSubtotal bool `xml:"sumSubtotal,attr,omitempty"` SumSubtotal bool `xml:"sumSubtotal,attr,omitempty"`
CountASubtotal bool `xml:"countASubtotal,attr,omitempty"` CountASubtotal bool `xml:"countASubtotal,attr,omitempty"`
AvgSubtotal bool `xml:"avgSubtotal,attr,omitempty"` AvgSubtotal bool `xml:"avgSubtotal,attr,omitempty"`
@ -189,7 +189,7 @@ type xlsxItem struct {
F bool `xml:"f,attr,omitempty"` F bool `xml:"f,attr,omitempty"`
M bool `xml:"m,attr,omitempty"` M bool `xml:"m,attr,omitempty"`
C bool `xml:"c,attr,omitempty"` C bool `xml:"c,attr,omitempty"`
X int `xml:"x,attr,omitempty"` X *int `xml:"x,attr,omitempty"`
D bool `xml:"d,attr,omitempty"` D bool `xml:"d,attr,omitempty"`
E bool `xml:"e,attr,omitempty"` E bool `xml:"e,attr,omitempty"`
} }

Loading…
Cancel
Save