Skip to content

Commit b1e776e

Browse files
committed
Support to set summary columns to appear to the right of detail in an outline
- Simplify calculation engine code - Update documentation for the functions - Update dependencies module
1 parent 5705132 commit b1e776e

11 files changed

+94
-75
lines changed

calc.go

+21-21
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,7 @@ func calcLe(rOpd, lOpd formulaArg, opdStack *Stack) error {
11321132
return nil
11331133
}
11341134

1135-
// calcG evaluate greater than or equal arithmetic operations.
1135+
// calcG evaluate greater than arithmetic operations.
11361136
func calcG(rOpd, lOpd formulaArg, opdStack *Stack) error {
11371137
if rOpd.Type == ArgNumber && lOpd.Type == ArgNumber {
11381138
opdStack.Push(newBoolFormulaArg(lOpd.Number > rOpd.Number))
@@ -1287,28 +1287,28 @@ func calculate(opdStack *Stack, opt efp.Token) error {
12871287
func (f *File) parseOperatorPrefixToken(optStack, opdStack *Stack, token efp.Token) (err error) {
12881288
if optStack.Len() == 0 {
12891289
optStack.Push(token)
1290-
} else {
1291-
tokenPriority := getPriority(token)
1292-
topOpt := optStack.Peek().(efp.Token)
1293-
topOptPriority := getPriority(topOpt)
1294-
if tokenPriority > topOptPriority {
1295-
optStack.Push(token)
1296-
} else {
1297-
for tokenPriority <= topOptPriority {
1298-
optStack.Pop()
1299-
if err = calculate(opdStack, topOpt); err != nil {
1300-
return
1301-
}
1302-
if optStack.Len() > 0 {
1303-
topOpt = optStack.Peek().(efp.Token)
1304-
topOptPriority = getPriority(topOpt)
1305-
continue
1306-
}
1307-
break
1308-
}
1309-
optStack.Push(token)
1290+
return
1291+
}
1292+
tokenPriority := getPriority(token)
1293+
topOpt := optStack.Peek().(efp.Token)
1294+
topOptPriority := getPriority(topOpt)
1295+
if tokenPriority > topOptPriority {
1296+
optStack.Push(token)
1297+
return
1298+
}
1299+
for tokenPriority <= topOptPriority {
1300+
optStack.Pop()
1301+
if err = calculate(opdStack, topOpt); err != nil {
1302+
return
1303+
}
1304+
if optStack.Len() > 0 {
1305+
topOpt = optStack.Peek().(efp.Token)
1306+
topOptPriority = getPriority(topOpt)
1307+
continue
13101308
}
1309+
break
13111310
}
1311+
optStack.Push(token)
13121312
return
13131313
}
13141314

excelize.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -444,9 +444,12 @@ func (f *File) UpdateLinkedValue() error {
444444
// AddVBAProject provides the method to add vbaProject.bin file which contains
445445
// functions and/or macros. The file extension should be .xlsm. For example:
446446
//
447-
// if err := f.SetSheetPrOptions("Sheet1", excelize.CodeName("Sheet1")); err != nil {
448-
// fmt.Println(err)
449-
// }
447+
// codeName := "Sheet1"
448+
// if err := f.SetSheetProps("Sheet1", &excelize.SheetPropsOptions{
449+
// CodeName: &codeName,
450+
// }); err != nil {
451+
// fmt.Println(err)
452+
// }
450453
// if err := f.AddVBAProject("vbaProject.bin"); err != nil {
451454
// fmt.Println(err)
452455
// }

go.mod

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ require (
1010
github.com/stretchr/testify v1.7.1
1111
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470
1212
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22
13-
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
13+
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b
1414
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9
15-
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b
15+
golang.org/x/net v0.0.0-20221004154528-8021a29435af
1616
golang.org/x/text v0.3.7
1717
gopkg.in/yaml.v3 v3.0.0 // indirect
1818
)

go.sum

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj0
1717
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
1818
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M=
1919
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
20-
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
21-
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
20+
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0=
21+
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
2222
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE=
2323
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
2424
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
25-
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
26-
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
25+
golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4=
26+
golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
2727
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
2828
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
2929
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

pivotTable.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ type PivotTableField struct {
109109
// f.SetCellValue("Sheet1", fmt.Sprintf("D%d", row), rand.Intn(5000))
110110
// f.SetCellValue("Sheet1", fmt.Sprintf("E%d", row), region[rand.Intn(4)])
111111
// }
112-
// if err := f.AddPivotTable(&excelize.PivotTableOption{
112+
// if err := f.AddPivotTable(&excelize.PivotTableOptions{
113113
// DataRange: "Sheet1!$A$1:$E$31",
114114
// PivotTableRange: "Sheet1!$G$2:$M$34",
115115
// Rows: []excelize.PivotTableField{{Data: "Month", DefaultSubtotal: true}, {Data: "Year"}},

sheet.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -1039,7 +1039,7 @@ func attrValToBool(name string, attrs []xml.Attr) (val bool, err error) {
10391039
//
10401040
// For example:
10411041
//
1042-
// err := f.SetHeaderFooter("Sheet1", &excelize.FormatHeaderFooter{
1042+
// err := f.SetHeaderFooter("Sheet1", &excelize.HeaderFooterOptions{
10431043
// DifferentFirst: true,
10441044
// DifferentOddEven: true,
10451045
// OddHeader: "&R&P",
@@ -1109,7 +1109,7 @@ func (f *File) SetHeaderFooter(sheet string, settings *HeaderFooterOptions) erro
11091109
// specified, will be using the XOR algorithm as default. For example, protect
11101110
// Sheet1 with protection settings:
11111111
//
1112-
// err := f.ProtectSheet("Sheet1", &excelize.FormatSheetProtection{
1112+
// err := f.ProtectSheet("Sheet1", &excelize.SheetProtectionOptions{
11131113
// AlgorithmName: "SHA-512",
11141114
// Password: "password",
11151115
// EditScenarios: false,

sheetpr.go

+33-21
Original file line numberDiff line numberDiff line change
@@ -106,41 +106,55 @@ func (f *File) GetPageMargins(sheet string) (PageLayoutMarginsOptions, error) {
106106
return opts, err
107107
}
108108

109-
// setSheetProps set worksheet format properties by given options.
110-
func (ws *xlsxWorksheet) setSheetProps(opts *SheetPropsOptions) {
111-
prepareSheetPr := func(ws *xlsxWorksheet) {
112-
if ws.SheetPr == nil {
113-
ws.SheetPr = new(xlsxSheetPr)
109+
// prepareSheetPr sheetPr element if which not exist.
110+
func (ws *xlsxWorksheet) prepareSheetPr() {
111+
if ws.SheetPr == nil {
112+
ws.SheetPr = new(xlsxSheetPr)
113+
}
114+
}
115+
116+
// setSheetOutlinePr set worksheet outline properties by given options.
117+
func (ws *xlsxWorksheet) setSheetOutlineProps(opts *SheetPropsOptions) {
118+
prepareOutlinePr := func(ws *xlsxWorksheet) {
119+
ws.prepareSheetPr()
120+
if ws.SheetPr.OutlinePr == nil {
121+
ws.SheetPr.OutlinePr = new(xlsxOutlinePr)
114122
}
115123
}
124+
if opts.OutlineSummaryBelow != nil {
125+
prepareOutlinePr(ws)
126+
ws.SheetPr.OutlinePr.SummaryBelow = opts.OutlineSummaryBelow
127+
}
128+
if opts.OutlineSummaryRight != nil {
129+
prepareOutlinePr(ws)
130+
ws.SheetPr.OutlinePr.SummaryRight = opts.OutlineSummaryRight
131+
}
132+
}
133+
134+
// setSheetProps set worksheet format properties by given options.
135+
func (ws *xlsxWorksheet) setSheetProps(opts *SheetPropsOptions) {
116136
preparePageSetUpPr := func(ws *xlsxWorksheet) {
117-
prepareSheetPr(ws)
137+
ws.prepareSheetPr()
118138
if ws.SheetPr.PageSetUpPr == nil {
119139
ws.SheetPr.PageSetUpPr = new(xlsxPageSetUpPr)
120140
}
121141
}
122-
prepareOutlinePr := func(ws *xlsxWorksheet) {
123-
prepareSheetPr(ws)
124-
if ws.SheetPr.OutlinePr == nil {
125-
ws.SheetPr.OutlinePr = new(xlsxOutlinePr)
126-
}
127-
}
128142
prepareTabColor := func(ws *xlsxWorksheet) {
129-
prepareSheetPr(ws)
143+
ws.prepareSheetPr()
130144
if ws.SheetPr.TabColor == nil {
131145
ws.SheetPr.TabColor = new(xlsxTabColor)
132146
}
133147
}
134148
if opts.CodeName != nil {
135-
prepareSheetPr(ws)
149+
ws.prepareSheetPr()
136150
ws.SheetPr.CodeName = *opts.CodeName
137151
}
138152
if opts.EnableFormatConditionsCalculation != nil {
139-
prepareSheetPr(ws)
153+
ws.prepareSheetPr()
140154
ws.SheetPr.EnableFormatConditionsCalculation = opts.EnableFormatConditionsCalculation
141155
}
142156
if opts.Published != nil {
143-
prepareSheetPr(ws)
157+
ws.prepareSheetPr()
144158
ws.SheetPr.Published = opts.Published
145159
}
146160
if opts.AutoPageBreaks != nil {
@@ -151,10 +165,7 @@ func (ws *xlsxWorksheet) setSheetProps(opts *SheetPropsOptions) {
151165
preparePageSetUpPr(ws)
152166
ws.SheetPr.PageSetUpPr.FitToPage = *opts.FitToPage
153167
}
154-
if opts.OutlineSummaryBelow != nil {
155-
prepareOutlinePr(ws)
156-
ws.SheetPr.OutlinePr.SummaryBelow = *opts.OutlineSummaryBelow
157-
}
168+
ws.setSheetOutlineProps(opts)
158169
if opts.TabColorIndexed != nil {
159170
prepareTabColor(ws)
160171
ws.SheetPr.TabColor.Indexed = *opts.TabColorIndexed
@@ -237,7 +248,8 @@ func (f *File) GetSheetProps(sheet string) (SheetPropsOptions, error) {
237248
opts.FitToPage = boolPtr(ws.SheetPr.PageSetUpPr.FitToPage)
238249
}
239250
if ws.SheetPr.OutlinePr != nil {
240-
opts.OutlineSummaryBelow = boolPtr(ws.SheetPr.OutlinePr.SummaryBelow)
251+
opts.OutlineSummaryBelow = ws.SheetPr.OutlinePr.SummaryBelow
252+
opts.OutlineSummaryRight = ws.SheetPr.OutlinePr.SummaryRight
241253
}
242254
if ws.SheetPr.TabColor != nil {
243255
opts.TabColorIndexed = intPtr(ws.SheetPr.TabColor.Indexed)

sheetpr_test.go

+12-11
Original file line numberDiff line numberDiff line change
@@ -61,33 +61,34 @@ func TestSetSheetProps(t *testing.T) {
6161
assert.True(t, ok)
6262
ws.(*xlsxWorksheet).SheetPr = nil
6363
ws.(*xlsxWorksheet).SheetFormatPr = nil
64-
baseColWidth := uint8(8)
64+
baseColWidth, enable := uint8(8), boolPtr(true)
6565
expected := SheetPropsOptions{
6666
CodeName: stringPtr("code"),
67-
EnableFormatConditionsCalculation: boolPtr(true),
68-
Published: boolPtr(true),
69-
AutoPageBreaks: boolPtr(true),
70-
FitToPage: boolPtr(true),
67+
EnableFormatConditionsCalculation: enable,
68+
Published: enable,
69+
AutoPageBreaks: enable,
70+
FitToPage: enable,
7171
TabColorIndexed: intPtr(1),
7272
TabColorRGB: stringPtr("#FFFF00"),
7373
TabColorTheme: intPtr(1),
7474
TabColorTint: float64Ptr(1),
75-
OutlineSummaryBelow: boolPtr(true),
75+
OutlineSummaryBelow: enable,
76+
OutlineSummaryRight: enable,
7677
BaseColWidth: &baseColWidth,
7778
DefaultColWidth: float64Ptr(10),
7879
DefaultRowHeight: float64Ptr(10),
79-
CustomHeight: boolPtr(true),
80-
ZeroHeight: boolPtr(true),
81-
ThickTop: boolPtr(true),
82-
ThickBottom: boolPtr(true),
80+
CustomHeight: enable,
81+
ZeroHeight: enable,
82+
ThickTop: enable,
83+
ThickBottom: enable,
8384
}
8485
assert.NoError(t, f.SetSheetProps("Sheet1", &expected))
8586
opts, err := f.GetSheetProps("Sheet1")
8687
assert.NoError(t, err)
8788
assert.Equal(t, expected, opts)
8889

8990
ws.(*xlsxWorksheet).SheetPr = nil
90-
assert.NoError(t, f.SetSheetProps("Sheet1", &SheetPropsOptions{FitToPage: boolPtr(true)}))
91+
assert.NoError(t, f.SetSheetProps("Sheet1", &SheetPropsOptions{FitToPage: enable}))
9192
ws.(*xlsxWorksheet).SheetPr = nil
9293
assert.NoError(t, f.SetSheetProps("Sheet1", &SheetPropsOptions{TabColorRGB: stringPtr("#FFFF00")}))
9394
ws.(*xlsxWorksheet).SheetPr = nil

sparkline.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ func (f *File) addSparklineGroupByStyle(ID int) *xlsxX14SparklineGroup {
365365
// Excel 2007, but they won't be displayed. For example, add a grouped
366366
// sparkline. Changes are applied to all three:
367367
//
368-
// err := f.AddSparkline("Sheet1", &excelize.SparklineOption{
368+
// err := f.AddSparkline("Sheet1", &excelize.SparklineOptions{
369369
// Location: []string{"A1", "A2", "A3"},
370370
// Range: []string{"Sheet2!A1:J1", "Sheet2!A2:J2", "Sheet2!A3:J3"},
371371
// Markers: true,

stream.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ type StreamWriter struct {
4040

4141
// NewStreamWriter return stream writer struct by given worksheet name for
4242
// generate new worksheet with large amounts of data. Note that after set
43-
// rows, you must call the 'Flush' method to end the streaming writing
44-
// process and ensure that the order of line numbers is ascending, the common
45-
// API and stream API can't be work mixed to writing data on the worksheets,
46-
// you can't get cell value when in-memory chunks data over 16MB. For
47-
// example, set data for worksheet of size 102400 rows x 50 columns with
48-
// numbers and style:
43+
// rows, you must call the 'Flush' method to end the streaming writing process
44+
// and ensure that the order of line numbers is ascending, the normal mode
45+
// functions and stream mode functions can't be work mixed to writing data on
46+
// the worksheets, you can't get cell value when in-memory chunks data over
47+
// 16MB. For example, set data for worksheet of size 102400 rows x 50 columns
48+
// with numbers and style:
4949
//
5050
// file := excelize.NewFile()
5151
// streamWriter, err := file.NewStreamWriter("Sheet1")

xmlWorksheet.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,9 @@ type xlsxSheetPr struct {
250250
// adjust the direction of grouper controls.
251251
type xlsxOutlinePr struct {
252252
ApplyStyles *bool `xml:"applyStyles,attr"`
253-
SummaryBelow bool `xml:"summaryBelow,attr"`
254-
SummaryRight bool `xml:"summaryRight,attr"`
255-
ShowOutlineSymbols bool `xml:"showOutlineSymbols,attr"`
253+
SummaryBelow *bool `xml:"summaryBelow,attr"`
254+
SummaryRight *bool `xml:"summaryRight,attr"`
255+
ShowOutlineSymbols *bool `xml:"showOutlineSymbols,attr"`
256256
}
257257

258258
// xlsxPageSetUpPr expresses page setup properties of the worksheet.
@@ -989,6 +989,9 @@ type SheetPropsOptions struct {
989989
// OutlineSummaryBelow indicating whether summary rows appear below detail
990990
// in an outline, when applying an outline.
991991
OutlineSummaryBelow *bool `json:"outline_summary_below,omitempty"`
992+
// OutlineSummaryRight indicating whether summary columns appear to the
993+
// right of detail in an outline, when applying an outline.
994+
OutlineSummaryRight *bool `json:"outline_summary_right,omitempty"`
992995
// BaseColWidth specifies the number of characters of the maximum digit
993996
// width of the normal style's font. This value does not include margin
994997
// padding or extra padding for grid lines. It is only the number of

0 commit comments

Comments
 (0)