diff --git a/cell.go b/cell.go index 4438c2c..9a45a98 100644 --- a/cell.go +++ b/cell.go @@ -115,8 +115,8 @@ func (c *Cell) Bool() (bool, error) { return false, errTypeMismatch } -//SetGeneral sets the value as general type -func (c *Cell) SetGeneral(value string) { +//setGeneral sets the value as general type +func (c *Cell) setGeneral(value string) { c.ml.Type = types.CellTypeGeneral c.ml.Value = value c.ml.Formula = nil @@ -290,7 +290,7 @@ func (c *Cell) SetValue(value interface{}) { case nil: c.Reset() default: - c.SetGeneral(fmt.Sprintf("%v", value)) + c.setGeneral(fmt.Sprintf("%v", value)) } } @@ -316,40 +316,13 @@ func (c *Cell) Styles() styles.DirectStyleID { //SetStyles sets style format to requested DirectStyleID or styles.Info func (c *Cell) SetStyles(s interface{}) { - if styleID, ok := s.(styles.DirectStyleID); ok { - c.ml.Style = styleID - return - } - - //we can update styleSheet only when sheet is in write mode, to prevent pollution of styleSheet with fake values - if (c.sheet.mode() & sheetModeWrite) == 0 { - panic(errorNotSupportedWrite) - } - - var format *styles.Info - if f, ok := s.(styles.Info); ok { - format = &f - } else if f, ok := s.(*styles.Info); ok { - format = f - } else { - panic("only DirectStyleID or styles.Info supported as styles for cell") - } - - styleID := c.sheet.workbook.doc.styleSheet.addStyle(format) - c.ml.Style = styleID + c.ml.Style = c.sheet.resolveStyleID(s) } //SetValueWithFormat is helper function that internally works as SetValue and SetStyles with NumberFormat func (c *Cell) SetValueWithFormat(value interface{}, formatCode string) { - //we can update styleSheet only when sheet is in write mode, to prevent pollution of styleSheet with fake values - if (c.sheet.mode() & sheetModeWrite) == 0 { - panic(errorNotSupportedWrite) - } - - styleID := c.sheet.workbook.doc.styleSheet.addStyle(styles.New(styles.NumberFormat(formatCode))) - + c.ml.Style = c.sheet.resolveStyleID(styles.New(styles.NumberFormat(formatCode))) c.SetValue(value) - c.ml.Style = styleID } //Hyperlink returns resolved hyperlink.Info if there is any hyperlink or nil otherwise diff --git a/col.go b/col.go index cd4c639..70d91aa 100644 --- a/col.go +++ b/col.go @@ -28,6 +28,10 @@ func (c *Col) SetOptions(o *options.Info) { c.ml.CustomWidth = true } + if o.Format != nil { + c.SetStyles(o.Format) + } + c.ml.OutlineLevel = o.OutlineLevel c.ml.Hidden = o.Hidden c.ml.Collapsed = o.Collapsed @@ -40,8 +44,8 @@ func (c *Col) Styles() styles.DirectStyleID { } //SetStyles sets default style for the column. Affects cells not yet allocated in the column. In other words, this style applies to new cells. -func (c *Col) SetStyles(styleID styles.DirectStyleID) { - c.ml.Style = styleID +func (c *Col) SetStyles(s interface{}) { + c.ml.Style = c.sheet.info().resolveStyleID(s) } //CopyTo copies col cells into another col with cIdx index. diff --git a/docs/src/.vuepress/config.js b/docs/src/.vuepress/config.js index fb0fe58..61db327 100644 --- a/docs/src/.vuepress/config.js +++ b/docs/src/.vuepress/config.js @@ -13,10 +13,10 @@ module.exports = { // editLinkText: 'Help to improve this page!', lastUpdated: 'Last Updated', displayAllHeaders: true, - // algolia: { - // apiKey: '', - // indexName: '' - // }, + algolia: { + apiKey: '3e97b85acaa0479ed415ab8ecdaf55d6', + indexName: 'xlsx2go' + }, nav: [ {text: 'Home', link: '/'}, {text: 'Guide', link: '/guide/'}, @@ -62,6 +62,6 @@ module.exports = { '@vuepress/nprogress', ['container', {type: 'right', defaultTitle: ''}], ['container', {type: 'note', defaultTitle: ''}], - // ['@vuepress/google-analytics', {'ga': 'UA-00000000-0'}], + ['@vuepress/google-analytics', {'ga': 'UA-122513-16'}], ], }; diff --git a/docs/src/code/rich_text_test.go b/docs/src/code/rich_text_test.go index 1b9c694..86d4074 100644 --- a/docs/src/code/rich_text_test.go +++ b/docs/src/code/rich_text_test.go @@ -62,7 +62,7 @@ func Example_richText() { sheet.CellByRef("B8").SetText( "E=mc", styles.New( - styles.Font.Effect(styles.FontEffectSuperscript), + styles.Font.Superscript, ), "2", styles.New( diff --git a/docs/src/code/styles_font_test.go b/docs/src/code/styles_font_test.go new file mode 100644 index 0000000..8e67045 --- /dev/null +++ b/docs/src/code/styles_font_test.go @@ -0,0 +1,26 @@ +package code + +import ( + "github.com/plandem/xlsx/format/styles" +) + +func Example_stylesFont() { + //all possible settings for font + styles.New( + styles.Font.Name("Courier New"), + styles.Font.Bold, + styles.Font.Italic, + styles.Font.Strikeout, + styles.Font.Superscript, + styles.Font.Subscript, + styles.Font.Shadow, + styles.Font.Condense, + styles.Font.Extend, + styles.Font.Family(styles.FontFamilyRoman), + styles.Font.Color("#FF0000"), + styles.Font.Size(16), + styles.Font.Underline(styles.UnderlineTypeSingle), + styles.Font.Scheme(styles.FontSchemeMinor), + styles.Font.Charset(styles.FontCharsetMAC), + ) +} diff --git a/docs/src/guide/number_format.md b/docs/src/guide/number_format.md new file mode 100644 index 0000000..7832d9c --- /dev/null +++ b/docs/src/guide/number_format.md @@ -0,0 +1,142 @@ +# Number Format Codes +[[toc]] +Number format code is way to show numeric value. It controls whether a number is displayed as an integer, a floating number, a date, a currency value or some other user defined format. + +::: tip +Xlsx2Go supports built-in Excel codes and will try to detect/convert to proper internal ID, as well as custom codes - use it as is without worrying. +::: + +### Built-in Codes +::: note General type +* `@` +* `General` +::: + +::: note Integer number +* `0` +* `0%` +* `(#,##0_);(#,##0)` +* `(#,##0_);[RED](#,##0)` +::: + +::: note Float number +* `0.00` +* `#,##0` +* `#,##0.00` +* `($#,##0_);($#,##0)` +* `($#,##0_);[RED]($#,##0)` +* `($#,##0.00_);($#,##0.00_)` +* `($#,##0.00_);[RED]($#,##0.00_)` +* `0.00%` +* `0.00E+00` +* `# ?/?` +* `# ??/??` +* `(#,##0.00);(#,##0.00)` +* `(#,##0.00);[RED](#,##0.00)` +* `_(*#,##0_);_(*(#,##0);_(*"-"_);_(@_)` +* `_($*#,##0_);_($*(#,##0);_(*"-"_);_(@_)` +* `_(*#,##0.00_);_(*(#,##0.00);_(*"-"??_);_(@_)` +* `_($*#,##0.00_);_($*(#,##0.00);_(*"-"??_);_(@_)` +* `##0.0E+0` +::: + +::: note Date +* `m-d-yy` +* `d-mmm-yy` +* `d-mmm` +* `mmm-yy` +::: + +::: note Time +* `h:mm AM/PM` +* `h:mm:ss AM/PM` +* `h:mm` +* `h:mm:ss` +::: + +::: note Date+Time +* `m-d-yy h:mm` +::: + +::: note DeltaTime +* `mm:ss` +* `[h]:mm:ss` +* `mm:ss.0` +::: + +### Custom Codes +Format code can control any aspect of number formatting allowed by Excel: + +::: tip Currency +The `$` in format appears as the local currency symbol. +::: + +::: tip Colors +The color format should have one of the following values: + +`[Black]` `[Blue]` `[Cyan]` `[Green]` `[Magenta]` `[Red]` `[White]` `[Yellow]` +::: + +#### Examples + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Number codeGo ValueExcel Output
dd/mm/yyyy hh:mm AM/PMtime.Now()18/07/2019 12:30 AM
mm/dd/yytime.Now()07/18/19
mmm d yyyytime.Now()Jul 18 2019
d mmmm yyyytime.Now()18 July 2019
0.0001.23456781.235
#,##01234.5671,235
0 "dollar and" .00 "cents"1.871 dollar and .87 cents
[Green]General;[Red]-General;General123451235
-12345-12345
00
+ +::: note + +::: right +For more information about custom formats, check [Microsoft Documentation](https://support.office.com/en-us/article/create-a-custom-number-format-78f2a361-936b-4c03-8772-09fab54be7f4?ui=en-US&rs=en-US&ad=US) +::: + diff --git a/docs/src/guide/styles-formatting.md b/docs/src/guide/styles-formatting.md index 15aace0..dae91ea 100644 --- a/docs/src/guide/styles-formatting.md +++ b/docs/src/guide/styles-formatting.md @@ -1,7 +1,56 @@ # Styles Formatting [[toc]] +Styles can be defined through special type - general type for all available styles. But information that will be using to style object, depends on usage, e.g. to style cells everything will be use, to style rich texts - only font information. + +```go + // create a new styles + ss := styles.New( + styles.Font.Bold, + styles.Font.Color("#ff0000"), + ) + + //update styles + ss.Set( + styles.Border.Color("#009000"), + styles.Border.Type(styles.BorderStyleMedium), + ) +``` +::: warning Modify Styles +While you can modify created styles, you should keep in mind, that modifying will work only before applying styles to cell and any modifications after applying, will create new styles. +::: + +```go + ss := styles.New( + styles.Font.Bold, + )) + + //font will be `bold` + sheet.CellByRef("A1").SetStyles(ss) + + //modify styles + ss.Set( + styles.Font.Color("#ff0000"), + ) + + //`A2` - will be `bold and red` + //`A1` - will be only `bold` and without color + sheet.CellByRef("A2").SetStyles(ss) +``` + ### Font +::: warning +Excel can only display installed fonts, that's why using standard fonts(e.g.: `Calibri`, `Times New Roman` or `Courier New`) is highly recommended. +::: + +::: note +The default font for cell is `Calibri` (Excel 2007+) +::: +<<< @/src/code/styles_font_test.go + +::: note Predefined values +Xlsx2Go defined all built-in values to use for styling. For more information, check [API documentation](https://godoc.org/github.com/plandem/xlsx/format/styles#pkg-constants) +::: ### Fill @@ -9,6 +58,6 @@ ### Alignment -### Numbers +### Number Format ### Protection \ No newline at end of file diff --git a/docs/src/guide/values.md b/docs/src/guide/values.md index 341ce6e..922300b 100644 --- a/docs/src/guide/values.md +++ b/docs/src/guide/values.md @@ -94,7 +94,7 @@ Keep in mind, that text can be a simple string, as well as full featured rich te Check [Rich Text](/guide/rich-text.md) for more information about rich texts. ::: -### Custom Formats +### Number Formats In some cases we want to set value, but also use format how to display that value. ```go @@ -102,61 +102,6 @@ In some cases we want to set value, but also use format how to display that valu sheet.CellByRef("A1").SetValueWithFormat(12345.12345, "0.00") ``` -#### Format Codes -::: tip -Xlsx2Go supports default Excel codes and will try to detect/convert to proper internal code, as well as custom codes - use it as is without worrying. -::: - -::: note General type -* `@` -::: - -::: note Integer number type -* `0` -* `0%` -* `(#,##0_);(#,##0)` -* `(#,##0_);[RED](#,##0)` -::: - -::: note Float number type -* `0.00` -* `#,##0` -* `#,##0.00` -* `($#,##0_);($#,##0)` -* `($#,##0_);[RED]($#,##0)` -* `($#,##0.00_);($#,##0.00_)` -* `($#,##0.00_);[RED]($#,##0.00_)` -* `0.00%` -* `0.00E+00` -* `# ?/?` -* `# ??/??` -* `(#,##0.00);(#,##0.00)` -* `(#,##0.00);[RED](#,##0.00)` -* `_(*#,##0_);_(*(#,##0);_(*"-"_);_(@_)` -* `_($*#,##0_);_($*(#,##0);_(*"-"_);_(@_)` -* `_(*#,##0.00_);_(*(#,##0.00);_(*"-"??_);_(@_)` -* `_($*#,##0.00_);_($*(#,##0.00);_(*"-"??_);_(@_)` -* `##0.0E+0` -::: - -::: note Date type -* `m-d-yy` -* `d-mmm-yy` -* `d-mmm` -* `mmm-yy` -::: - -::: note Time type -* `h:mm AM/PM` -* `h:mm:ss AM/PM` -* `h:mm` -* `h:mm:ss` -::: - -::: note DeltaTime type -* `m-d-yy h:mm` -* `mm:ss` -* `[h]:mm:ss` -* `mm:ss.0` -::: - +::: tip Format Codes +Check [Number Format](/guide/number_format.md) for more information about codes for number format. +::: \ No newline at end of file diff --git a/format/styles/font.go b/format/styles/font.go index 3f5bcd8..d28de53 100644 --- a/format/styles/font.go +++ b/format/styles/font.go @@ -41,6 +41,14 @@ func (f *fontOption) Strikeout(s *Info) { s.styleInfo.Font.Strike = true } +func (f *fontOption) Superscript(s *Info) { + s.styleInfo.Font.Effect = primitives.FontEffectSuperscript +} + +func (f *fontOption) Subscript(s *Info) { + s.styleInfo.Font.Effect = primitives.FontEffectSubscript +} + func (f *fontOption) Shadow(s *Info) { s.styleInfo.Font.Shadow = true } @@ -77,12 +85,6 @@ func (f *fontOption) Underline(underline primitives.UnderlineType) Option { } } -func (f *fontOption) Effect(effect primitives.FontEffectType) Option { - return func(s *Info) { - s.styleInfo.Font.Effect = effect - } -} - func (f *fontOption) Scheme(scheme primitives.FontSchemeType) Option { return func(s *Info) { s.styleInfo.Font.Scheme = scheme diff --git a/format/styles/font_effect.go b/format/styles/font_effect.go deleted file mode 100644 index b3f3669..0000000 --- a/format/styles/font_effect.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2017 Andrey Gayvoronsky -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package styles - -import ( - "github.com/plandem/xlsx/internal/ml/primitives" -) - -//List of all possible values for FontEffectType -const ( - FontEffectBaseline primitives.FontEffectType = "baseline" - FontEffectSuperscript primitives.FontEffectType = "superscript" - FontEffectSubscript primitives.FontEffectType = "subscript" -) diff --git a/format/styles/font_test.go b/format/styles/font_test.go index da45b5b..63a5380 100644 --- a/format/styles/font_test.go +++ b/format/styles/font_test.go @@ -7,6 +7,7 @@ package styles import ( "github.com/plandem/xlsx/internal/color" "github.com/plandem/xlsx/internal/ml" + "github.com/plandem/xlsx/internal/ml/primitives" "github.com/stretchr/testify/require" "testing" ) @@ -24,7 +25,7 @@ func TestFont(t *testing.T) { Font.Family(FontFamilyDecorative), Font.Color("#FF00FF"), Font.Underline(UnderlineTypeSingle), - Font.Effect(FontEffectBaseline), + Font.Superscript, Font.Scheme(FontSchemeMinor), ) @@ -42,7 +43,7 @@ func TestFont(t *testing.T) { Color: color.New("FFFF00FF"), Family: FontFamilyDecorative, Underline: UnderlineTypeSingle, - Effect: FontEffectBaseline, + Effect: primitives.FontEffectSuperscript, Scheme: FontSchemeMinor, } }), style) diff --git a/format/styles/styles_test.go b/format/styles/styles_test.go index 31dc028..22e4d7f 100644 --- a/format/styles/styles_test.go +++ b/format/styles/styles_test.go @@ -8,6 +8,7 @@ import ( "encoding/xml" "github.com/plandem/xlsx/internal/color" "github.com/plandem/xlsx/internal/ml" + "github.com/plandem/xlsx/internal/ml/primitives" "github.com/stretchr/testify/require" "testing" ) @@ -64,7 +65,7 @@ func TestStyleFormat_Settings(t *testing.T) { Font.Family(FontFamilyDecorative), Font.Color("#FF00FF"), Font.Underline(UnderlineTypeSingle), - Font.Effect(FontEffectBaseline), + Font.Superscript, Font.Scheme(FontSchemeMinor), NumberFormatID(8), Protection.Hidden, @@ -143,7 +144,7 @@ func TestStyleFormat_Settings(t *testing.T) { Color: color.New("FFFF00FF"), Family: FontFamilyDecorative, Underline: UnderlineTypeSingle, - Effect: FontEffectBaseline, + Effect: primitives.FontEffectSuperscript, Scheme: FontSchemeMinor, }, font) @@ -320,7 +321,7 @@ func TestStyleFormat_Settings_Font(t *testing.T) { Font.Family(FontFamilyDecorative), Font.Color("#FF00FF"), Font.Underline(UnderlineTypeSingle), - Font.Effect(FontEffectBaseline), + Font.Superscript, Font.Scheme(FontSchemeMinor), ) @@ -345,7 +346,7 @@ func TestStyleFormat_Settings_Font(t *testing.T) { Color: color.New("FFFF00FF"), Family: FontFamilyDecorative, Underline: UnderlineTypeSingle, - Effect: FontEffectBaseline, + Effect: primitives.FontEffectSuperscript, Scheme: FontSchemeMinor, }, font) } @@ -418,12 +419,12 @@ func TestFontMarshal(t *testing.T) { Font.Family(FontFamilyDecorative), Font.Color("#FF00FF"), Font.Underline(UnderlineTypeSingle), - Font.Effect(FontEffectBaseline), + Font.Superscript, Font.Scheme(FontSchemeMinor), )) encoded, _ = xml.Marshal(font) - require.Equal(t, ``, string(encoded)) + require.Equal(t, ``, string(encoded)) } func TestFillMarshal(t *testing.T) { diff --git a/internal/ml/hash_test.go b/internal/ml/hash_test.go index 320dd8a..4fcbe1b 100644 --- a/internal/ml/hash_test.go +++ b/internal/ml/hash_test.go @@ -8,6 +8,7 @@ import ( "github.com/plandem/ooxml/index" "github.com/plandem/xlsx/format/styles" "github.com/plandem/xlsx/internal/ml" + "github.com/plandem/xlsx/internal/ml/primitives" "github.com/stretchr/testify/require" "testing" ) @@ -183,11 +184,11 @@ func TestFont_Hash(t *testing.T) { require.Nil(t, idx.Add(&ml.Font{Color: &ml.Color{RGB: "112233"}}, 1)) require.Nil(t, idx.Add(&ml.Font{Size: 2.2}, 1)) require.Nil(t, idx.Add(&ml.Font{Underline: styles.UnderlineTypeDoubleAccounting}, 1)) - require.Nil(t, idx.Add(&ml.Font{Effect: styles.FontEffectSubscript}, 1)) + require.Nil(t, idx.Add(&ml.Font{Effect: primitives.FontEffectSubscript}, 1)) require.Nil(t, idx.Add(&ml.Font{Scheme: styles.FontSchemeMajor}, 1)) require.Nil(t, idx.Add(&ml.Font{ Scheme: styles.FontSchemeMajor, - Effect: styles.FontEffectSubscript, + Effect: primitives.FontEffectSubscript, Underline: styles.UnderlineTypeDoubleAccounting, Size: 2.2, Color: &ml.Color{RGB: "112233"}, @@ -298,7 +299,7 @@ func TestDiffStyle_Hash(t *testing.T) { require.Nil(t, idx.Add(&ml.DiffStyle{ Font: &ml.Font{ Scheme: styles.FontSchemeMajor, - Effect: styles.FontEffectSubscript, + Effect: primitives.FontEffectSubscript, Underline: styles.UnderlineTypeDoubleAccounting, Size: 2.2, Color: &ml.Color{RGB: "112233"}, diff --git a/internal/ml/primitives/font_valign.go b/internal/ml/primitives/font_effect.go similarity index 75% rename from internal/ml/primitives/font_valign.go rename to internal/ml/primitives/font_effect.go index 1b26ed3..fbbf0f9 100644 --- a/internal/ml/primitives/font_valign.go +++ b/internal/ml/primitives/font_effect.go @@ -12,6 +12,13 @@ import ( //FontEffectType is a type to encode XSD ST_VerticalAlignRun type FontEffectType ml.Property +//List of all possible values for FontEffectType +const ( + FontEffectBaseline FontEffectType = "baseline" + FontEffectSuperscript FontEffectType = "superscript" + FontEffectSubscript FontEffectType = "subscript" +) + //MarshalXML marshal FontEffectType func (t *FontEffectType) MarshalXML(e *xml.Encoder, start xml.StartElement) error { return (*ml.Property)(t).MarshalXML(e, start) diff --git a/internal/ml/primitives/font_valign_test.go b/internal/ml/primitives/font_effect_test.go similarity index 78% rename from internal/ml/primitives/font_valign_test.go rename to internal/ml/primitives/font_effect_test.go index ce12124..8ca5945 100644 --- a/internal/ml/primitives/font_valign_test.go +++ b/internal/ml/primitives/font_effect_test.go @@ -7,7 +7,6 @@ package primitives_test import ( "encoding/xml" "fmt" - "github.com/plandem/xlsx/format/styles" "github.com/plandem/xlsx/internal/ml/primitives" "github.com/stretchr/testify/require" "testing" @@ -19,9 +18,9 @@ func TestFontVAlign(t *testing.T) { } list := map[primitives.FontEffectType]string{ - styles.FontEffectBaseline: string(styles.FontEffectBaseline), - styles.FontEffectSuperscript: string(styles.FontEffectSuperscript), - styles.FontEffectSubscript: string(styles.FontEffectSubscript), + primitives.FontEffectBaseline: string(primitives.FontEffectBaseline), + primitives.FontEffectSuperscript: string(primitives.FontEffectSuperscript), + primitives.FontEffectSubscript: string(primitives.FontEffectSubscript), primitives.FontEffectType("align-a"): "align-a", } diff --git a/internal/number_format/indexed.go b/internal/number_format/indexed.go index 0a4bfd5..84319d8 100644 --- a/internal/number_format/indexed.go +++ b/internal/number_format/indexed.go @@ -25,7 +25,7 @@ func init() { } builtIn = map[int]*builtInFormat{ - 0x00: {ml.NumberFormat{ID: 0x00, Code: `@`}, General}, + 0x00: {ml.NumberFormat{ID: 0x00, Code: `General`}, General}, 0x01: {ml.NumberFormat{ID: 0x01, Code: `0`}, Integer}, 0x02: {ml.NumberFormat{ID: 0x02, Code: `0.00`}, Float}, 0x03: {ml.NumberFormat{ID: 0x03, Code: `#,##0`}, Float}, diff --git a/internal/number_format/types_test.go b/internal/number_format/types_test.go index 883907b..98d91c1 100644 --- a/internal/number_format/types_test.go +++ b/internal/number_format/types_test.go @@ -20,7 +20,7 @@ func TestNumberFormat(t *testing.T) { require.Equal(t, builtIn[0x00], Resolve(ml.NumberFormat{ID: 0, Code: "0.00"})) //built-in ID was provided, ignore custom CODE and return general code/type - unknownBuiltIn := &builtInFormat{ml.NumberFormat{ID: 162, Code: "@"}, General} + unknownBuiltIn := &builtInFormat{ml.NumberFormat{ID: 162, Code: "General"}, General} require.Equal(t, unknownBuiltIn, Resolve(ml.NumberFormat(ml.NumberFormat{ID: 162, Code: "abcd"}))) //built-in CODE was provided, ignore custom ID @@ -30,13 +30,10 @@ func TestNumberFormat(t *testing.T) { require.Nil(t, Resolve(ml.NumberFormat{ID: 1000, Code: "abcde"})) //built-in ID was provided, ignore custom CODE - require.Equal(t, ml.NumberFormat(ml.NumberFormat{ID: 0, Code: "@"}), New(0, "abcd")) - - //built-in ID was provided, ignore custom CODE - require.Equal(t, ml.NumberFormat(ml.NumberFormat{ID: 0, Code: "@"}), New(0, "abcd")) + require.Equal(t, ml.NumberFormat(ml.NumberFormat{ID: 0, Code: "General"}), New(0, "abcd")) //built-in ID was provided, ignore built-in CODE - require.Equal(t, ml.NumberFormat(ml.NumberFormat{ID: 0, Code: "@"}), New(0, "0.00")) + require.Equal(t, ml.NumberFormat(ml.NumberFormat{ID: 0, Code: "General"}), New(0, "0.00")) //built-in CODE was provided, ignore custom ID require.Equal(t, ml.NumberFormat(ml.NumberFormat{ID: 2, Code: "0.00"}), New(1000, "0.00")) diff --git a/rich_text.go b/rich_text.go index f5fcd7e..62cc02f 100644 --- a/rich_text.go +++ b/rich_text.go @@ -19,6 +19,7 @@ import ( //go:linkname toRichFont github.com/plandem/xlsx/format/styles.toRichFont func toRichFont(f *styles.Info) *ml.RichFont +//nolint func toRichText(parts ...interface{}) (*ml.StringItem, *styles.Info, error) { si := &ml.StringItem{} length := 0 diff --git a/row.go b/row.go index 5b4849c..dc2fd12 100644 --- a/row.go +++ b/row.go @@ -28,6 +28,10 @@ func (r *Row) SetOptions(o *options.Info) { r.ml.CustomHeight = true } + if o.Format != nil { + r.SetStyles(o.Format) + } + r.ml.OutlineLevel = o.OutlineLevel r.ml.Hidden = o.Hidden r.ml.Collapsed = o.Collapsed @@ -40,9 +44,9 @@ func (r *Row) Styles() styles.DirectStyleID { } //SetStyles sets default style for the row. Affects cells not yet allocated in the row. In other words, this style applies to new cells. -func (r *Row) SetStyles(styleID styles.DirectStyleID) { +func (r *Row) SetStyles(s interface{}) { r.ml.CustomFormat = true - r.ml.Style = styleID + r.ml.Style = r.sheet.info().resolveStyleID(s) } //CopyTo copies row cells into another row with rIdx index. diff --git a/sheet_info.go b/sheet_info.go index a5b5488..3ace4e1 100644 --- a/sheet_info.go +++ b/sheet_info.go @@ -10,6 +10,7 @@ import ( "github.com/plandem/ooxml" sharedML "github.com/plandem/ooxml/ml" "github.com/plandem/xlsx/format/conditional" + "github.com/plandem/xlsx/format/styles" "github.com/plandem/xlsx/internal" "github.com/plandem/xlsx/internal/ml" "github.com/plandem/xlsx/types" @@ -288,3 +289,29 @@ func (s *sheetInfo) AfterMarshalXML(content []byte) []byte { return content } + +func (s *sheetInfo) resolveStyleID(st interface{}) styles.DirectStyleID { + if st == nil { + return 0 + } + + if styleID, ok := st.(styles.DirectStyleID); ok { + return styleID + } + + //we can update styleSheet only when sheet is in write mode, to prevent pollution of styleSheet with fake values + if (s.mode() & sheetModeWrite) == 0 { + panic(errorNotSupportedWrite) + } + + var format *styles.Info + if f, ok := st.(styles.Info); ok { + format = &f + } else if f, ok := st.(*styles.Info); ok { + format = f + } else { + panic("only DirectStyleID or styles.Info supported as styles for cell") + } + + return s.workbook.doc.styleSheet.addStyle(format) +} diff --git a/spreadsheet.go b/spreadsheet.go index 53cb8b9..a83f9db 100644 --- a/spreadsheet.go +++ b/spreadsheet.go @@ -121,13 +121,13 @@ func (xl *Spreadsheet) AddSheet(name string, options ...sheetMode) Sheet { si.sheetMode = mode sheet.afterCreate(name) return sheet - } else { - sheet := &sheetReadWrite{si} - si.sheet = sheet - si.sheetMode = mode | sheetModeRead - sheet.afterCreate(name) - return sheet } + + sheet := &sheetReadWrite{si} + si.sheet = sheet + si.sheetMode = mode | sheetModeRead + sheet.afterCreate(name) + return sheet } return nil diff --git a/types/options/column/col.go b/types/options/column/col.go index a977c98..762a702 100644 --- a/types/options/column/col.go +++ b/types/options/column/col.go @@ -12,6 +12,7 @@ type Info struct { Phonetic bool Hidden bool Width float32 + Format interface{} } //Option is helper type to set options for comment @@ -67,3 +68,10 @@ func Width(width float32) Option { i.Width = width } } + +//Styles sets style format to requested DirectStyleID or styles.Info +func Styles(s interface{}) Option { + return func(i *Info) { + i.Format = s + } +} diff --git a/types/options/column/col_test.go b/types/options/column/col_test.go index a60cd28..8667d3e 100644 --- a/types/options/column/col_test.go +++ b/types/options/column/col_test.go @@ -5,6 +5,7 @@ package options import ( + "github.com/plandem/xlsx/format/styles" "github.com/stretchr/testify/require" "testing" ) @@ -16,6 +17,7 @@ func TestColumnOptions(t *testing.T) { Phonetic(true), Width(45.5), Collapsed(true), + Styles(styles.DirectStyleID(1)), ) require.IsType(t, &Info{}, o) @@ -25,6 +27,7 @@ func TestColumnOptions(t *testing.T) { Phonetic: true, Width: 45.5, Collapsed: true, + Format: styles.DirectStyleID(1), }, o) o = New( diff --git a/types/options/row/row.go b/types/options/row/row.go index 50ce15a..0a6b97b 100644 --- a/types/options/row/row.go +++ b/types/options/row/row.go @@ -12,6 +12,7 @@ type Info struct { Phonetic bool Hidden bool Height float32 + Format interface{} } //Option is helper type to set options for row @@ -67,3 +68,10 @@ func Height(height float32) Option { i.Height = height } } + +//Styles sets style format to requested DirectStyleID or styles.Info +func Styles(s interface{}) Option { + return func(i *Info) { + i.Format = s + } +} diff --git a/types/options/row/row_test.go b/types/options/row/row_test.go index 3b65312..2b4bda9 100644 --- a/types/options/row/row_test.go +++ b/types/options/row/row_test.go @@ -5,6 +5,7 @@ package options import ( + "github.com/plandem/xlsx/format/styles" "github.com/stretchr/testify/require" "testing" ) @@ -16,6 +17,7 @@ func TestRowOptions(t *testing.T) { Phonetic(true), Height(45.5), Collapsed(true), + Styles(styles.DirectStyleID(1)), ) require.IsType(t, &Info{}, o) @@ -25,6 +27,7 @@ func TestRowOptions(t *testing.T) { Phonetic: true, Height: 45.5, Collapsed: true, + Format: styles.DirectStyleID(1), }, o) o = New(