diff --git a/calc.go b/calc.go index b19dba74..5d559921 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 fd6a463a..ec7485bd 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 9d49dbee..1ce8df38 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 3f9cd78d..b30b6c14 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 8266c8e6..0999a971 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 6ec9aef8..a737a9a0 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 a246e9ef..3a805c47 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) - } - } - preparePageSetUpPr := func(ws *xlsxWorksheet) { - prepareSheetPr(ws) - if ws.SheetPr.PageSetUpPr == nil { - ws.SheetPr.PageSetUpPr = new(xlsxPageSetUpPr) - } +// 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) { - prepareSheetPr(ws) + 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) { + ws.prepareSheetPr() + if ws.SheetPr.PageSetUpPr == nil { + ws.SheetPr.PageSetUpPr = new(xlsxPageSetUpPr) + } + } 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 ccadbefc..b4ee18db 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 f2e0d7a4..0c324626 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 3d067902..b99730dc 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 28e785f2..e55406c2 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