From 3f8f4f52e68d408da5a2e5108af3cc99bf8586bc Mon Sep 17 00:00:00 2001 From: xuri Date: Tue, 8 Feb 2022 00:08:06 +0800 Subject: [PATCH] This closes #1139, `SetCellDefault` support non-numeric value - Add default value on getting `View` property of sheet views - Add examples and unit test for set sheet views - Re-order field on sheet view options - Fix incorrect build-in number format: 42 - Simplify code for the `stylesReader` function --- cell.go | 3 + sheetview.go | 153 +++++++++++++++++++++++----------------------- sheetview_test.go | 84 ++++++++++++++++--------- styles.go | 7 +-- 4 files changed, 136 insertions(+), 111 deletions(-) diff --git a/cell.go b/cell.go index 35060ab4e4..9af93f6356 100644 --- a/cell.go +++ b/cell.go @@ -450,6 +450,9 @@ func (f *File) SetCellDefault(sheet, axis, value string) error { // setCellDefault prepares cell type and string type cell value by a given // string. func setCellDefault(value string) (t string, v string) { + if ok, _ := isNumeric(value); !ok { + t = "str" + } v = value return } diff --git a/sheetview.go b/sheetview.go index 5bb5aaff75..b0912ec7a7 100644 --- a/sheetview.go +++ b/sheetview.go @@ -27,74 +27,49 @@ type SheetViewOptionPtr interface { } type ( - // DefaultGridColor is a SheetViewOption. It specifies a flag indicating that - // the consuming application should use the default grid lines color (system - // dependent). Overrides any color specified in colorId. + // DefaultGridColor is a SheetViewOption. It specifies a flag indicating + // that the consuming application should use the default grid lines color + // (system dependent). Overrides any color specified in colorId. DefaultGridColor bool - // RightToLeft is a SheetViewOption. It specifies a flag indicating whether - // the sheet is in 'right to left' display mode. When in this mode, Column A - // is on the far right, Column B ;is one column left of Column A, and so on. - // Also, information in cells is displayed in the Right to Left format. - RightToLeft bool - // ShowFormulas is a SheetViewOption. It specifies a flag indicating whether - // this sheet should display formulas. + // ShowFormulas is a SheetViewOption. It specifies a flag indicating + // whether this sheet should display formulas. ShowFormulas bool - // ShowGridLines is a SheetViewOption. It specifies a flag indicating whether - // this sheet should display gridlines. + // ShowGridLines is a SheetViewOption. It specifies a flag indicating + // whether this sheet should display gridlines. ShowGridLines bool // ShowRowColHeaders is a SheetViewOption. It specifies a flag indicating // whether the sheet should display row and column headings. ShowRowColHeaders bool - // ZoomScale is a SheetViewOption. It specifies a window zoom magnification - // for current view representing percent values. This attribute is restricted - // to values ranging from 10 to 400. Horizontal & Vertical scale together. - ZoomScale float64 - // TopLeftCell is a SheetViewOption. It specifies a location of the top left - // visible cell Location of the top left visible cell in the bottom right - // pane (when in Left-to-Right mode). - TopLeftCell string - // ShowZeros is a SheetViewOption. It specifies a flag indicating - // whether to "show a zero in cells that have zero value". - // When using a formula to reference another cell which is empty, the referenced value becomes 0 + // ShowZeros is a SheetViewOption. It specifies a flag indicating whether + // to "show a zero in cells that have zero value". When using a formula to + // reference another cell which is empty, the referenced value becomes 0 // when the flag is true. (Default setting is true.) ShowZeros bool - // View is a SheetViewOption. It specifies a flag indicating - // how sheet is displayed, by default it uses empty string - // available options: normal, pageLayout, pageBreakPreview - View string - // ShowRuler is a SheetViewOption. It specifies a flag indicating - // this sheet should display ruler. + // RightToLeft is a SheetViewOption. It specifies a flag indicating whether + // the sheet is in 'right to left' display mode. When in this mode, Column + // A is on the far right, Column B ;is one column left of Column A, and so + // on. Also, information in cells is displayed in the Right to Left format. + RightToLeft bool + // ShowRuler is a SheetViewOption. It specifies a flag indicating this + // sheet should display ruler. ShowRuler bool - - /* TODO - // ShowWhiteSpace is a SheetViewOption. It specifies a flag indicating - // whether page layout view shall display margins. False means do not display - // left, right, top (header), and bottom (footer) margins (even when there is - // data in the header or footer). - ShowWhiteSpace bool - // WindowProtection is a SheetViewOption. - WindowProtection bool - */ + // View is a SheetViewOption. It specifies a flag indicating how sheet is + // displayed, by default it uses empty string available options: normal, + // pageLayout, pageBreakPreview + View string + // TopLeftCell is a SheetViewOption. It specifies a location of the top + // left visible cell Location of the top left visible cell in the bottom + // right pane (when in Left-to-Right mode). + TopLeftCell string + // ZoomScale is a SheetViewOption. It specifies a window zoom magnification + // for current view representing percent values. This attribute is + // restricted to values ranging from 10 to 400. Horizontal & Vertical + // scale together. + ZoomScale float64 ) // Defaults for each option are described in XML schema for CT_SheetView -func (o TopLeftCell) setSheetViewOption(view *xlsxSheetView) { - view.TopLeftCell = string(o) -} - -func (o *TopLeftCell) getSheetViewOption(view *xlsxSheetView) { - *o = TopLeftCell(string(view.TopLeftCell)) -} - -func (o View) setSheetViewOption(view *xlsxSheetView) { - view.View = string(o) -} - -func (o *View) getSheetViewOption(view *xlsxSheetView) { - *o = View(string(view.View)) -} - func (o DefaultGridColor) setSheetViewOption(view *xlsxSheetView) { view.DefaultGridColor = boolPtr(bool(o)) } @@ -103,14 +78,6 @@ func (o *DefaultGridColor) getSheetViewOption(view *xlsxSheetView) { *o = DefaultGridColor(defaultTrue(view.DefaultGridColor)) // Excel default: true } -func (o RightToLeft) setSheetViewOption(view *xlsxSheetView) { - view.RightToLeft = bool(o) // Excel default: false -} - -func (o *RightToLeft) getSheetViewOption(view *xlsxSheetView) { - *o = RightToLeft(view.RightToLeft) -} - func (o ShowFormulas) setSheetViewOption(view *xlsxSheetView) { view.ShowFormulas = bool(o) // Excel default: false } @@ -127,12 +94,12 @@ func (o *ShowGridLines) getSheetViewOption(view *xlsxSheetView) { *o = ShowGridLines(defaultTrue(view.ShowGridLines)) // Excel default: true } -func (o ShowRuler) setSheetViewOption(view *xlsxSheetView) { - view.ShowRuler = boolPtr(bool(o)) +func (o ShowRowColHeaders) setSheetViewOption(view *xlsxSheetView) { + view.ShowRowColHeaders = boolPtr(bool(o)) } -func (o *ShowRuler) getSheetViewOption(view *xlsxSheetView) { - *o = ShowRuler(defaultTrue(view.ShowRuler)) // Excel default: true +func (o *ShowRowColHeaders) getSheetViewOption(view *xlsxSheetView) { + *o = ShowRowColHeaders(defaultTrue(view.ShowRowColHeaders)) // Excel default: true } func (o ShowZeros) setSheetViewOption(view *xlsxSheetView) { @@ -143,12 +110,40 @@ func (o *ShowZeros) getSheetViewOption(view *xlsxSheetView) { *o = ShowZeros(defaultTrue(view.ShowZeros)) // Excel default: true } -func (o ShowRowColHeaders) setSheetViewOption(view *xlsxSheetView) { - view.ShowRowColHeaders = boolPtr(bool(o)) +func (o RightToLeft) setSheetViewOption(view *xlsxSheetView) { + view.RightToLeft = bool(o) // Excel default: false } -func (o *ShowRowColHeaders) getSheetViewOption(view *xlsxSheetView) { - *o = ShowRowColHeaders(defaultTrue(view.ShowRowColHeaders)) // Excel default: true +func (o *RightToLeft) getSheetViewOption(view *xlsxSheetView) { + *o = RightToLeft(view.RightToLeft) +} + +func (o ShowRuler) setSheetViewOption(view *xlsxSheetView) { + view.ShowRuler = boolPtr(bool(o)) +} + +func (o *ShowRuler) getSheetViewOption(view *xlsxSheetView) { + *o = ShowRuler(defaultTrue(view.ShowRuler)) // Excel default: true +} + +func (o View) setSheetViewOption(view *xlsxSheetView) { + view.View = string(o) +} + +func (o *View) getSheetViewOption(view *xlsxSheetView) { + if view.View != "" { + *o = View(view.View) + return + } + *o = View("normal") +} + +func (o TopLeftCell) setSheetViewOption(view *xlsxSheetView) { + view.TopLeftCell = string(o) +} + +func (o *TopLeftCell) getSheetViewOption(view *xlsxSheetView) { + *o = TopLeftCell(string(view.TopLeftCell)) } func (o ZoomScale) setSheetViewOption(view *xlsxSheetView) { @@ -186,13 +181,15 @@ func (f *File) getSheetView(sheet string, viewIndex int) (*xlsxSheetView, error) // Available options: // // DefaultGridColor(bool) -// RightToLeft(bool) // ShowFormulas(bool) // ShowGridLines(bool) // ShowRowColHeaders(bool) -// ZoomScale(float64) -// TopLeftCell(string) // ShowZeros(bool) +// RightToLeft(bool) +// ShowRuler(bool) +// View(string) +// TopLeftCell(string) +// ZoomScale(float64) // // Example: // @@ -216,13 +213,15 @@ func (f *File) SetSheetViewOptions(name string, viewIndex int, opts ...SheetView // Available options: // // DefaultGridColor(bool) -// RightToLeft(bool) // ShowFormulas(bool) // ShowGridLines(bool) // ShowRowColHeaders(bool) -// ZoomScale(float64) -// TopLeftCell(string) // ShowZeros(bool) +// RightToLeft(bool) +// ShowRuler(bool) +// View(string) +// TopLeftCell(string) +// ZoomScale(float64) // // Example: // diff --git a/sheetview_test.go b/sheetview_test.go index cfe628d716..2bba8f9802 100644 --- a/sheetview_test.go +++ b/sheetview_test.go @@ -9,31 +9,39 @@ import ( var _ = []SheetViewOption{ DefaultGridColor(true), - RightToLeft(false), ShowFormulas(false), ShowGridLines(true), ShowRowColHeaders(true), - TopLeftCell("B2"), - View("pageLayout"), + ShowZeros(true), + RightToLeft(false), ShowRuler(false), + View("pageLayout"), + TopLeftCell("B2"), + ZoomScale(100), // SheetViewOptionPtr are also SheetViewOption new(DefaultGridColor), - new(RightToLeft), new(ShowFormulas), new(ShowGridLines), new(ShowRowColHeaders), + new(ShowZeros), + new(RightToLeft), + new(ShowRuler), + new(View), new(TopLeftCell), + new(ZoomScale), } var _ = []SheetViewOptionPtr{ (*DefaultGridColor)(nil), - (*RightToLeft)(nil), (*ShowFormulas)(nil), (*ShowGridLines)(nil), (*ShowRowColHeaders)(nil), - (*TopLeftCell)(nil), - (*View)(nil), + (*ShowZeros)(nil), + (*RightToLeft)(nil), (*ShowRuler)(nil), + (*View)(nil), + (*TopLeftCell)(nil), + (*ZoomScale)(nil), } func ExampleFile_SetSheetViewOptions() { @@ -42,14 +50,14 @@ func ExampleFile_SetSheetViewOptions() { if err := f.SetSheetViewOptions(sheet, 0, DefaultGridColor(false), - RightToLeft(false), ShowFormulas(true), ShowGridLines(true), ShowRowColHeaders(true), - ZoomScale(80), - TopLeftCell("C3"), - View("pageLayout"), + RightToLeft(false), ShowRuler(false), + View("pageLayout"), + TopLeftCell("C3"), + ZoomScale(80), ); err != nil { fmt.Println(err) } @@ -95,80 +103,98 @@ func ExampleFile_GetSheetViewOptions() { var ( defaultGridColor DefaultGridColor - rightToLeft RightToLeft showFormulas ShowFormulas showGridLines ShowGridLines - showZeros ShowZeros showRowColHeaders ShowRowColHeaders - zoomScale ZoomScale + showZeros ShowZeros + rightToLeft RightToLeft + showRuler ShowRuler + view View topLeftCell TopLeftCell + zoomScale ZoomScale ) if err := f.GetSheetViewOptions(sheet, 0, &defaultGridColor, - &rightToLeft, &showFormulas, &showGridLines, - &showZeros, &showRowColHeaders, - &zoomScale, + &showZeros, + &rightToLeft, + &showRuler, + &view, &topLeftCell, + &zoomScale, ); err != nil { fmt.Println(err) } fmt.Println("Default:") fmt.Println("- defaultGridColor:", defaultGridColor) - fmt.Println("- rightToLeft:", rightToLeft) fmt.Println("- showFormulas:", showFormulas) fmt.Println("- showGridLines:", showGridLines) - fmt.Println("- showZeros:", showZeros) fmt.Println("- showRowColHeaders:", showRowColHeaders) - fmt.Println("- zoomScale:", zoomScale) + fmt.Println("- showZeros:", showZeros) + fmt.Println("- rightToLeft:", rightToLeft) + fmt.Println("- showRuler:", showRuler) + fmt.Println("- view:", view) fmt.Println("- topLeftCell:", `"`+topLeftCell+`"`) + fmt.Println("- zoomScale:", zoomScale) - if err := f.SetSheetViewOptions(sheet, 0, TopLeftCell("B2")); err != nil { + if err := f.SetSheetViewOptions(sheet, 0, ShowGridLines(false)); err != nil { fmt.Println(err) } - if err := f.GetSheetViewOptions(sheet, 0, &topLeftCell); err != nil { + if err := f.GetSheetViewOptions(sheet, 0, &showGridLines); err != nil { fmt.Println(err) } - if err := f.SetSheetViewOptions(sheet, 0, ShowGridLines(false)); err != nil { + if err := f.SetSheetViewOptions(sheet, 0, ShowZeros(false)); err != nil { fmt.Println(err) } - if err := f.GetSheetViewOptions(sheet, 0, &showGridLines); err != nil { + if err := f.GetSheetViewOptions(sheet, 0, &showZeros); err != nil { fmt.Println(err) } - if err := f.SetSheetViewOptions(sheet, 0, ShowZeros(false)); err != nil { + if err := f.SetSheetViewOptions(sheet, 0, View("pageLayout")); err != nil { fmt.Println(err) } - if err := f.GetSheetViewOptions(sheet, 0, &showZeros); err != nil { + if err := f.GetSheetViewOptions(sheet, 0, &view); err != nil { + fmt.Println(err) + } + + if err := f.SetSheetViewOptions(sheet, 0, TopLeftCell("B2")); err != nil { + fmt.Println(err) + } + + if err := f.GetSheetViewOptions(sheet, 0, &topLeftCell); err != nil { fmt.Println(err) } fmt.Println("After change:") fmt.Println("- showGridLines:", showGridLines) fmt.Println("- showZeros:", showZeros) + fmt.Println("- view:", view) fmt.Println("- topLeftCell:", topLeftCell) // Output: // Default: // - defaultGridColor: true - // - rightToLeft: false // - showFormulas: false // - showGridLines: true - // - showZeros: true // - showRowColHeaders: true - // - zoomScale: 0 + // - showZeros: true + // - rightToLeft: false + // - showRuler: true + // - view: normal // - topLeftCell: "" + // - zoomScale: 0 // After change: // - showGridLines: false // - showZeros: false + // - view: pageLayout // - topLeftCell: B2 } diff --git a/styles.go b/styles.go index 5d373d38df..7678b847b3 100644 --- a/styles.go +++ b/styles.go @@ -53,7 +53,7 @@ var builtInNumFmt = map[int]string{ 39: "#,##0.00;(#,##0.00)", 40: "#,##0.00;[red](#,##0.00)", 41: `_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)`, - 42: `_("$"* #,##0_);_("$* \(#,##0\);_("$"* "-"_);_(@_)`, + 42: `_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)`, 43: `_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)`, 44: `_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)`, 45: "mm:ss", @@ -1074,16 +1074,13 @@ func is12HourTime(format string) bool { // stylesReader provides a function to get the pointer to the structure after // deserialization of xl/styles.xml. func (f *File) stylesReader() *xlsxStyleSheet { - var err error - if f.Styles == nil { f.Styles = new(xlsxStyleSheet) - if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathStyles)))). + if err := f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathStyles)))). Decode(f.Styles); err != nil && err != io.EOF { log.Printf("xml decode error: %s", err) } } - return f.Styles }