summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chart.go19
-rw-r--r--chart_test.go2
-rw-r--r--drawing.go22
-rw-r--r--file.go4
-rw-r--r--shape.go28
-rw-r--r--styles.go18
-rw-r--r--table.go2
-rw-r--r--xmlChart.go45
-rw-r--r--xmlDrawing.go14
9 files changed, 78 insertions, 76 deletions
diff --git a/chart.go b/chart.go
index 0caa505..ce11b59 100644
--- a/chart.go
+++ b/chart.go
@@ -750,22 +750,24 @@ func parseChartOptions(opts string) (*chartOptions, error) {
// reverse_order
// maximum
// minimum
+// number_font
//
// The properties of y_axis that can be set are:
//
// none
// major_grid_lines
// minor_grid_lines
-// major_unit
+// tick_label_skip
// reverse_order
// maximum
// minimum
+// number_font
//
// none: Disable axes.
//
-// major_grid_lines: Specifies major gridlines.
+// major_grid_lines: Specifies major grid lines.
//
-// minor_grid_lines: Specifies minor gridlines.
+// minor_grid_lines: Specifies minor grid lines.
//
// major_unit: Specifies the distance between major ticks. Shall contain a positive floating-point number. The major_unit property is optional. The default value is auto.
//
@@ -777,6 +779,17 @@ func parseChartOptions(opts string) (*chartOptions, error) {
//
// minimum: Specifies that the fixed minimum, 0 is auto. The minimum property is optional. The default value is auto.
//
+// number_font: Specifies that the font of the horizontal and vertical axis. The properties of number_font that can be set are:
+//
+// bold
+// italic
+// underline
+// family
+// size
+// strike
+// color
+// vertAlign
+//
// Set chart size by dimension property. The dimension property is optional. The default width is 480, and height is 290.
//
// combo: Specifies the create a chart that combines two or more chart types
diff --git a/chart_test.go b/chart_test.go
index 3c80b39..a0f7156 100644
--- a/chart_test.go
+++ b/chart_test.go
@@ -116,7 +116,7 @@ func TestAddChart(t *testing.T) {
// Test add chart on not exists worksheet.
assert.EqualError(t, f.AddChart("SheetN", "P1", "{}"), "sheet SheetN does not exist")
- 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"}`))
+ 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"}}}`))
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"}`))
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"}`))
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"}`))
diff --git a/drawing.go b/drawing.go
index 2da2573..974d627 100644
--- a/drawing.go
+++ b/drawing.go
@@ -1017,7 +1017,7 @@ func (f *File) drawPlotAreaCatAx(opts *chartOptions) []*cAxs {
MinorTickMark: &attrValString{Val: stringPtr("none")},
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
SpPr: f.drawPlotAreaSpPr(),
- TxPr: f.drawPlotAreaTxPr(),
+ TxPr: f.drawPlotAreaTxPr(&opts.YAxis),
CrossAx: &attrValInt{Val: intPtr(753999904)},
Crosses: &attrValString{Val: stringPtr("autoZero")},
Auto: &attrValBool{Val: boolPtr(true)},
@@ -1071,7 +1071,7 @@ func (f *File) drawPlotAreaValAx(opts *chartOptions) []*cAxs {
MinorTickMark: &attrValString{Val: stringPtr("none")},
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
SpPr: f.drawPlotAreaSpPr(),
- TxPr: f.drawPlotAreaTxPr(),
+ TxPr: f.drawPlotAreaTxPr(&opts.XAxis),
CrossAx: &attrValInt{Val: intPtr(754001152)},
Crosses: &attrValString{Val: stringPtr("autoZero")},
CrossBetween: &attrValString{Val: stringPtr(chartValAxCrossBetween[opts.Type])},
@@ -1114,7 +1114,7 @@ func (f *File) drawPlotAreaSerAx(opts *chartOptions) []*cAxs {
AxPos: &attrValString{Val: stringPtr(catAxPos[opts.XAxis.ReverseOrder])},
TickLblPos: &attrValString{Val: stringPtr("nextTo")},
SpPr: f.drawPlotAreaSpPr(),
- TxPr: f.drawPlotAreaTxPr(),
+ TxPr: f.drawPlotAreaTxPr(nil),
CrossAx: &attrValInt{Val: intPtr(753999904)},
},
}
@@ -1140,8 +1140,8 @@ func (f *File) drawPlotAreaSpPr() *cSpPr {
}
// drawPlotAreaTxPr provides a function to draw the c:txPr element.
-func (f *File) drawPlotAreaTxPr() *cTxPr {
- return &cTxPr{
+func (f *File) drawPlotAreaTxPr(opts *chartAxisOptions) *cTxPr {
+ cTxPr := &cTxPr{
BodyPr: aBodyPr{
Rot: -60000000,
SpcFirstLastPara: true,
@@ -1176,6 +1176,18 @@ func (f *File) drawPlotAreaTxPr() *cTxPr {
EndParaRPr: &aEndParaRPr{Lang: "en-US"},
},
}
+ if opts != nil {
+ cTxPr.P.PPr.DefRPr.B = opts.NumFont.Bold
+ cTxPr.P.PPr.DefRPr.I = opts.NumFont.Italic
+ if idx := inStrSlice(supportedDrawingUnderlineTypes, opts.NumFont.Underline, true); idx != -1 {
+ cTxPr.P.PPr.DefRPr.U = supportedDrawingUnderlineTypes[idx]
+ }
+ if opts.NumFont.Color != "" {
+ cTxPr.P.PPr.DefRPr.SolidFill.SchemeClr = nil
+ cTxPr.P.PPr.DefRPr.SolidFill.SrgbClr = &attrValString{Val: stringPtr(strings.ReplaceAll(strings.ToUpper(opts.NumFont.Color), "#", ""))}
+ }
+ }
+ return cTxPr
}
// drawingParser provides a function to parse drawingXML. In order to solve
diff --git a/file.go b/file.go
index c83d17e..7ce536c 100644
--- a/file.go
+++ b/file.go
@@ -72,7 +72,7 @@ func (f *File) SaveAs(name string, opts ...Options) error {
return ErrMaxFilePathLength
}
f.Path = name
- if _, ok := supportedContentType[filepath.Ext(f.Path)]; !ok {
+ if _, ok := supportedContentTypes[filepath.Ext(f.Path)]; !ok {
return ErrWorkbookFileFormat
}
file, err := os.OpenFile(filepath.Clean(name), os.O_WRONLY|os.O_TRUNC|os.O_CREATE, os.ModePerm)
@@ -112,7 +112,7 @@ func (f *File) WriteTo(w io.Writer, opts ...Options) (int64, error) {
f.options = &opts[i]
}
if len(f.Path) != 0 {
- contentType, ok := supportedContentType[filepath.Ext(f.Path)]
+ contentType, ok := supportedContentTypes[filepath.Ext(f.Path)]
if !ok {
return 0, ErrWorkbookFileFormat
}
diff --git a/shape.go b/shape.go
index eca354f..e3c6c8b 100644
--- a/shape.go
+++ b/shape.go
@@ -323,27 +323,6 @@ func (f *File) addDrawingShape(sheet, drawingXML, cell string, opts *shapeOption
colIdx := fromCol - 1
rowIdx := fromRow - 1
- textUnderlineType := map[string]bool{
- "none": true,
- "words": true,
- "sng": true,
- "dbl": true,
- "heavy": true,
- "dotted": true,
- "dottedHeavy": true,
- "dash": true,
- "dashHeavy": true,
- "dashLong": true,
- "dashLongHeavy": true,
- "dotDash": true,
- "dotDashHeavy": true,
- "dotDotDash": true,
- "dotDotDashHeavy": true,
- "wavy": true,
- "wavyHeavy": true,
- "wavyDbl": true,
- }
-
width := int(float64(opts.Width) * opts.Format.XScale)
height := int(float64(opts.Height) * opts.Format.YScale)
@@ -422,10 +401,9 @@ func (f *File) addDrawingShape(sheet, drawingXML, cell string, opts *shapeOption
}
}
for _, p := range opts.Paragraph {
- u := p.Font.Underline
- _, ok := textUnderlineType[u]
- if !ok {
- u = "none"
+ u := "none"
+ if idx := inStrSlice(supportedDrawingUnderlineTypes, p.Font.Underline, true); idx != -1 {
+ u = supportedDrawingUnderlineTypes[idx]
}
text := p.Text
if text == "" {
diff --git a/styles.go b/styles.go
index 5299fbd..dc34427 100644
--- a/styles.go
+++ b/styles.go
@@ -2087,7 +2087,6 @@ func (f *File) getFontID(styleSheet *xlsxStyleSheet, style *Style) (fontID int)
// newFont provides a function to add font style by given cell format
// settings.
func (f *File) newFont(style *Style) *xlsxFont {
- fontUnderlineType := map[string]string{"single": "single", "double": "double"}
if style.Font.Size < MinFontSize {
style.Font.Size = 11
}
@@ -2112,9 +2111,8 @@ func (f *File) newFont(style *Style) *xlsxFont {
if style.Font.Strike {
fnt.Strike = &attrValBool{Val: &style.Font.Strike}
}
- val, ok := fontUnderlineType[style.Font.Underline]
- if ok {
- fnt.U = &attrValString{Val: stringPtr(val)}
+ if idx := inStrSlice(supportedUnderlineTypes, style.Font.Underline, true); idx != -1 {
+ fnt.U = &attrValString{Val: stringPtr(supportedUnderlineTypes[idx])}
}
return &fnt
}
@@ -3100,13 +3098,10 @@ func drawCondFmtCellIs(p int, ct string, format *conditionalOptions) *xlsxCfRule
DxfID: &format.Format,
}
// "between" and "not between" criteria require 2 values.
- _, ok := map[string]bool{"between": true, "notBetween": true}[ct]
- if ok {
- c.Formula = append(c.Formula, format.Minimum)
- c.Formula = append(c.Formula, format.Maximum)
+ if ct == "between" || ct == "notBetween" {
+ c.Formula = append(c.Formula, []string{format.Minimum, format.Maximum}...)
}
- _, ok = map[string]bool{"equal": true, "notEqual": true, "greaterThan": true, "lessThan": true, "greaterThanOrEqual": true, "lessThanOrEqual": true, "containsText": true, "notContains": true, "beginsWith": true, "endsWith": true}[ct]
- if ok {
+ if idx := inStrSlice([]string{"equal", "notEqual", "greaterThan", "lessThan", "greaterThanOrEqual", "lessThanOrEqual", "containsText", "notContains", "beginsWith", "endsWith"}, ct, true); idx != -1 {
c.Formula = append(c.Formula, format.Value)
}
return c
@@ -3124,8 +3119,7 @@ func drawCondFmtTop10(p int, ct string, format *conditionalOptions) *xlsxCfRule
DxfID: &format.Format,
Percent: format.Percent,
}
- rank, err := strconv.Atoi(format.Value)
- if err == nil {
+ if rank, err := strconv.Atoi(format.Value); err == nil {
c.Rank = rank
}
return c
diff --git a/table.go b/table.go
index f7cac20..112882c 100644
--- a/table.go
+++ b/table.go
@@ -516,7 +516,7 @@ func (f *File) parseFilterTokens(expression string, tokens []string) ([]int, str
}
}
}
- // if the string token contains an Excel match character then change the
+ // If the string token contains an Excel match character then change the
// operator type to indicate a non "simple" equality.
re, _ = regexp.Match("[*?]", []byte(token))
if operator == 2 && re {
diff --git a/xmlChart.go b/xmlChart.go
index 9024770..27a790e 100644
--- a/xmlChart.go
+++ b/xmlChart.go
@@ -521,31 +521,26 @@ type cPageMargins struct {
// chartAxisOptions directly maps the format settings of the chart axis.
type chartAxisOptions struct {
- None bool `json:"none"`
- Crossing string `json:"crossing"`
- MajorGridlines bool `json:"major_grid_lines"`
- MinorGridlines bool `json:"minor_grid_lines"`
- MajorTickMark string `json:"major_tick_mark"`
- MinorTickMark string `json:"minor_tick_mark"`
- MinorUnitType string `json:"minor_unit_type"`
- MajorUnit float64 `json:"major_unit"`
- MajorUnitType string `json:"major_unit_type"`
- TickLabelSkip int `json:"tick_label_skip"`
- DisplayUnits string `json:"display_units"`
- DisplayUnitsVisible bool `json:"display_units_visible"`
- DateAxis bool `json:"date_axis"`
- ReverseOrder bool `json:"reverse_order"`
- Maximum *float64 `json:"maximum"`
- Minimum *float64 `json:"minimum"`
- NumFormat string `json:"num_format"`
- NumFont struct {
- Color string `json:"color"`
- Bold bool `json:"bold"`
- Italic bool `json:"italic"`
- Underline bool `json:"underline"`
- } `json:"num_font"`
- LogBase float64 `json:"logbase"`
- NameLayout layoutOptions `json:"name_layout"`
+ None bool `json:"none"`
+ Crossing string `json:"crossing"`
+ MajorGridlines bool `json:"major_grid_lines"`
+ MinorGridlines bool `json:"minor_grid_lines"`
+ MajorTickMark string `json:"major_tick_mark"`
+ MinorTickMark string `json:"minor_tick_mark"`
+ MinorUnitType string `json:"minor_unit_type"`
+ MajorUnit float64 `json:"major_unit"`
+ MajorUnitType string `json:"major_unit_type"`
+ TickLabelSkip int `json:"tick_label_skip"`
+ DisplayUnits string `json:"display_units"`
+ DisplayUnitsVisible bool `json:"display_units_visible"`
+ DateAxis bool `json:"date_axis"`
+ ReverseOrder bool `json:"reverse_order"`
+ Maximum *float64 `json:"maximum"`
+ Minimum *float64 `json:"minimum"`
+ NumFormat string `json:"number_format"`
+ NumFont Font `json:"number_font"`
+ LogBase float64 `json:"logbase"`
+ NameLayout layoutOptions `json:"name_layout"`
}
// chartDimensionOptions directly maps the dimension of the chart.
diff --git a/xmlDrawing.go b/xmlDrawing.go
index 6a2f79d..b52e449 100644
--- a/xmlDrawing.go
+++ b/xmlDrawing.go
@@ -144,8 +144,8 @@ const (
// supportedImageTypes defined supported image types.
var supportedImageTypes = map[string]string{".gif": ".gif", ".jpg": ".jpeg", ".jpeg": ".jpeg", ".png": ".png", ".tif": ".tiff", ".tiff": ".tiff", ".emf": ".emf", ".wmf": ".wmf", ".emz": ".emz", ".wmz": ".wmz"}
-// supportedContentType defined supported file format types.
-var supportedContentType = map[string]string{
+// supportedContentTypes defined supported file format types.
+var supportedContentTypes = map[string]string{
".xlam": ContentTypeAddinMacro,
".xlsm": ContentTypeMacro,
".xlsx": ContentTypeSheetML,
@@ -153,6 +153,16 @@ var supportedContentType = map[string]string{
".xltx": ContentTypeTemplate,
}
+// supportedUnderlineTypes defined supported underline types.
+var supportedUnderlineTypes = []string{"none", "single", "double"}
+
+// supportedDrawingUnderlineTypes defined supported underline types in drawing
+// markup language.
+var supportedDrawingUnderlineTypes = []string{
+ "none", "words", "sng", "dbl", "heavy", "dotted", "dottedHeavy", "dash", "dashHeavy", "dashLong", "dashLongHeavy", "dotDash", "dotDashHeavy", "dotDotDash", "dotDotDashHeavy", "wavy", "wavyHeavy",
+ "wavyDbl",
+}
+
// xlsxCNvPr directly maps the cNvPr (Non-Visual Drawing Properties). This
// element specifies non-visual canvas properties. This allows for additional
// information that does not affect the appearance of the picture to be stored.