Skip to content

Commit 97bffe6

Browse files
Extend pivot table funtionality (qax-os#692)
Add different pivot options Add header options to pivot table opts Add Style name options to pivot table opts
1 parent 01afc6e commit 97bffe6

File tree

3 files changed

+117
-37
lines changed

3 files changed

+117
-37
lines changed

pivotTable.go

+94-28
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,25 @@ import (
2121

2222
// PivotTableOption directly maps the format settings of the pivot table.
2323
type PivotTableOption struct {
24-
DataRange string
25-
PivotTableRange string
26-
Rows []PivotTableField
27-
Columns []PivotTableField
28-
Data []PivotTableField
29-
Filter []PivotTableField
24+
DataRange string
25+
PivotTableRange string
26+
Rows []PivotTableField
27+
Columns []PivotTableField
28+
Data []PivotTableField
29+
Filter []PivotTableField
30+
RowGrandTotals bool
31+
ColGrandTotals bool
32+
ShowDrill bool
33+
UseAutoFormatting bool
34+
PageOverThenDown bool
35+
MergeItem bool
36+
CompactData bool
37+
ShowRowHeaders bool
38+
ShowColHeaders bool
39+
ShowRowStripes bool
40+
ShowColStripes bool
41+
ShowLastColumn bool
42+
PivotTableStyleName string
3043
}
3144

3245
// PivotTableField directly maps the field settings of the pivot table.
@@ -49,9 +62,10 @@ type PivotTableOption struct {
4962
// Name specifies the name of the data field. Maximum 255 characters
5063
// are allowed in data field name, excess characters will be truncated.
5164
type PivotTableField struct {
52-
Data string
53-
Name string
54-
Subtotal string
65+
Data string
66+
Name string
67+
Subtotal string
68+
DefaultSubtotal bool
5569
}
5670

5771
// 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
233247
},
234248
CacheFields: &xlsxCacheFields{},
235249
}
250+
236251
for _, name := range order {
252+
defaultRowsSubtotal, rowOk := f.getPivotTableFieldNameDefaultSubtotal(name, opt.Rows)
253+
defaultColumnsSubtotal, colOk := f.getPivotTableFieldNameDefaultSubtotal(name, opt.Columns)
254+
sharedItems := xlsxSharedItems{
255+
Count: 0,
256+
}
257+
s := xlsxString{}
258+
if (rowOk && !defaultRowsSubtotal) || (colOk && !defaultColumnsSubtotal) {
259+
s = xlsxString{
260+
V: "",
261+
}
262+
sharedItems.Count++
263+
sharedItems.S = &s
264+
}
265+
237266
pc.CacheFields.CacheField = append(pc.CacheFields.CacheField, &xlsxCacheField{
238-
Name: name,
239-
SharedItems: &xlsxSharedItems{
240-
Count: 0,
241-
},
267+
Name: name,
268+
SharedItems: &sharedItems,
242269
})
243270
}
244271
pc.CacheFields.Count = len(pc.CacheFields.CacheField)
@@ -259,10 +286,24 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
259286
hcell, _ := CoordinatesToCellName(coordinates[0], coordinates[1])
260287
vcell, _ := CoordinatesToCellName(coordinates[2], coordinates[3])
261288

289+
pivotTableStyle := func() string {
290+
if opt.PivotTableStyleName == "" {
291+
return "PivotStyleLight16"
292+
} else {
293+
return opt.PivotTableStyleName
294+
}
295+
}
262296
pt := xlsxPivotTableDefinition{
263-
Name: fmt.Sprintf("Pivot Table%d", pivotTableID),
264-
CacheID: cacheID,
265-
DataCaption: "Values",
297+
Name: fmt.Sprintf("Pivot Table%d", pivotTableID),
298+
CacheID: cacheID,
299+
RowGrandTotals: &opt.RowGrandTotals,
300+
ColGrandTotals: &opt.ColGrandTotals,
301+
ShowDrill: &opt.ShowDrill,
302+
UseAutoFormatting: &opt.UseAutoFormatting,
303+
PageOverThenDown: &opt.PageOverThenDown,
304+
MergeItem: &opt.MergeItem,
305+
CompactData: &opt.CompactData,
306+
DataCaption: "Values",
266307
Location: &xlsxLocation{
267308
Ref: hcell + ":" + vcell,
268309
FirstDataCol: 1,
@@ -283,10 +324,12 @@ func (f *File) addPivotTable(cacheID, pivotTableID int, pivotTableXML string, op
283324
I: []*xlsxI{{}},
284325
},
285326
PivotTableStyleInfo: &xlsxPivotTableStyleInfo{
286-
Name: "PivotStyleLight16",
287-
ShowRowHeaders: true,
288-
ShowColHeaders: true,
289-
ShowLastColumn: true,
327+
Name: pivotTableStyle(),
328+
ShowRowHeaders: opt.ShowRowHeaders,
329+
ShowColHeaders: opt.ShowColHeaders,
330+
ShowRowStripes: opt.ShowRowStripes,
331+
ShowColStripes: opt.ShowColStripes,
332+
ShowLastColumn: opt.ShowLastColumn,
290333
},
291334
}
292335

@@ -440,17 +483,25 @@ func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opt *PivotTableOptio
440483
if err != nil {
441484
return err
442485
}
486+
x := 0
443487
for _, name := range order {
444488
if inPivotTableField(opt.Rows, name) != -1 {
489+
defaultSubtotal, ok := f.getPivotTableFieldNameDefaultSubtotal(name, opt.Rows)
490+
var items []*xlsxItem
491+
if !ok || !defaultSubtotal {
492+
items = append(items, &xlsxItem{X: &x})
493+
} else {
494+
items = append(items, &xlsxItem{T: "default"})
495+
}
496+
445497
pt.PivotFields.PivotField = append(pt.PivotFields.PivotField, &xlsxPivotField{
446498
Axis: "axisRow",
447499
Name: f.getPivotTableFieldName(name, opt.Rows),
448500
Items: &xlsxItems{
449-
Count: 1,
450-
Item: []*xlsxItem{
451-
{T: "default"},
452-
},
501+
Count: len(items),
502+
Item: items,
453503
},
504+
DefaultSubtotal: &defaultSubtotal,
454505
})
455506
continue
456507
}
@@ -468,15 +519,21 @@ func (f *File) addPivotFields(pt *xlsxPivotTableDefinition, opt *PivotTableOptio
468519
continue
469520
}
470521
if inPivotTableField(opt.Columns, name) != -1 {
522+
defaultSubtotal, ok := f.getPivotTableFieldNameDefaultSubtotal(name, opt.Columns)
523+
var items []*xlsxItem
524+
if !ok || !defaultSubtotal {
525+
items = append(items, &xlsxItem{X: &x})
526+
} else {
527+
items = append(items, &xlsxItem{T: "default"})
528+
}
471529
pt.PivotFields.PivotField = append(pt.PivotFields.PivotField, &xlsxPivotField{
472530
Axis: "axisCol",
473531
Name: f.getPivotTableFieldName(name, opt.Columns),
474532
Items: &xlsxItems{
475-
Count: 1,
476-
Item: []*xlsxItem{
477-
{T: "default"},
478-
},
533+
Count: len(items),
534+
Item: items,
479535
},
536+
DefaultSubtotal: &defaultSubtotal,
480537
})
481538
continue
482539
}
@@ -574,6 +631,15 @@ func (f *File) getPivotTableFieldName(name string, fields []PivotTableField) str
574631
return ""
575632
}
576633

634+
func (f *File) getPivotTableFieldNameDefaultSubtotal(name string, fields []PivotTableField) (bool, bool) {
635+
for _, field := range fields {
636+
if field.Data == name {
637+
return field.DefaultSubtotal, true
638+
}
639+
}
640+
return false, false
641+
}
642+
577643
// addWorkbookPivotCache add the association ID of the pivot cache in xl/workbook.xml.
578644
func (f *File) addWorkbookPivotCache(RID int) int {
579645
wb := f.workbookReader()

xmlPivotCache.go

+14
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,20 @@ type xlsxError struct {
182182

183183
// xlsxString represents a character value in a PivotTable.
184184
type xlsxString struct {
185+
V string `xml:"v,attr"`
186+
U bool `xml:"u,attr,omitempty"`
187+
F bool `xml:"f,attr,omitempty"`
188+
C string `xml:"c,attr,omitempty"`
189+
Cp int `xml:"cp,attr,omitempty"`
190+
In int `xml:"in,attr,omitempty"`
191+
Bc string `xml:"bc,attr,omitempty"`
192+
Fc string `xml:"fc,attr,omitempty"`
193+
I bool `xml:"i,attr,omitempty"`
194+
Un bool `xml:"un,attr,omitempty"`
195+
St bool `xml:"st,attr,omitempty"`
196+
B bool `xml:"b,attr,omitempty"`
197+
Tpls *xlsxTuples `xml:"tpls"`
198+
X *attrValInt `xml:"x"`
185199
}
186200

187201
// xlsxDateTime represents a date-time value in the PivotTable.

xmlPivotTable.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,23 @@ type xlsxPivotTableDefinition struct {
4848
VisualTotals bool `xml:"visualTotals,attr,omitempty"`
4949
ShowMultipleLabel bool `xml:"showMultipleLabel,attr,omitempty"`
5050
ShowDataDropDown bool `xml:"showDataDropDown,attr,omitempty"`
51-
ShowDrill bool `xml:"showDrill,attr,omitempty"`
51+
ShowDrill *bool `xml:"showDrill,attr,omitempty"`
5252
PrintDrill bool `xml:"printDrill,attr,omitempty"`
5353
ShowMemberPropertyTips bool `xml:"showMemberPropertyTips,attr,omitempty"`
5454
ShowDataTips bool `xml:"showDataTips,attr,omitempty"`
5555
EnableWizard bool `xml:"enableWizard,attr,omitempty"`
5656
EnableDrill bool `xml:"enableDrill,attr,omitempty"`
5757
EnableFieldProperties bool `xml:"enableFieldProperties,attr,omitempty"`
5858
PreserveFormatting bool `xml:"preserveFormatting,attr,omitempty"`
59-
UseAutoFormatting bool `xml:"useAutoFormatting,attr,omitempty"`
59+
UseAutoFormatting *bool `xml:"useAutoFormatting,attr,omitempty"`
6060
PageWrap int `xml:"pageWrap,attr,omitempty"`
61-
PageOverThenDown bool `xml:"pageOverThenDown,attr,omitempty"`
61+
PageOverThenDown *bool `xml:"pageOverThenDown,attr,omitempty"`
6262
SubtotalHiddenItems bool `xml:"subtotalHiddenItems,attr,omitempty"`
63-
RowGrandTotals bool `xml:"rowGrandTotals,attr,omitempty"`
64-
ColGrandTotals bool `xml:"colGrandTotals,attr,omitempty"`
63+
RowGrandTotals *bool `xml:"rowGrandTotals,attr,omitempty"`
64+
ColGrandTotals *bool `xml:"colGrandTotals,attr,omitempty"`
6565
FieldPrintTitles bool `xml:"fieldPrintTitles,attr,omitempty"`
6666
ItemPrintTitles bool `xml:"itemPrintTitles,attr,omitempty"`
67-
MergeItem bool `xml:"mergeItem,attr,omitempty"`
67+
MergeItem *bool `xml:"mergeItem,attr,omitempty"`
6868
ShowDropZones bool `xml:"showDropZones,attr,omitempty"`
6969
CreatedVersion int `xml:"createdVersion,attr,omitempty"`
7070
Indent int `xml:"indent,attr,omitempty"`
@@ -74,7 +74,7 @@ type xlsxPivotTableDefinition struct {
7474
Compact bool `xml:"compact,attr"`
7575
Outline bool `xml:"outline,attr"`
7676
OutlineData bool `xml:"outlineData,attr,omitempty"`
77-
CompactData bool `xml:"compactData,attr,omitempty"`
77+
CompactData *bool `xml:"compactData,attr,omitempty"`
7878
Published bool `xml:"published,attr,omitempty"`
7979
GridDropZones bool `xml:"gridDropZones,attr,omitempty"`
8080
Immersive bool `xml:"immersive,attr,omitempty"`
@@ -150,7 +150,7 @@ type xlsxPivotField struct {
150150
DataSourceSort bool `xml:"dataSourceSort,attr,omitempty"`
151151
NonAutoSortDefault bool `xml:"nonAutoSortDefault,attr,omitempty"`
152152
RankBy int `xml:"rankBy,attr,omitempty"`
153-
DefaultSubtotal bool `xml:"defaultSubtotal,attr,omitempty"`
153+
DefaultSubtotal *bool `xml:"defaultSubtotal,attr,omitempty"`
154154
SumSubtotal bool `xml:"sumSubtotal,attr,omitempty"`
155155
CountASubtotal bool `xml:"countASubtotal,attr,omitempty"`
156156
AvgSubtotal bool `xml:"avgSubtotal,attr,omitempty"`
@@ -189,7 +189,7 @@ type xlsxItem struct {
189189
F bool `xml:"f,attr,omitempty"`
190190
M bool `xml:"m,attr,omitempty"`
191191
C bool `xml:"c,attr,omitempty"`
192-
X int `xml:"x,attr,omitempty"`
192+
X *int `xml:"x,attr,omitempty"`
193193
D bool `xml:"d,attr,omitempty"`
194194
E bool `xml:"e,attr,omitempty"`
195195
}

0 commit comments

Comments
 (0)