Skip to content

Commit 3ece904

Browse files
authored
This closes qax-os#1369, support set, and get font color with theme and tint (qax-os#1370)
1 parent 3d02726 commit 3ece904

8 files changed

+67
-35
lines changed

cell.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,10 @@ func getCellRichText(si *xlsxSI) (runs []RichTextRun) {
823823
font.Strike = v.RPr.Strike != nil
824824
if v.RPr.Color != nil {
825825
font.Color = strings.TrimPrefix(v.RPr.Color.RGB, "FF")
826+
if v.RPr.Color.Theme != nil {
827+
font.ColorTheme = v.RPr.Color.Theme
828+
}
829+
font.ColorTint = v.RPr.Color.Tint
826830
}
827831
run.Font = &font
828832
}
@@ -879,9 +883,7 @@ func newRpr(fnt *Font) *xlsxRPr {
879883
if fnt.Size > 0 {
880884
rpr.Sz = &attrValFloat{Val: &fnt.Size}
881885
}
882-
if fnt.Color != "" {
883-
rpr.Color = &xlsxColor{RGB: getPaletteColor(fnt.Color)}
884-
}
886+
rpr.Color = newFontColor(fnt)
885887
return &rpr
886888
}
887889

cell_test.go

+14-8
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ func TestSetCellFormula(t *testing.T) {
518518
}
519519

