summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2022-10-08 22:08:06 +0800
committerxuri <xuri.me@gmail.com>2022-10-08 22:08:16 +0800
commitb1e776ee33ec78b7f6c2a0de8109009963dea521 (patch)
tree2a769b090171be17d3d1d6dacb7cc987f34d28ad
parent57051326d06cea02774dc0ace3293906ec5f281e (diff)
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
-rw-r--r--calc.go42
-rw-r--r--excelize.go9
-rw-r--r--go.mod4
-rw-r--r--go.sum8
-rw-r--r--pivotTable.go2
-rw-r--r--sheet.go4
-rw-r--r--sheetpr.go54
-rw-r--r--sheetpr_test.go23
-rw-r--r--sparkline.go2
-rw-r--r--stream.go12
-rw-r--r--xmlWorksheet.go9
11 files changed, 94 insertions, 75 deletions
diff --git a/calc.go b/calc.go
index b19dba7..5d55992 100644
--- a/calc.go
+++ b/calc.go
@@ -1132,7 +1132,7 @@ func calcLe(rOpd, lOpd formulaArg, opdStack *Stack) error {
return nil
}
-// calcG evaluate greater than or equal arithmetic operations.
+// calcG evaluate greater than arithmetic operations.
func calcG(rOpd, lOpd formulaArg, opdStack *Stack) error {
if rOpd.Type == ArgNumber && lOpd.Type == ArgNumber {
opdStack.Push(newBoolFormulaArg(lOpd.Number > rOpd.Number))
@@ -1287,28 +1287,28 @@ func calculate(opdStack *Stack, opt efp.Token) error {
func (f *File) parseOperatorPrefixToken(optStack, opdStack *Stack, token efp.Token) (err error) {
if optStack.Len() == 0 {
optStack.Push(token)
- } else {
- tokenPriority := getPriority(token)
- topOpt := optStack.Peek().(efp.Token)
- topOptPriority := getPriority(topOpt)
- if tokenPriority > topOptPriority {
- optStack.Push(token)
- } else {
- for tokenPriority <= topOptPriority {
- optStack.Pop()
- if err = calculate(opdStack, topOpt); err != nil {
- return
- }
- if optStack.Len() > 0 {
- topOpt = optStack.Peek().(efp.Token)
- topOptPriority = getPriority(topOpt)
- continue
- }
- break
- }
- optStack.Push(token)
+ return
+ }
+ tokenPriority := getPriority(token)
+ topOpt := optStack.Peek().(efp.Token)
+ topOptPriority := getPriority(topOpt)
+ if tokenPriority > topOptPriority {
+ optStack.Push(token)
+ return
+ }
+ for tokenPriority <= topOptPriority {
+ optStack.Pop()
+ if err = calculate(opdStack, topOpt); err != nil {
+ return
+ }
+ if optStack.Len() > 0 {
+ topOpt = optStack.Peek().(efp.Token)
+ topOptPriority = getPriority(topOpt)
+ continue
}
+ break
}
+ optStack.Push(token)
return
}
diff --git a/excelize.go b/excelize.go
index fd6a463..ec7485b 100644
--- a/excelize.go
+++ b/excelize.go
@@ -444,9 +444,12 @@ func (f *File) UpdateLinkedValue() error {
// AddVBAProject provides the method to add vbaProject.bin file which contains
// functions and/or macros. The file extension should be .xlsm. For example:
//
-// if err := f.SetSheetPrOptions("Sheet1", excelize.CodeName("Sheet1")); err != nil {
-// fmt.Println(err)
-// }
+// codeName := "Sheet1"
+// if err := f.SetSheetProps("Sheet1", &excelize.SheetPropsOptions{
+// CodeName: &codeName,
+// }); err != nil {
+// fmt.Println(err)
+// }
// if err := f.AddVBAProject("vbaProject.bin"); err != nil {
// fmt.Println(err)
// }
diff --git a/go.mod b/go.mod
index 9d49dbe..1ce8df3 100644
--- a/go.mod
+++ b/go.mod
@@ -10,9 +10,9 @@ require (
github.com/stretchr/testify v1.7.1
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22
- golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
+ golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9
- golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b
+ golang.org/x/net v0.0.0-20221004154528-8021a29435af
golang.org/x/text v0.3.7
gopkg.in/yaml.v3 v3.0.0 // indirect
)
diff --git a/go.sum b/go.sum
index 3f9cd78..b30b6c1 100644
--- a/go.sum
+++ b/go.sum
@@ -17,13 +17,13 @@ github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj0
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M=
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
-golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
-golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0=
+golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE=
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
-golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
+golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4=
+golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
diff --git a/pivotTable.go b/pivotTable.go
index 8266c8e..0999a97 100644
--- a/pivotTable.go
+++ b/pivotTable.go
@@ -109,7 +109,7 @@ type PivotTableField struct {
// f.SetCellValue("Sheet1", fmt.Sprintf("D%d", row), rand.Intn(5000))
// f.SetCellValue("Sheet1", fmt.Sprintf("E%d", row), region[rand.Intn(4)])
// }
-// if err := f.AddPivotTable(&excelize.PivotTableOption{
+// if err := f.AddPivotTable(&excelize.PivotTableOptions{
// DataRange: "Sheet1!$A$1:$E$31",
// PivotTableRange: "Sheet1!$G$2:$M$34",
// Rows: []excelize.PivotTableField{{Data: "Month", DefaultSubtotal: true}, {Data: "Year"}},
diff --git a/sheet.go b/sheet.go
index 6ec9aef..a737a9a 100644
--- a/sheet.go
+++ b/sheet.go
@@ -1039,7 +1039,7 @@ func attrValToBool(name string, attrs []xml.Attr) (val bool, err error) {
//
// For example:
//
-// err := f.SetHeaderFooter("Sheet1", &excelize.FormatHeaderFooter{
+// err := f.SetHeaderFooter("Sheet1", &excelize.HeaderFooterOptions{
// DifferentFirst: true,
// DifferentOddEven: true,
// OddHeader: "&R&P",
@@ -1109,7 +1109,7 @@ func (f *File) SetHeaderFooter(sheet string, settings *HeaderFooterOptions) erro
// specified, will be using the XOR algorithm as default. For example, protect
// Sheet1 with protection settings:
//
-// err := f.ProtectSheet("Sheet1", &excelize.FormatSheetProtection{
+// err := f.ProtectSheet("Sheet1", &excelize.SheetProtectionOptions{
// AlgorithmName: "SHA-512",
// Password: "password",
// EditScenarios: false,
diff --git a/sheetpr.go b/sheetpr.go
index a246e9e..3a805c4 100644
--- a/sheetpr.go
+++ b/sheetpr.go
@@ -106,41 +106,55 @@ func (f *File) GetPageMargins(sheet string) (PageLayoutMarginsOptions, error) {
return opts, err
}
-// setSheetProps set worksheet format properties by given options.
-func (ws *xlsxWorksheet) setSheetProps(opts *SheetPropsOptions) {
- prepareSheetPr := func(ws *xlsxWorksheet) {
- if ws.SheetPr == nil {
- ws.SheetPr = new(xlsxSheetPr)
+// prepareSheetPr sheetPr element if which not exist.
+func (ws *xlsxWorksheet) prepareSheetPr() {
+ if ws.SheetPr == nil {
+ ws.SheetPr = new(xlsxSheetPr)
+ }
+}
+
+// setSheetOutlinePr set worksheet outline properties by given options.
+func (ws *xlsxWorksheet) setSheetOutlineProps(opts *SheetPropsOptions) {
+ prepareOutlinePr := func(ws *xlsxWorksheet) {
+ ws.prepareSheetPr()
+ if ws.SheetPr.OutlinePr == nil {
+ ws.SheetPr.OutlinePr = new(xlsxOutlinePr)
}
}
+ if opts.OutlineSummaryBelow != nil {
+ prepareOutlinePr(ws)
+ ws.SheetPr.OutlinePr.SummaryBelow = opts.OutlineSummaryBelow
+ }
+ if opts.OutlineSummaryRight != nil {
+ prepareOutlinePr(ws)
+ ws.SheetPr.OutlinePr.SummaryRight = opts.OutlineSummaryRight
+ }
+}
+
+// setSheetProps set worksheet format properties by given options.
+func (ws *xlsxWorksheet) setSheetProps(opts *SheetPropsOptions) {
preparePageSetUpPr := func(ws *xlsxWorksheet) {
- prepareSheetPr(ws)
+ ws.prepareSheetPr()
if ws.SheetPr.PageSetUpPr == nil {
ws.SheetPr.PageSetUpPr = new(xlsxPageSetUpPr)
}
}
- prepareOutlinePr := func(ws *xlsxWorksheet) {
- prepareSheetPr(ws)
- if ws.SheetPr.OutlinePr == nil {
- ws.SheetPr.OutlinePr = new(xlsxOutlinePr)
- }
- }
prepareTabColor := func(ws *xlsxWorksheet) {
- prepareSheetPr(ws)
+ ws.prepareSheetPr()
if ws.SheetPr.TabColor == nil {
ws.SheetPr.TabColor = new(xlsxTabColor)
}
}
if opts.CodeName != nil {
- prepareSheetPr(ws)
+ ws.prepareSheetPr()
ws.SheetPr.CodeName = *opts.CodeName
}
if opts.EnableFormatConditionsCalculation != nil {
- prepareSheetPr(ws)
+ ws.prepareSheetPr()
ws.SheetPr.EnableFormatConditionsCalculation = opts.EnableFormatConditionsCalculation
}
if opts.Published != nil {
- prepareSheetPr(ws)
+ ws.prepareSheetPr()
ws.SheetPr.Published = opts.Published
}
if opts.AutoPageBreaks != nil {
@@ -151,10 +165,7 @@ func (ws *xlsxWorksheet) setSheetProps(opts *SheetPropsOptions) {
preparePageSetUpPr(ws)
ws.SheetPr.PageSetUpPr.FitToPage = *opts.FitToPage
}
- if opts.OutlineSummaryBelow != nil {
- prepareOutlinePr(ws)
- ws.SheetPr.OutlinePr.SummaryBelow = *opts.OutlineSummaryBelow
- }
+ ws.setSheetOutlineProps(opts)
if opts.TabColorIndexed != nil {
prepareTabColor(ws)
ws.SheetPr.TabColor.Indexed = *opts.TabColorIndexed
@@ -237,7 +248,8 @@ func (f *File) GetSheetProps(sheet string) (SheetPropsOptions, error) {
opts.FitToPage = boolPtr(ws.SheetPr.PageSetUpPr.FitToPage)
}
if ws.SheetPr.OutlinePr != nil {
- opts.OutlineSummaryBelow = boolPtr(ws.SheetPr.OutlinePr.SummaryBelow)
+ opts.OutlineSummaryBelow = ws.SheetPr.OutlinePr.SummaryBelow
+ opts.OutlineSummaryRight = ws.SheetPr.OutlinePr.SummaryRight
}
if ws.SheetPr.TabColor != nil {
opts.TabColorIndexed = intPtr(ws.SheetPr.TabColor.Indexed)
diff --git a/sheetpr_test.go b/sheetpr_test.go
index ccadbef..b4ee18d 100644
--- a/sheetpr_test.go
+++ b/sheetpr_test.go
@@ -61,25 +61,26 @@ func TestSetSheetProps(t *testing.T) {
assert.True(t, ok)
ws.(*xlsxWorksheet).SheetPr = nil
ws.(*xlsxWorksheet).SheetFormatPr = nil
- baseColWidth := uint8(8)
+ baseColWidth, enable := uint8(8), boolPtr(true)
expected := SheetPropsOptions{
CodeName: stringPtr("code"),
- EnableFormatConditionsCalculation: boolPtr(true),
- Published: boolPtr(true),
- AutoPageBreaks: boolPtr(true),
- FitToPage: boolPtr(true),
+ EnableFormatConditionsCalculation: enable,
+ Published: enable,
+ AutoPageBreaks: enable,
+ FitToPage: enable,
TabColorIndexed: intPtr(1),
TabColorRGB: stringPtr("#FFFF00"),
TabColorTheme: intPtr(1),
TabColorTint: float64Ptr(1),
- OutlineSummaryBelow: boolPtr(true),
+ OutlineSummaryBelow: enable,
+ OutlineSummaryRight: enable,
BaseColWidth: &baseColWidth,
DefaultColWidth: float64Ptr(10),
DefaultRowHeight: float64Ptr(10),
- CustomHeight: boolPtr(true),
- ZeroHeight: boolPtr(true),
- ThickTop: boolPtr(true),
- ThickBottom: boolPtr(true),
+ CustomHeight: enable,
+ ZeroHeight: enable,
+ ThickTop: enable,
+ ThickBottom: enable,
}
assert.NoError(t, f.SetSheetProps("Sheet1", &expected))
opts, err := f.GetSheetProps("Sheet1")
@@ -87,7 +88,7 @@ func TestSetSheetProps(t *testing.T) {
assert.Equal(t, expected, opts)
ws.(*xlsxWorksheet).SheetPr = nil
- assert.NoError(t, f.SetSheetProps("Sheet1", &SheetPropsOptions{FitToPage: boolPtr(true)}))
+ assert.NoError(t, f.SetSheetProps("Sheet1", &SheetPropsOptions{FitToPage: enable}))
ws.(*xlsxWorksheet).SheetPr = nil
assert.NoError(t, f.SetSheetProps("Sheet1", &SheetPropsOptions{TabColorRGB: stringPtr("#FFFF00")}))
ws.(*xlsxWorksheet).SheetPr = nil
diff --git a/sparkline.go b/sparkline.go
index f2e0d7a..0c32462 100644
--- a/sparkline.go
+++ b/sparkline.go
@@ -365,7 +365,7 @@ func (f *File) addSparklineGroupByStyle(ID int) *xlsxX14SparklineGroup {
// Excel 2007, but they won't be displayed. For example, add a grouped
// sparkline. Changes are applied to all three:
//
-// err := f.AddSparkline("Sheet1", &excelize.SparklineOption{
+// err := f.AddSparkline("Sheet1", &excelize.SparklineOptions{
// Location: []string{"A1", "A2", "A3"},
// Range: []string{"Sheet2!A1:J1", "Sheet2!A2:J2", "Sheet2!A3:J3"},
// Markers: true,
diff --git a/stream.go b/stream.go
index 3d06790..b99730d 100644
--- a/stream.go
+++ b/stream.go
@@ -40,12 +40,12 @@ type StreamWriter struct {
// NewStreamWriter return stream writer struct by given worksheet name for
// generate new worksheet with large amounts of data. Note that after set
-// rows, you must call the 'Flush' method to end the streaming writing
-// process and ensure that the order of line numbers is ascending, the common
-// API and stream API can't be work mixed to writing data on the worksheets,
-// you can't get cell value when in-memory chunks data over 16MB. For
-// example, set data for worksheet of size 102400 rows x 50 columns with
-// numbers and style:
+// rows, you must call the 'Flush' method to end the streaming writing process
+// and ensure that the order of line numbers is ascending, the normal mode
+// functions and stream mode functions can't be work mixed to writing data on
+// the worksheets, you can't get cell value when in-memory chunks data over
+// 16MB. For example, set data for worksheet of size 102400 rows x 50 columns
+// with numbers and style:
//
// file := excelize.NewFile()
// streamWriter, err := file.NewStreamWriter("Sheet1")
diff --git a/xmlWorksheet.go b/xmlWorksheet.go
index 28e785f..e55406c 100644
--- a/xmlWorksheet.go
+++ b/xmlWorksheet.go
@@ -250,9 +250,9 @@ type xlsxSheetPr struct {
// adjust the direction of grouper controls.
type xlsxOutlinePr struct {
ApplyStyles *bool `xml:"applyStyles,attr"`
- SummaryBelow bool `xml:"summaryBelow,attr"`
- SummaryRight bool `xml:"summaryRight,attr"`
- ShowOutlineSymbols bool `xml:"showOutlineSymbols,attr"`
+ SummaryBelow *bool `xml:"summaryBelow,attr"`
+ SummaryRight *bool `xml:"summaryRight,attr"`
+ ShowOutlineSymbols *bool `xml:"showOutlineSymbols,attr"`
}
// xlsxPageSetUpPr expresses page setup properties of the worksheet.
@@ -989,6 +989,9 @@ type SheetPropsOptions struct {
// OutlineSummaryBelow indicating whether summary rows appear below detail
// in an outline, when applying an outline.
OutlineSummaryBelow *bool `json:"outline_summary_below,omitempty"`
+ // OutlineSummaryRight indicating whether summary columns appear to the
+ // right of detail in an outline, when applying an outline.
+ OutlineSummaryRight *bool `json:"outline_summary_right,omitempty"`
// BaseColWidth specifies the number of characters of the maximum digit
// width of the normal style's font. This value does not include margin
// padding or extra padding for grid lines. It is only the number of