520520
func TestGetCellRichText(t *testing.T) {
521-
f := NewFile()
521+
f, theme := NewFile(), 1
522522

523523
runsSource := []RichTextRun{
524524
{
@@ -527,13 +527,15 @@ func TestGetCellRichText(t *testing.T) {
527527
{
528528
Text: "b",
529529
Font: &Font{
530-
Underline: "single",
531-
Color: "ff0000",
532-
Bold: true,
533-
Italic: true,
534-
Family: "Times New Roman",
535-
Size: 100,
536-
Strike: true,
530+
Underline: "single",
531+
Color: "ff0000",
532+
ColorTheme: &theme,
533+
ColorTint: 0.5,
534+
Bold: true,
535+
Italic: true,
536+
Family: "Times New Roman",
537+
Size: 100,
538+
Strike: true,
537539
},
538540
},
539541
}
@@ -580,6 +582,10 @@ func TestGetCellRichText(t *testing.T) {
580582
// Test set cell rich text with illegal cell reference
581583
_, err = f.GetCellRichText("Sheet1", "A")
582584
assert.EqualError(t, err, newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
585+
// Test set rich text color theme without tint
586+
assert.NoError(t, f.SetCellRichText("Sheet1", "A1", []RichTextRun{{Font: &Font{ColorTheme: &theme}}}))
587+
// Test set rich text color tint without theme
588+
assert.NoError(t, f.SetCellRichText("Sheet1", "A1", []RichTextRun{{Font: &Font{ColorTint: 0.5}}}))
583589
}
584590

585591
func TestSetCellRichText(t *testing.T) {

chart.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ func parseChartOptions(opts string) (*chartOptions, error) {
702702
//
703703
// title
704704
//
705-
// name: Set the name (title) for the chart. The name is displayed above the chart. The name can also be a formula such as Sheet1!$A$1 or a list with a sheetname. The name property is optional. The default is to have no chart title.
705+
// name: Set the name (title) for the chart. The name is displayed above the chart. The name can also be a formula such as Sheet1!$A$1 or a list with a sheet name. The name property is optional. The default is to have no chart title.
706706
//
707707
// Specifies how blank cells are plotted on the chart by show_blanks_as. The default value is gap. The options that can be set are:
708708
//
@@ -750,18 +750,19 @@ func parseChartOptions(opts string) (*chartOptions, error) {
750750
// reverse_order
751751
// maximum
752752
// minimum
753-
// number_font
753+
// font
754754
//
755755
// The properties of y_axis that can be set are:
756756
//
757757
// none
758758
// major_grid_lines
759759
// minor_grid_lines
760+
// major_unit
760761
// tick_label_skip
761762
// reverse_order
762763
// maximum
763764
// minimum
764-
// number_font
765+
// font
765766
//
766767
// none: Disable axes.
767768
//
@@ -779,7 +780,7 @@ func parseChartOptions(opts string) (*chartOptions, error) {
779780
//
780781
// minimum: Specifies that the fixed minimum, 0 is auto. The minimum property is optional. The default value is auto.
781782
//
782-
// number_font: Specifies that the font of the horizontal and vertical axis. The properties of number_font that can be set are:
783+
// font: Specifies that the font of the horizontal and vertical axis. The properties of font that can be set are:
783784
//
784785
// bold
785786
// italic

chart_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ func TestAddChart(t *testing.T) {
116116
// Test add chart on not exists worksheet.
117117
assert.EqualError(t, f.AddChart("SheetN", "P1", "{}"), "sheet SheetN does not exist")
118118

119-
assert.NoError(t, f.AddChart("Sheet1", "P1", `{"type":"col","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"none":true,"show_legend_key":true},"title":{"name":"2D Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","x_axis":{"number_font":{"bold":true,"italic":true,"underline":"dbl","color":"#000000"}},"y_axis":{"number_font":{"bold":false,"italic":false,"underline":"sng","color":"#777777"}}}`))
119+
assert.NoError(t, f.AddChart("Sheet1", "P1", `{"type":"col","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"none":true,"show_legend_key":true},"title":{"name":"2D Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero","x_axis":{"font":{"bold":true,"italic":true,"underline":"dbl","color":"#000000"}},"y_axis":{"font":{"bold":false,"italic":false,"underline":"sng","color":"#777777"}}}`))
120120
assert.NoError(t, f.AddChart("Sheet1", "X1", `{"type":"colStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"2D Stacked Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
121121
assert.NoError(t, f.AddChart("Sheet1", "P16", `{"type":"colPercentStacked","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"left","show_legend_key":false},"title":{"name":"100% Stacked Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))
122122
assert.NoError(t, f.AddChart("Sheet1", "X16", `{"type":"col3DClustered","series":[{"name":"Sheet1!$A$30","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$30:$D$30"},{"name":"Sheet1!$A$31","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$31:$D$31"},{"name":"Sheet1!$A$32","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$32:$D$32"},{"name":"Sheet1!$A$33","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$33:$D$33"},{"name":"Sheet1!$A$34","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$34:$D$34"},{"name":"Sheet1!$A$35","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$35:$D$35"},{"name":"Sheet1!$A$36","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$36:$D$36"},{"name":"Sheet1!$A$37","categories":"Sheet1!$B$29:$D$29","values":"Sheet1!$B$37:$D$37"}],"format":{"x_scale":1.0,"y_scale":1.0,"x_offset":15,"y_offset":10,"print_obj":true,"lock_aspect_ratio":false,"locked":false},"legend":{"position":"bottom","show_legend_key":false},"title":{"name":"3D Clustered Column Chart"},"plotarea":{"show_bubble_size":true,"show_cat_name":false,"show_leader_lines":false,"show_percent":true,"show_series_name":true,"show_val":true},"show_blanks_as":"zero"}`))

drawing.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -1177,14 +1177,14 @@ func (f *File) drawPlotAreaTxPr(opts *chartAxisOptions) *cTxPr {
11771177
},
11781178
}
11791179
if opts != nil {
1180-
cTxPr.P.PPr.DefRPr.B = opts.NumFont.Bold
1181-
cTxPr.P.PPr.DefRPr.I = opts.NumFont.Italic
1182-
if idx := inStrSlice(supportedDrawingUnderlineTypes, opts.NumFont.Underline, true); idx != -1 {
1180+
cTxPr.P.PPr.DefRPr.B = opts.Font.Bold
1181+
cTxPr.P.PPr.DefRPr.I = opts.Font.Italic
1182+
if idx := inStrSlice(supportedDrawingUnderlineTypes, opts.Font.Underline, true); idx != -1 {
11831183
cTxPr.P.PPr.DefRPr.U = supportedDrawingUnderlineTypes[idx]
11841184
}
1185-
if opts.NumFont.Color != "" {
1185+
if opts.Font.Color != "" {
11861186
cTxPr.P.PPr.DefRPr.SolidFill.SchemeClr = nil
1187-
cTxPr.P.PPr.DefRPr.SolidFill.SrgbClr = &attrValString{Val: stringPtr(strings.ReplaceAll(strings.ToUpper(opts.NumFont.Color), "#", ""))}
1187+
cTxPr.P.PPr.DefRPr.SolidFill.SrgbClr = &attrValString{Val: stringPtr(strings.ReplaceAll(strings.ToUpper(opts.Font.Color), "#", ""))}
11881188
}
11891189
}
11901190
return cTxPr

styles.go

+25-4
Original file line numberDiff line numberDiff line change
@@ -2084,21 +2084,42 @@ func (f *File) getFontID(styleSheet *xlsxStyleSheet, style *Style) (fontID int)
20842084
return
20852085
}
20862086

2087+
// newFontColor set font color by given styles.
2088+
func newFontColor(font *Font) *xlsxColor {
2089+
var fontColor *xlsxColor
2090+
prepareFontColor := func() {
2091+
if fontColor != nil {
2092+
return
2093+
}
2094+
fontColor = &xlsxColor{}
2095+
}
2096+
if font.Color != "" {
2097+
prepareFontColor()
2098+
fontColor.RGB = getPaletteColor(font.Color)
2099+
}
2100+
if font.ColorTheme != nil {
2101+
prepareFontColor()
2102+
fontColor.Theme = font.ColorTheme
2103+
}
2104+
if font.ColorTint != 0 {
2105+
prepareFontColor()
2106+
fontColor.Tint = font.ColorTint
2107+
}
2108+
return fontColor
2109+
}
2110+
20872111
// newFont provides a function to add font style by given cell format
20882112
// settings.
20892113
func (f *File) newFont(style *Style) *xlsxFont {
20902114
if style.Font.Size < MinFontSize {
20912115
style.Font.Size = 11
20922116
}
2093-
if style.Font.Color == "" {
2094-
style.Font.Color = "#000000"
2095-
}
20962117
fnt := xlsxFont{
20972118
Sz: &attrValFloat{Val: float64Ptr(style.Font.Size)},
2098-
Color: &xlsxColor{RGB: getPaletteColor(style.Font.Color)},
20992119
Name: &attrValString{Val: stringPtr(style.Font.Family)},
21002120
Family: &attrValInt{Val: intPtr(2)},
21012121
}
2122+
fnt.Color = newFontColor(style.Font)
21022123
if style.Font.Bold {
21032124
fnt.B = &attrValBool{Val: &style.Font.Bold}
21042125
}

xmlChart.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ type cNumCache struct {
476476
PtCount *attrValInt `xml:"ptCount"`
477477
}
478478

479-
// cDLbls (Data Lables) directly maps the dLbls element. This element serves
479+
// cDLbls (Data Labels) directly maps the dLbls element. This element serves
480480
// as a root element that specifies the settings for the data labels for an
481481
// entire series or the entire chart. It contains child elements that specify
482482
// the specific formatting and positioning settings.
@@ -538,7 +538,7 @@ type chartAxisOptions struct {
538538
Maximum *float64 `json:"maximum"`
539539
Minimum *float64 `json:"minimum"`
540540
NumFormat string `json:"number_format"`
541-
NumFont Font `json:"number_font"`
541+
Font Font `json:"font"`
542542
LogBase float64 `json:"logbase"`
543543
NameLayout layoutOptions `json:"name_layout"`
544544
}

xmlStyles.go

+10-8
Original file line numberDiff line numberDiff line change
@@ -334,14 +334,16 @@ type Border struct {
334334

335335
// Font directly maps the font settings of the fonts.
336336
type Font struct {
337-
Bold bool `json:"bold"`
338-
Italic bool `json:"italic"`
339-
Underline string `json:"underline"`
340-
Family string `json:"family"`
341-
Size float64 `json:"size"`
342-
Strike bool `json:"strike"`
343-
Color string `json:"color"`
344-
VertAlign string `json:"vertAlign"`
337+
Bold bool `json:"bold"`
338+
Italic bool `json:"italic"`
339+
Underline string `json:"underline"`
340+
Family string `json:"family"`
341+
Size float64 `json:"size"`
342+
Strike bool `json:"strike"`
343+
Color string `json:"color"`
344+
ColorTheme *int `json:"color_theme"`
345+
ColorTint float64 `json:"color_tint"`
346+
VertAlign string `json:"vertAlign"`
345347
}
346348

347349
// Fill directly maps the fill settings of the cells.

0 commit comments

Comments
 (0)