This fixed worksheet protection issue

- Update example code in the documentation
- Update unit tests
- Rename `PictureOptions` to `GraphicOptions`
- Adjust partial options fields data types for the `PictureOptions` and `Shape` structure
- Update dependencies module
This commit is contained in:
xuri 2023-01-02 11:47:31 +08:00
parent f58dabd492
commit b39626fae9
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
65 changed files with 498 additions and 378 deletions

View File

@ -1,6 +1,6 @@
BSD 3-Clause License BSD 3-Clause License
Copyright (c) 2016-2022 The excelize Authors. Copyright (c) 2016-2023 The excelize Authors.
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

View File

@ -44,8 +44,17 @@ import (
func main() { func main() {
f := excelize.NewFile() f := excelize.NewFile()
defer func() {
if err := f.Close(); err != nil {
fmt.Println(err)
}
}()
// Create a new sheet. // Create a new sheet.
index := f.NewSheet("Sheet2") index, err := f.NewSheet("Sheet2")
if err != nil {
fmt.Println(err)
return
}
// Set value of a cell. // Set value of a cell.
f.SetCellValue("Sheet2", "A2", "Hello world.") f.SetCellValue("Sheet2", "A2", "Hello world.")
f.SetCellValue("Sheet1", "B2", 100) f.SetCellValue("Sheet1", "B2", 100)
@ -122,6 +131,11 @@ import (
func main() { func main() {
f := excelize.NewFile() f := excelize.NewFile()
defer func() {
if err := f.Close(); err != nil {
fmt.Println(err)
}
}()
for idx, row := range [][]interface{}{ for idx, row := range [][]interface{}{
{nil, "Apple", "Orange", "Pear"}, {"Small", 2, 3, 3}, {nil, "Apple", "Orange", "Pear"}, {"Small", 2, 3, 3},
{"Normal", 5, 2, 4}, {"Large", 6, 7, 8}, {"Normal", 5, 2, 4}, {"Large", 6, 7, 8},
@ -196,14 +210,14 @@ func main() {
fmt.Println(err) fmt.Println(err)
} }
// Insert a picture to worksheet with scaling. // Insert a picture to worksheet with scaling.
enable, disable, scale := true, false, 0.5
if err := f.AddPicture("Sheet1", "D2", "image.jpg", if err := f.AddPicture("Sheet1", "D2", "image.jpg",
&excelize.PictureOptions{XScale: &scale, YScale: &scale}); err != nil { &excelize.GraphicOptions{ScaleX: 0.5, ScaleY: 0.5}); err != nil {
fmt.Println(err) fmt.Println(err)
} }
// Insert a picture offset in the cell with printing support. // Insert a picture offset in the cell with printing support.
enable, disable := true, false
if err := f.AddPicture("Sheet1", "H2", "image.gif", if err := f.AddPicture("Sheet1", "H2", "image.gif",
&excelize.PictureOptions{ &excelize.GraphicOptions{
PrintObject: &enable, PrintObject: &enable,
LockAspectRatio: false, LockAspectRatio: false,
OffsetX: 15, OffsetX: 15,

View File

@ -44,8 +44,17 @@ import (
func main() { func main() {
f := excelize.NewFile() f := excelize.NewFile()
defer func() {
if err := f.Close(); err != nil {
fmt.Println(err)
}
}()
// 创建一个工作表 // 创建一个工作表
index := f.NewSheet("Sheet2") index, err := f.NewSheet("Sheet2")
if err != nil {
fmt.Println(err)
return
}
// 设置单元格的值 // 设置单元格的值
f.SetCellValue("Sheet2", "A2", "Hello world.") f.SetCellValue("Sheet2", "A2", "Hello world.")
f.SetCellValue("Sheet1", "B2", 100) f.SetCellValue("Sheet1", "B2", 100)
@ -122,6 +131,11 @@ import (
func main() { func main() {
f := excelize.NewFile() f := excelize.NewFile()
defer func() {
if err := f.Close(); err != nil {
fmt.Println(err)
}
}()
for idx, row := range [][]interface{}{ for idx, row := range [][]interface{}{
{nil, "Apple", "Orange", "Pear"}, {"Small", 2, 3, 3}, {nil, "Apple", "Orange", "Pear"}, {"Small", 2, 3, 3},
{"Normal", 5, 2, 4}, {"Large", 6, 7, 8}, {"Normal", 5, 2, 4}, {"Large", 6, 7, 8},
@ -196,14 +210,14 @@ func main() {
fmt.Println(err) fmt.Println(err)
} }
// 在工作表中插入图片,并设置图片的缩放比例 // 在工作表中插入图片,并设置图片的缩放比例
enable, disable, scale := true, false, 0.5
if err := f.AddPicture("Sheet1", "D2", "image.jpg", if err := f.AddPicture("Sheet1", "D2", "image.jpg",
&excelize.PictureOptions{XScale: &scale, YScale: &scale}); err != nil { &excelize.GraphicOptions{ScaleX: 0.5, ScaleY: 0.5}); err != nil {
fmt.Println(err) fmt.Println(err)
} }
// 在工作表中插入图片,并设置图片的打印属性 // 在工作表中插入图片,并设置图片的打印属性
enable, disable := true, false
if err := f.AddPicture("Sheet1", "H2", "image.gif", if err := f.AddPicture("Sheet1", "H2", "image.gif",
&excelize.PictureOptions{ &excelize.GraphicOptions{
PrintObject: &enable, PrintObject: &enable,
LockAspectRatio: false, LockAspectRatio: false,
OffsetX: 15, OffsetX: 15,

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

42
cell.go
View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -679,6 +679,11 @@ type FormulaOpts struct {
// //
// func main() { // func main() {
// f := excelize.NewFile() // f := excelize.NewFile()
// defer func() {
// if err := f.Close(); err != nil {
// fmt.Println(err)
// }
// }()
// for idx, row := range [][]interface{}{{"A", "B", "C"}, {1, 2}} { // for idx, row := range [][]interface{}{{"A", "B", "C"}, {1, 2}} {
// if err := f.SetSheetRow("Sheet1", fmt.Sprintf("A%d", idx+1), &row); err != nil { // if err := f.SetSheetRow("Sheet1", fmt.Sprintf("A%d", idx+1), &row); err != nil {
// fmt.Println(err) // fmt.Println(err)
@ -1044,6 +1049,11 @@ func setRichText(runs []RichTextRun) ([]xlsxR, error) {
// //
// func main() { // func main() {
// f := excelize.NewFile() // f := excelize.NewFile()
// defer func() {
// if err := f.Close(); err != nil {
// fmt.Println(err)
// }
// }()
// if err := f.SetRowHeight("Sheet1", 1, 35); err != nil { // if err := f.SetRowHeight("Sheet1", 1, 35); err != nil {
// fmt.Println(err) // fmt.Println(err)
// return // return
@ -1395,39 +1405,39 @@ func (f *File) mergeCellsParser(ws *xlsxWorksheet, cell string) (string, error)
// checkCellInRangeRef provides a function to determine if a given cell reference // checkCellInRangeRef provides a function to determine if a given cell reference
// in a range. // in a range.
func (f *File) checkCellInRangeRef(cell, reference string) (bool, error) { func (f *File) checkCellInRangeRef(cell, rangeRef string) (bool, error) {
col, row, err := CellNameToCoordinates(cell) col, row, err := CellNameToCoordinates(cell)
if err != nil { if err != nil {
return false, err return false, err
} }
if rng := strings.Split(reference, ":"); len(rng) != 2 { if rng := strings.Split(rangeRef, ":"); len(rng) != 2 {
return false, err return false, err
} }
coordinates, err := rangeRefToCoordinates(reference) coordinates, err := rangeRefToCoordinates(rangeRef)
if err != nil { if err != nil {
return false, err return false, err
} }
return cellInRef([]int{col, row}, coordinates), err return cellInRange([]int{col, row}, coordinates), err
} }
// cellInRef provides a function to determine if a given range is within a // cellInRange provides a function to determine if a given range is within a
// range. // range.
func cellInRef(cell, ref []int) bool { func cellInRange(cell, ref []int) bool {
return cell[0] >= ref[0] && cell[0] <= ref[2] && cell[1] >= ref[1] && cell[1] <= ref[3] return cell[0] >= ref[0] && cell[0] <= ref[2] && cell[1] >= ref[1] && cell[1] <= ref[3]
} }
// isOverlap find if the given two rectangles overlap or not. // isOverlap find if the given two rectangles overlap or not.
func isOverlap(rect1, rect2 []int) bool { func isOverlap(rect1, rect2 []int) bool {
return cellInRef([]int{rect1[0], rect1[1]}, rect2) || return cellInRange([]int{rect1[0], rect1[1]}, rect2) ||
cellInRef([]int{rect1[2], rect1[1]}, rect2) || cellInRange([]int{rect1[2], rect1[1]}, rect2) ||
cellInRef([]int{rect1[0], rect1[3]}, rect2) || cellInRange([]int{rect1[0], rect1[3]}, rect2) ||
cellInRef([]int{rect1[2], rect1[3]}, rect2) || cellInRange([]int{rect1[2], rect1[3]}, rect2) ||
cellInRef([]int{rect2[0], rect2[1]}, rect1) || cellInRange([]int{rect2[0], rect2[1]}, rect1) ||
cellInRef([]int{rect2[2], rect2[1]}, rect1) || cellInRange([]int{rect2[2], rect2[1]}, rect1) ||
cellInRef([]int{rect2[0], rect2[3]}, rect1) || cellInRange([]int{rect2[0], rect2[3]}, rect1) ||
cellInRef([]int{rect2[2], rect2[3]}, rect1) cellInRange([]int{rect2[2], rect2[3]}, rect1)
} }
// parseSharedFormula generate dynamic part of shared formula for target cell // parseSharedFormula generate dynamic part of shared formula for target cell

View File

@ -43,7 +43,7 @@ func TestConcurrency(t *testing.T) {
assert.NoError(t, f.SetCellStyle("Sheet1", "A3", "A3", style)) assert.NoError(t, f.SetCellStyle("Sheet1", "A3", "A3", style))
// Concurrency add picture // Concurrency add picture
assert.NoError(t, f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"), assert.NoError(t, f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"),
&PictureOptions{ &GraphicOptions{
OffsetX: 10, OffsetX: 10,
OffsetY: 10, OffsetY: 10,
Hyperlink: "https://github.com/xuri/excelize", Hyperlink: "https://github.com/xuri/excelize",
@ -475,11 +475,20 @@ func TestGetCellFormula(t *testing.T) {
func ExampleFile_SetCellFloat() { func ExampleFile_SetCellFloat() {
f := NewFile() f := NewFile()
defer func() {
if err := f.Close(); err != nil {
fmt.Println(err)
}
}()
x := 3.14159265 x := 3.14159265
if err := f.SetCellFloat("Sheet1", "A1", x, 2, 64); err != nil { if err := f.SetCellFloat("Sheet1", "A1", x, 2, 64); err != nil {
fmt.Println(err) fmt.Println(err)
} }
val, _ := f.GetCellValue("Sheet1", "A1") val, err := f.GetCellValue("Sheet1", "A1")
if err != nil {
fmt.Println(err)
return
}
fmt.Println(val) fmt.Println(val)
// Output: 3.14 // Output: 3.14
} }

166
chart.go
View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -483,11 +483,11 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
if opts == nil { if opts == nil {
return nil, ErrParameterInvalid return nil, ErrParameterInvalid
} }
if opts.Dimension.Width == nil { if opts.Dimension.Width == 0 {
opts.Dimension.Width = intPtr(defaultChartDimensionWidth) opts.Dimension.Width = defaultChartDimensionWidth
} }
if opts.Dimension.Height == nil { if opts.Dimension.Height == 0 {
opts.Dimension.Height = intPtr(defaultChartDimensionHeight) opts.Dimension.Height = defaultChartDimensionHeight
} }
if opts.Format.PrintObject == nil { if opts.Format.PrintObject == nil {
opts.Format.PrintObject = boolPtr(true) opts.Format.PrintObject = boolPtr(true)
@ -495,14 +495,14 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
if opts.Format.Locked == nil { if opts.Format.Locked == nil {
opts.Format.Locked = boolPtr(false) opts.Format.Locked = boolPtr(false)
} }
if opts.Format.XScale == nil { if opts.Format.ScaleX == 0 {
opts.Format.XScale = float64Ptr(defaultPictureScale) opts.Format.ScaleX = defaultPictureScale
} }
if opts.Format.YScale == nil { if opts.Format.ScaleY == 0 {
opts.Format.YScale = float64Ptr(defaultPictureScale) opts.Format.ScaleY = defaultPictureScale
} }
if opts.Legend.Position == nil { if opts.Legend.Position == "" {
opts.Legend.Position = stringPtr(defaultChartLegendPosition) opts.Legend.Position = defaultChartLegendPosition
} }
if opts.Title.Name == "" { if opts.Title.Name == "" {
opts.Title.Name = " " opts.Title.Name = " "
@ -531,6 +531,11 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// //
// func main() { // func main() {
// f := excelize.NewFile() // f := excelize.NewFile()
// defer func() {
// if err := f.Close(); err != nil {
// fmt.Println(err)
// }
// }()
// for idx, row := range [][]interface{}{ // for idx, row := range [][]interface{}{
// {nil, "Apple", "Orange", "Pear"}, {"Small", 2, 3, 3}, // {nil, "Apple", "Orange", "Pear"}, {"Small", 2, 3, 3},
// {"Normal", 5, 2, 4}, {"Large", 6, 7, 8}, // {"Normal", 5, 2, 4}, {"Large", 6, 7, 8},
@ -542,7 +547,6 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// } // }
// f.SetSheetRow("Sheet1", cell, &row) // f.SetSheetRow("Sheet1", cell, &row)
// } // }
// positionBottom := "bottom"
// if err := f.AddChart("Sheet1", "E1", &excelize.Chart{ // if err := f.AddChart("Sheet1", "E1", &excelize.Chart{
// Type: "col3DClustered", // Type: "col3DClustered",
// Series: []excelize.ChartSeries{ // Series: []excelize.ChartSeries{
@ -566,7 +570,7 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// Name: "Fruit 3D Clustered Column Chart", // Name: "Fruit 3D Clustered Column Chart",
// }, // },
// Legend: excelize.ChartLegend{ // Legend: excelize.ChartLegend{
// None: false, Position: &positionBottom, ShowLegendKey: false, // ShowLegendKey: false,
// }, // },
// PlotArea: excelize.ChartPlotArea{ // PlotArea: excelize.ChartPlotArea{
// ShowBubbleSize: true, // ShowBubbleSize: true,
@ -646,7 +650,8 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// bubble | bubble chart // bubble | bubble chart
// bubble3D | 3D bubble chart // bubble3D | 3D bubble chart
// //
// In Excel a chart series is a collection of information that defines which data is plotted such as values, axis labels and formatting. // In Excel a chart series is a collection of information that defines which
// data is plotted such as values, axis labels and formatting.
// //
// The series options that can be set are: // The series options that can be set are:
// //
@ -656,15 +661,29 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// Line // Line
// Marker // Marker
// //
// Name: Set the name for the series. The name is displayed in the chart legend and in the formula bar. The 'Name' property is optional and if it isn't supplied it will default to Series 1..n. The name can also be a formula such as Sheet1!$A$1 // Name: Set the name for the series. The name is displayed in the chart legend
// and in the formula bar. The 'Name' property is optional and if it isn't
// supplied it will default to Series 1..n. The name can also be a formula such
// as Sheet1!$A$1
// //
// Categories: This sets the chart category labels. The category is more or less the same as the X axis. In most chart types the 'Categories' property is optional and the chart will just assume a sequential series from 1..n. // Categories: This sets the chart category labels. The category is more or less
// the same as the X axis. In most chart types the 'Categories' property is
// optional and the chart will just assume a sequential series from 1..n.
// //
// Values: This is the most important property of a series and is the only mandatory option for every chart object. This option links the chart with the worksheet data that it displays. // Values: This is the most important property of a series and is the only
// mandatory option for every chart object. This option links the chart with
// the worksheet data that it displays.
// //
// Line: This sets the line format of the line chart. The 'Line' property is optional and if it isn't supplied it will default style. The options that can be set are width and color. The range of width is 0.25pt - 999pt. If the value of width is outside the range, the default width of the line is 2pt. The value for color should be represented in hex format (e.g., #000000 - #FFFFFF) // Line: This sets the line format of the line chart. The 'Line' property is
// optional and if it isn't supplied it will default style. The options that
// can be set are width and color. The range of width is 0.25pt - 999pt. If the
// value of width is outside the range, the default width of the line is 2pt.
// The value for color should be represented in hex format
// (e.g., #000000 - #FFFFFF)
// //
// Marker: This sets the marker of the line chart and scatter chart. The range of optional field 'size' is 2-72 (default value is 5). The enumeration value of optional field 'Symbol' are (default value is 'auto'): // Marker: This sets the marker of the line chart and scatter chart. The range
// of optional field 'Size' is 2-72 (default value is 5). The enumeration value
// of optional field 'Symbol' are (default value is 'auto'):
// //
// circle // circle
// dash // dash
@ -681,29 +700,33 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// //
// Set properties of the chart legend. The options that can be set are: // Set properties of the chart legend. The options that can be set are:
// //
// None
// Position // Position
// ShowLegendKey // ShowLegendKey
// //
// None: Specified if show the legend without overlapping the chart. The default value is 'false'. // Position: Set the position of the chart legend. The default legend position
// // is bottom. The available positions are:
// Position: Set the position of the chart legend. The default legend position is right. This parameter only takes effect when 'none' is false. The available positions are:
// //
// none
// top // top
// bottom // bottom
// left // left
// right // right
// top_right // top_right
// //
// ShowLegendKey: Set the legend keys shall be shown in data labels. The default value is false. // ShowLegendKey: Set the legend keys shall be shown in data labels. The default
// value is false.
// //
// Set properties of the chart title. The properties that can be set are: // Set properties of the chart title. The properties that can be set are:
// //
// Title // Title
// //
// 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. // 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.
// //
// Specifies how blank cells are plotted on the chart by ShowBlanksAs. The default value is gap. The options that can be set are: // Specifies how blank cells are plotted on the chart by 'ShowBlanksAs'. The
// default value is gap. The options that can be set are:
// //
// gap // gap
// span // span
@ -715,11 +738,14 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// //
// zero: Specifies that blank values shall be treated as zero. // zero: Specifies that blank values shall be treated as zero.
// //
// Specifies that each data marker in the series has a different color by VaryColors. The default value is true. // Specifies that each data marker in the series has a different color by
// 'VaryColors'. The default value is true.
// //
// Set chart offset, scale, aspect ratio setting and print settings by format, same as function AddPicture. // Set chart offset, scale, aspect ratio setting and print settings by format,
// same as function 'AddPicture'.
// //
// Set the position of the chart plot area by PlotArea. The properties that can be set are: // Set the position of the chart plot area by PlotArea. The properties that can
// be set are:
// //
// ShowBubbleSize // ShowBubbleSize
// ShowCatName // ShowCatName
@ -728,19 +754,26 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// ShowSerName // ShowSerName
// ShowVal // ShowVal
// //
// ShowBubbleSize: Specifies the bubble size shall be shown in a data label. The ShowBubbleSize property is optional. The default value is false. // ShowBubbleSize: Specifies the bubble size shall be shown in a data label. The
// 'ShowBubbleSize' property is optional. The default value is false.
// //
// ShowCatName: Specifies that the category name shall be shown in the data label. The ShowCatName property is optional. The default value is true. // ShowCatName: Specifies that the category name shall be shown in the data
// label. The 'ShowCatName' property is optional. The default value is true.
// //
// ShowLeaderLines: Specifies leader lines shall be shown for data labels. The ShowLeaderLines property is optional. The default value is false. // ShowLeaderLines: Specifies leader lines shall be shown for data labels. The
// 'ShowLeaderLines' property is optional. The default value is false.
// //
// ShowPercent: Specifies that the percentage shall be shown in a data label. The ShowPercent property is optional. The default value is false. // ShowPercent: Specifies that the percentage shall be shown in a data label.
// The 'ShowPercent' property is optional. The default value is false.
// //
// ShowSerName: Specifies that the series name shall be shown in a data label. The ShowSerName property is optional. The default value is false. // ShowSerName: Specifies that the series name shall be shown in a data label.
// The 'ShowSerName' property is optional. The default value is false.
// //
// ShowVal: Specifies that the value shall be shown in a data label. The ShowVal property is optional. The default value is false. // ShowVal: Specifies that the value shall be shown in a data label.
// The 'ShowVal' property is optional. The default value is false.
// //
// Set the primary horizontal and vertical axis options by XAxis and YAxis. The properties of XAxis that can be set are: // Set the primary horizontal and vertical axis options by 'XAxis' and 'YAxis'.
// The properties of XAxis that can be set are:
// //
// None // None
// MajorGridLines // MajorGridLines
@ -751,7 +784,7 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// Minimum // Minimum
// Font // Font
// //
// The properties of YAxis that can be set are: // The properties of 'YAxis' that can be set are:
// //
// None // None
// MajorGridLines // MajorGridLines
@ -769,17 +802,25 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// //
// MinorGridLines: Specifies minor grid lines. // MinorGridLines: Specifies minor grid lines.
// //
// MajorUnit: Specifies the distance between major ticks. Shall contain a positive floating-point number. The MajorUnit property is optional. The default value is auto. // MajorUnit: Specifies the distance between major ticks. Shall contain a
// positive floating-point number. The MajorUnit property is optional. The
// default value is auto.
// //
// TickLabelSkip: Specifies how many tick labels to skip between label that is drawn. The TickLabelSkip property is optional. The default value is auto. // TickLabelSkip: Specifies how many tick labels to skip between label that is
// drawn. The 'TickLabelSkip' property is optional. The default value is auto.
// //
// ReverseOrder: Specifies that the categories or values on reverse order (orientation of the chart). The ReverseOrder property is optional. The default value is false. // ReverseOrder: Specifies that the categories or values on reverse order
// (orientation of the chart). The ReverseOrder property is optional. The
// default value is false.
// //
// Maximum: Specifies that the fixed maximum, 0 is auto. The Maximum property is optional. The default value is auto. // Maximum: Specifies that the fixed maximum, 0 is auto. The 'Maximum' property
// is optional. The default value is auto.
// //
// Minimum: Specifies that the fixed minimum, 0 is auto. The Minimum property is optional. The default value is auto. // Minimum: Specifies that the fixed minimum, 0 is auto. The 'Minimum' property
// is optional. The default value is auto.
// //
// Font: Specifies that the font of the horizontal and vertical axis. The properties of font that can be set are: // Font: Specifies that the font of the horizontal and vertical axis. The
// properties of font that can be set are:
// //
// Bold // Bold
// Italic // Italic
@ -790,10 +831,11 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// Color // Color
// VertAlign // VertAlign
// //
// Set chart size by dimension property. The dimension property is optional. The default width is 480, and height is 290. // 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 // combo: Specifies the create a chart that combines two or more chart types in
// in a single chart. For example, create a clustered column - line chart with // a single chart. For example, create a clustered column - line chart with
// data Sheet1!$E$1:$L$15: // data Sheet1!$E$1:$L$15:
// //
// package main // package main
@ -806,6 +848,11 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// //
// func main() { // func main() {
// f := excelize.NewFile() // f := excelize.NewFile()
// defer func() {
// if err := f.Close(); err != nil {
// fmt.Println(err)
// }
// }()
// for idx, row := range [][]interface{}{ // for idx, row := range [][]interface{}{
// {nil, "Apple", "Orange", "Pear"}, {"Small", 2, 3, 3}, // {nil, "Apple", "Orange", "Pear"}, {"Small", 2, 3, 3},
// {"Normal", 5, 2, 4}, {"Large", 6, 7, 8}, // {"Normal", 5, 2, 4}, {"Large", 6, 7, 8},
@ -817,8 +864,7 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// } // }
// f.SetSheetRow("Sheet1", cell, &row) // f.SetSheetRow("Sheet1", cell, &row)
// } // }
// enable, disable, scale := true, false, 1.0 // enable, disable := true, false
// positionLeft, positionRight := "left", "right"
// if err := f.AddChart("Sheet1", "E1", &excelize.Chart{ // if err := f.AddChart("Sheet1", "E1", &excelize.Chart{
// Type: "col", // Type: "col",
// Series: []excelize.ChartSeries{ // Series: []excelize.ChartSeries{
@ -828,9 +874,9 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// Values: "Sheet1!$B$2:$D$2", // Values: "Sheet1!$B$2:$D$2",
// }, // },
// }, // },
// Format: excelize.Picture{ // Format: excelize.GraphicOptions{
// XScale: &scale, // ScaleX: 1,
// YScale: &scale, // ScaleY: 1,
// OffsetX: 15, // OffsetX: 15,
// OffsetY: 10, // OffsetY: 10,
// PrintObject: &enable, // PrintObject: &enable,
@ -841,10 +887,10 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// Name: "Clustered Column - Line Chart", // Name: "Clustered Column - Line Chart",
// }, // },
// Legend: excelize.ChartLegend{ // Legend: excelize.ChartLegend{
// Position: &positionLeft, ShowLegendKey: false, // Position: "left",
// ShowLegendKey: false,
// }, // },
// PlotArea: excelize.ChartPlotArea{ // PlotArea: excelize.ChartPlotArea{
// ShowBubbleSize: true,
// ShowCatName: false, // ShowCatName: false,
// ShowLeaderLines: false, // ShowLeaderLines: false,
// ShowPercent: true, // ShowPercent: true,
@ -863,9 +909,9 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// }, // },
// }, // },
// }, // },
// Format: excelize.Picture{ // Format: excelize.GraphicOptions{
// XScale: &scale, // ScaleX: 1,
// YScale: &scale, // ScaleY: 1,
// OffsetX: 15, // OffsetX: 15,
// OffsetY: 10, // OffsetY: 10,
// PrintObject: &enable, // PrintObject: &enable,
@ -873,10 +919,10 @@ func parseChartOptions(opts *Chart) (*Chart, error) {
// Locked: &disable, // Locked: &disable,
// }, // },
// Legend: excelize.ChartLegend{ // Legend: excelize.ChartLegend{
// Position: &positionRight, ShowLegendKey: false, // Position: "right",
// ShowLegendKey: false,
// }, // },
// PlotArea: excelize.ChartPlotArea{ // PlotArea: excelize.ChartPlotArea{
// ShowBubbleSize: true,
// ShowCatName: false, // ShowCatName: false,
// ShowLeaderLines: false, // ShowLeaderLines: false,
// ShowPercent: true, // ShowPercent: true,
@ -909,7 +955,7 @@ func (f *File) AddChart(sheet, cell string, chart *Chart, combo ...*Chart) error
drawingID, drawingXML = f.prepareDrawing(ws, drawingID, sheet, drawingXML) drawingID, drawingXML = f.prepareDrawing(ws, drawingID, sheet, drawingXML)
drawingRels := "xl/drawings/_rels/drawing" + strconv.Itoa(drawingID) + ".xml.rels" drawingRels := "xl/drawings/_rels/drawing" + strconv.Itoa(drawingID) + ".xml.rels"
drawingRID := f.addRels(drawingRels, SourceRelationshipChart, "../charts/chart"+strconv.Itoa(chartID)+".xml", "") drawingRID := f.addRels(drawingRels, SourceRelationshipChart, "../charts/chart"+strconv.Itoa(chartID)+".xml", "")
err = f.addDrawingChart(sheet, drawingXML, cell, *opts.Dimension.Width, *opts.Dimension.Height, drawingRID, &opts.Format) err = f.addDrawingChart(sheet, drawingXML, cell, int(opts.Dimension.Width), int(opts.Dimension.Height), drawingRID, &opts.Format)
if err != nil { if err != nil {
return err return err
} }

View File

@ -41,12 +41,11 @@ func TestChartSize(t *testing.T) {
assert.NoError(t, f.SetCellValue(sheet1, cell, v)) assert.NoError(t, f.SetCellValue(sheet1, cell, v))
} }
width, height := 640, 480
assert.NoError(t, f.AddChart("Sheet1", "E4", &Chart{ assert.NoError(t, f.AddChart("Sheet1", "E4", &Chart{
Type: "col3DClustered", Type: "col3DClustered",
Dimension: ChartDimension{ Dimension: ChartDimension{
Width: &width, Width: 640,
Height: &height, Height: 480,
}, },
Series: []ChartSeries{ Series: []ChartSeries{
{Name: "Sheet1!$A$2", Categories: "Sheet1!$B$1:$D$1", Values: "Sheet1!$B$2:$D$2"}, {Name: "Sheet1!$A$2", Categories: "Sheet1!$B$1:$D$1", Values: "Sheet1!$B$2:$D$2"},
@ -107,14 +106,14 @@ func TestAddDrawingChart(t *testing.T) {
path := "xl/drawings/drawing1.xml" path := "xl/drawings/drawing1.xml"
f.Pkg.Store(path, MacintoshCyrillicCharset) f.Pkg.Store(path, MacintoshCyrillicCharset)
assert.EqualError(t, f.addDrawingChart("Sheet1", path, "A1", 0, 0, 0, &PictureOptions{PrintObject: boolPtr(true), Locked: boolPtr(false), XScale: float64Ptr(defaultPictureScale), YScale: float64Ptr(defaultPictureScale)}), "XML syntax error on line 1: invalid UTF-8") assert.EqualError(t, f.addDrawingChart("Sheet1", path, "A1", 0, 0, 0, &GraphicOptions{PrintObject: boolPtr(true), Locked: boolPtr(false)}), "XML syntax error on line 1: invalid UTF-8")
} }
func TestAddSheetDrawingChart(t *testing.T) { func TestAddSheetDrawingChart(t *testing.T) {
f := NewFile() f := NewFile()
path := "xl/drawings/drawing1.xml" path := "xl/drawings/drawing1.xml"
f.Pkg.Store(path, MacintoshCyrillicCharset) f.Pkg.Store(path, MacintoshCyrillicCharset)
assert.EqualError(t, f.addSheetDrawingChart(path, 0, &PictureOptions{PrintObject: boolPtr(true), Locked: boolPtr(false), XScale: float64Ptr(defaultPictureScale), YScale: float64Ptr(defaultPictureScale)}), "XML syntax error on line 1: invalid UTF-8") assert.EqualError(t, f.addSheetDrawingChart(path, 0, &GraphicOptions{PrintObject: boolPtr(true), Locked: boolPtr(false)}), "XML syntax error on line 1: invalid UTF-8")
} }
func TestDeleteDrawing(t *testing.T) { func TestDeleteDrawing(t *testing.T) {
@ -142,7 +141,6 @@ func TestAddChart(t *testing.T) {
// Test add chart on not exists worksheet // Test add chart on not exists worksheet
assert.EqualError(t, f.AddChart("SheetN", "P1", nil), "sheet SheetN does not exist") assert.EqualError(t, f.AddChart("SheetN", "P1", nil), "sheet SheetN does not exist")
positionLeft, positionBottom, positionRight, positionTop, positionTopRight := "left", "bottom", "right", "top", "top_right"
maximum, minimum, zero := 7.5, 0.5, .0 maximum, minimum, zero := 7.5, 0.5, .0
series := []ChartSeries{ series := []ChartSeries{
{Name: "Sheet1!$A$30", Categories: "Sheet1!$B$29:$D$29", Values: "Sheet1!$B$30:$D$30"}, {Name: "Sheet1!$A$30", Categories: "Sheet1!$B$29:$D$29", Values: "Sheet1!$B$30:$D$30"},
@ -165,16 +163,16 @@ func TestAddChart(t *testing.T) {
{Name: "Sheet1!$A$37", Categories: "Sheet1!$B$29:$D$29", Values: "Sheet1!$B$37:$D$37", Line: ChartLine{Width: 0.25}}, {Name: "Sheet1!$A$37", Categories: "Sheet1!$B$29:$D$29", Values: "Sheet1!$B$37:$D$37", Line: ChartLine{Width: 0.25}},
} }
series3 := []ChartSeries{{Name: "Sheet1!$A$30", Categories: "Sheet1!$A$30:$D$37", Values: "Sheet1!$B$30:$B$37"}} series3 := []ChartSeries{{Name: "Sheet1!$A$30", Categories: "Sheet1!$A$30:$D$37", Values: "Sheet1!$B$30:$B$37"}}
format := PictureOptions{ format := GraphicOptions{
XScale: float64Ptr(defaultPictureScale), ScaleX: defaultPictureScale,
YScale: float64Ptr(defaultPictureScale), ScaleY: defaultPictureScale,
OffsetX: 15, OffsetX: 15,
OffsetY: 10, OffsetY: 10,
PrintObject: boolPtr(true), PrintObject: boolPtr(true),
LockAspectRatio: false, LockAspectRatio: false,
Locked: boolPtr(false), Locked: boolPtr(false),
} }
legend := ChartLegend{Position: &positionLeft, ShowLegendKey: false} legend := ChartLegend{Position: "left", ShowLegendKey: false}
plotArea := ChartPlotArea{ plotArea := ChartPlotArea{
ShowBubbleSize: true, ShowBubbleSize: true,
ShowCatName: true, ShowCatName: true,
@ -187,13 +185,13 @@ func TestAddChart(t *testing.T) {
sheetName, cell string sheetName, cell string
opts *Chart opts *Chart
}{ }{
{sheetName: "Sheet1", cell: "P1", opts: &Chart{Type: "col", Series: series, Format: format, Legend: ChartLegend{None: true, ShowLegendKey: true}, Title: ChartTitle{Name: "2D Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{Font: Font{Bold: true, Italic: true, Underline: "dbl", Color: "#000000"}}, YAxis: ChartAxis{Font: Font{Bold: false, Italic: false, Underline: "sng", Color: "#777777"}}}}, {sheetName: "Sheet1", cell: "P1", opts: &Chart{Type: "col", Series: series, Format: format, Legend: ChartLegend{Position: "none", ShowLegendKey: true}, Title: ChartTitle{Name: "2D Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{Font: Font{Bold: true, Italic: true, Underline: "dbl", Color: "#000000"}}, YAxis: ChartAxis{Font: Font{Bold: false, Italic: false, Underline: "sng", Color: "#777777"}}}},
{sheetName: "Sheet1", cell: "X1", opts: &Chart{Type: "colStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Stacked Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "X1", opts: &Chart{Type: "colStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Stacked Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "P16", opts: &Chart{Type: "colPercentStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "100% Stacked Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "P16", opts: &Chart{Type: "colPercentStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "100% Stacked Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "X16", opts: &Chart{Type: "col3DClustered", Series: series, Format: format, Legend: ChartLegend{Position: &positionBottom, ShowLegendKey: false}, Title: ChartTitle{Name: "3D Clustered Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "X16", opts: &Chart{Type: "col3DClustered", Series: series, Format: format, Legend: ChartLegend{Position: "bottom", ShowLegendKey: false}, Title: ChartTitle{Name: "3D Clustered Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "P30", opts: &Chart{Type: "col3DStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Stacked Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "P30", opts: &Chart{Type: "col3DStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Stacked Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "X30", opts: &Chart{Type: "col3DPercentStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D 100% Stacked Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "X30", opts: &Chart{Type: "col3DPercentStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D 100% Stacked Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "X45", opts: &Chart{Type: "radar", Series: series, Format: format, Legend: ChartLegend{Position: &positionTopRight, ShowLegendKey: false}, Title: ChartTitle{Name: "Radar Chart"}, PlotArea: plotArea, ShowBlanksAs: "span"}}, {sheetName: "Sheet1", cell: "X45", opts: &Chart{Type: "radar", Series: series, Format: format, Legend: ChartLegend{Position: "top_right", ShowLegendKey: false}, Title: ChartTitle{Name: "Radar Chart"}, PlotArea: plotArea, ShowBlanksAs: "span"}},
{sheetName: "Sheet1", cell: "AF1", opts: &Chart{Type: "col3DConeStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cone Stacked Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "AF1", opts: &Chart{Type: "col3DConeStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cone Stacked Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "AF16", opts: &Chart{Type: "col3DConeClustered", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cone Clustered Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "AF16", opts: &Chart{Type: "col3DConeClustered", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cone Clustered Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "AF30", opts: &Chart{Type: "col3DConePercentStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cone Percent Stacked Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "AF30", opts: &Chart{Type: "col3DConePercentStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cone Percent Stacked Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
@ -207,12 +205,12 @@ func TestAddChart(t *testing.T) {
{sheetName: "Sheet1", cell: "AV30", opts: &Chart{Type: "col3DCylinderPercentStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cylinder Percent Stacked Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "AV30", opts: &Chart{Type: "col3DCylinderPercentStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cylinder Percent Stacked Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "AV45", opts: &Chart{Type: "col3DCylinder", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cylinder Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "AV45", opts: &Chart{Type: "col3DCylinder", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Cylinder Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet1", cell: "P45", opts: &Chart{Type: "col3D", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet1", cell: "P45", opts: &Chart{Type: "col3D", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "3D Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet2", cell: "P1", opts: &Chart{Type: "line3D", Series: series2, Format: format, Legend: ChartLegend{Position: &positionTop, ShowLegendKey: false}, Title: ChartTitle{Name: "3D Line Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, TickLabelSkip: 1}, YAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, MajorUnit: 1}}}, {sheetName: "Sheet2", cell: "P1", opts: &Chart{Type: "line3D", Series: series2, Format: format, Legend: ChartLegend{Position: "top", ShowLegendKey: false}, Title: ChartTitle{Name: "3D Line Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, TickLabelSkip: 1}, YAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, MajorUnit: 1}}},
{sheetName: "Sheet2", cell: "X1", opts: &Chart{Type: "scatter", Series: series, Format: format, Legend: ChartLegend{Position: &positionBottom, ShowLegendKey: false}, Title: ChartTitle{Name: "Scatter Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet2", cell: "X1", opts: &Chart{Type: "scatter", Series: series, Format: format, Legend: ChartLegend{Position: "bottom", ShowLegendKey: false}, Title: ChartTitle{Name: "Scatter Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet2", cell: "P16", opts: &Chart{Type: "doughnut", Series: series3, Format: format, Legend: ChartLegend{Position: &positionRight, ShowLegendKey: false}, Title: ChartTitle{Name: "Doughnut Chart"}, PlotArea: ChartPlotArea{ShowBubbleSize: false, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: false, ShowVal: false}, ShowBlanksAs: "zero", HoleSize: 30}}, {sheetName: "Sheet2", cell: "P16", opts: &Chart{Type: "doughnut", Series: series3, Format: format, Legend: ChartLegend{Position: "right", ShowLegendKey: false}, Title: ChartTitle{Name: "Doughnut Chart"}, PlotArea: ChartPlotArea{ShowBubbleSize: false, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: false, ShowVal: false}, ShowBlanksAs: "zero", HoleSize: 30}},
{sheetName: "Sheet2", cell: "X16", opts: &Chart{Type: "line", Series: series2, Format: format, Legend: ChartLegend{Position: &positionTop, ShowLegendKey: false}, Title: ChartTitle{Name: "Line Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, TickLabelSkip: 1}, YAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, MajorUnit: 1}}}, {sheetName: "Sheet2", cell: "X16", opts: &Chart{Type: "line", Series: series2, Format: format, Legend: ChartLegend{Position: "top", ShowLegendKey: false}, Title: ChartTitle{Name: "Line Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero", XAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, TickLabelSkip: 1}, YAxis: ChartAxis{MajorGridLines: true, MinorGridLines: true, MajorUnit: 1}}},
{sheetName: "Sheet2", cell: "P32", opts: &Chart{Type: "pie3D", Series: series3, Format: format, Legend: ChartLegend{Position: &positionBottom, ShowLegendKey: false}, Title: ChartTitle{Name: "3D Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet2", cell: "P32", opts: &Chart{Type: "pie3D", Series: series3, Format: format, Legend: ChartLegend{Position: "bottom", ShowLegendKey: false}, Title: ChartTitle{Name: "3D Column Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet2", cell: "X32", opts: &Chart{Type: "pie", Series: series3, Format: format, Legend: ChartLegend{Position: &positionBottom, ShowLegendKey: false}, Title: ChartTitle{Name: "Pie Chart"}, PlotArea: ChartPlotArea{ShowBubbleSize: true, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: false, ShowVal: false}, ShowBlanksAs: "gap"}}, {sheetName: "Sheet2", cell: "X32", opts: &Chart{Type: "pie", Series: series3, Format: format, Legend: ChartLegend{Position: "bottom", ShowLegendKey: false}, Title: ChartTitle{Name: "Pie Chart"}, PlotArea: ChartPlotArea{ShowBubbleSize: true, ShowCatName: false, ShowLeaderLines: false, ShowPercent: true, ShowSerName: false, ShowVal: false}, ShowBlanksAs: "gap"}},
// bar series chart // bar series chart
{sheetName: "Sheet2", cell: "P48", opts: &Chart{Type: "bar", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Clustered Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet2", cell: "P48", opts: &Chart{Type: "bar", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Clustered Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
{sheetName: "Sheet2", cell: "X48", opts: &Chart{Type: "barStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Stacked Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}}, {sheetName: "Sheet2", cell: "X48", opts: &Chart{Type: "barStacked", Series: series, Format: format, Legend: legend, Title: ChartTitle{Name: "2D Stacked Bar Chart"}, PlotArea: plotArea, ShowBlanksAs: "zero"}},
@ -343,7 +341,6 @@ func TestDeleteChart(t *testing.T) {
f, err := OpenFile(filepath.Join("test", "Book1.xlsx")) f, err := OpenFile(filepath.Join("test", "Book1.xlsx"))
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, f.DeleteChart("Sheet1", "A1")) assert.NoError(t, f.DeleteChart("Sheet1", "A1"))
positionLeft := "left"
series := []ChartSeries{ series := []ChartSeries{
{Name: "Sheet1!$A$30", Categories: "Sheet1!$B$29:$D$29", Values: "Sheet1!$B$30:$D$30"}, {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$31", Categories: "Sheet1!$B$29:$D$29", Values: "Sheet1!$B$31:$D$31"},
@ -354,16 +351,16 @@ func TestDeleteChart(t *testing.T) {
{Name: "Sheet1!$A$36", Categories: "Sheet1!$B$29:$D$29", Values: "Sheet1!$B$36:$D$36"}, {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"}, {Name: "Sheet1!$A$37", Categories: "Sheet1!$B$29:$D$29", Values: "Sheet1!$B$37:$D$37"},
} }
format := PictureOptions{ format := GraphicOptions{
XScale: float64Ptr(defaultPictureScale), ScaleX: defaultPictureScale,
YScale: float64Ptr(defaultPictureScale), ScaleY: defaultPictureScale,
OffsetX: 15, OffsetX: 15,
OffsetY: 10, OffsetY: 10,
PrintObject: boolPtr(true), PrintObject: boolPtr(true),
LockAspectRatio: false, LockAspectRatio: false,
Locked: boolPtr(false), Locked: boolPtr(false),
} }
legend := ChartLegend{Position: &positionLeft, ShowLegendKey: false} legend := ChartLegend{Position: "left", ShowLegendKey: false}
plotArea := ChartPlotArea{ plotArea := ChartPlotArea{
ShowBubbleSize: true, ShowBubbleSize: true,
ShowCatName: true, ShowCatName: true,
@ -416,17 +413,17 @@ func TestChartWithLogarithmicBase(t *testing.T) {
assert.NoError(t, f.SetCellValue(sheet1, cell, v)) assert.NoError(t, f.SetCellValue(sheet1, cell, v))
} }
series := []ChartSeries{{Name: "value", Categories: "Sheet1!$A$1:$A$19", Values: "Sheet1!$B$1:$B$10"}} series := []ChartSeries{{Name: "value", Categories: "Sheet1!$A$1:$A$19", Values: "Sheet1!$B$1:$B$10"}}
dimension := []int{640, 480, 320, 240} dimension := []uint{640, 480, 320, 240}
for _, c := range []struct { for _, c := range []struct {
cell string cell string
opts *Chart opts *Chart
}{ }{
{cell: "C1", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: &dimension[0], Height: &dimension[1]}, Series: series, Title: ChartTitle{Name: "Line chart without log scaling"}}}, {cell: "C1", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: dimension[0], Height: dimension[1]}, Series: series, Title: ChartTitle{Name: "Line chart without log scaling"}}},
{cell: "M1", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: &dimension[0], Height: &dimension[1]}, Series: series, Title: ChartTitle{Name: "Line chart with log 10.5 scaling"}, YAxis: ChartAxis{LogBase: 10.5}}}, {cell: "M1", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: dimension[0], Height: dimension[1]}, Series: series, Title: ChartTitle{Name: "Line chart with log 10.5 scaling"}, YAxis: ChartAxis{LogBase: 10.5}}},
{cell: "A25", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: &dimension[2], Height: &dimension[3]}, Series: series, Title: ChartTitle{Name: "Line chart with log 1.9 scaling"}, YAxis: ChartAxis{LogBase: 1.9}}}, {cell: "A25", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: dimension[2], Height: dimension[3]}, Series: series, Title: ChartTitle{Name: "Line chart with log 1.9 scaling"}, YAxis: ChartAxis{LogBase: 1.9}}},
{cell: "F25", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: &dimension[2], Height: &dimension[3]}, Series: series, Title: ChartTitle{Name: "Line chart with log 2 scaling"}, YAxis: ChartAxis{LogBase: 2}}}, {cell: "F25", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: dimension[2], Height: dimension[3]}, Series: series, Title: ChartTitle{Name: "Line chart with log 2 scaling"}, YAxis: ChartAxis{LogBase: 2}}},
{cell: "K25", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: &dimension[2], Height: &dimension[3]}, Series: series, Title: ChartTitle{Name: "Line chart with log 1000.1 scaling"}, YAxis: ChartAxis{LogBase: 1000.1}}}, {cell: "K25", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: dimension[2], Height: dimension[3]}, Series: series, Title: ChartTitle{Name: "Line chart with log 1000.1 scaling"}, YAxis: ChartAxis{LogBase: 1000.1}}},
{cell: "P25", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: &dimension[2], Height: &dimension[3]}, Series: series, Title: ChartTitle{Name: "Line chart with log 1000 scaling"}, YAxis: ChartAxis{LogBase: 1000}}}, {cell: "P25", opts: &Chart{Type: "line", Dimension: ChartDimension{Width: dimension[2], Height: dimension[3]}, Series: series, Title: ChartTitle{Name: "Line chart with log 1000 scaling"}, YAxis: ChartAxis{LogBase: 1000}}},
} { } {
// Add two chart, one without and one with log scaling // Add two chart, one without and one with log scaling
assert.NoError(t, f.AddChart(sheet1, c.cell, c.opts)) assert.NoError(t, f.AddChart(sheet1, c.cell, c.opts))

5
col.go
View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -475,7 +475,6 @@ func (f *File) SetColStyle(sheet, columns string, styleID int) error {
// SetColWidth provides a function to set the width of a single column or // SetColWidth provides a function to set the width of a single column or
// multiple columns. This function is concurrency safe. For example: // multiple columns. This function is concurrency safe. For example:
// //
// f := excelize.NewFile()
// err := f.SetColWidth("Sheet1", "A", "H", 20) // err := f.SetColWidth("Sheet1", "A", "H", 20)
func (f *File) SetColWidth(sheet, startCol, endCol string, width float64) error { func (f *File) SetColWidth(sheet, startCol, endCol string, width float64) error {
min, max, err := f.parseColRange(startCol + ":" + endCol) min, max, err := f.parseColRange(startCol + ":" + endCol)

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -87,7 +87,7 @@ func (f *File) getSheetComments(sheetFile string) string {
// author length is 255 and the max text length is 32512. For example, add a // author length is 255 and the max text length is 32512. For example, add a
// comment in Sheet1!$A$30: // comment in Sheet1!$A$30:
// //
// err := f.AddComment(sheet, excelize.Comment{ // err := f.AddComment("Sheet1", excelize.Comment{
// Cell: "A12", // Cell: "A12",
// Author: "Excelize", // Author: "Excelize",
// Runs: []excelize.RichTextRun{ // Runs: []excelize.RichTextRun{

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -139,7 +139,7 @@ func (f *File) addChart(opts *Chart, comboCharts []*Chart) {
}, },
PlotArea: &cPlotArea{}, PlotArea: &cPlotArea{},
Legend: &cLegend{ Legend: &cLegend{
LegendPos: &attrValString{Val: stringPtr(chartLegendPosition[*opts.Legend.Position])}, LegendPos: &attrValString{Val: stringPtr(chartLegendPosition[opts.Legend.Position])},
Overlay: &attrValBool{Val: boolPtr(false)}, Overlay: &attrValBool{Val: boolPtr(false)},
}, },
@ -237,7 +237,7 @@ func (f *File) addChart(opts *Chart, comboCharts []*Chart) {
Bubble: f.drawBaseChart, Bubble: f.drawBaseChart,
Bubble3D: f.drawBaseChart, Bubble3D: f.drawBaseChart,
} }
if opts.Legend.None { if opts.Legend.Position == "none" {
xlsxChartSpace.Chart.Legend = nil xlsxChartSpace.Chart.Legend = nil
} }
addChart := func(c, p *cPlotArea) { addChart := func(c, p *cPlotArea) {
@ -1242,7 +1242,7 @@ func (f *File) drawingParser(path string) (*xlsxWsDr, int, error) {
// addDrawingChart provides a function to add chart graphic frame by given // addDrawingChart provides a function to add chart graphic frame by given
// sheet, drawingXML, cell, width, height, relationship index and format sets. // sheet, drawingXML, cell, width, height, relationship index and format sets.
func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rID int, opts *PictureOptions) error { func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rID int, opts *GraphicOptions) error {
col, row, err := CellNameToCoordinates(cell) col, row, err := CellNameToCoordinates(cell)
if err != nil { if err != nil {
return err return err
@ -1250,8 +1250,8 @@ func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rI
colIdx := col - 1 colIdx := col - 1
rowIdx := row - 1 rowIdx := row - 1
width = int(float64(width) * *opts.XScale) width = int(float64(width) * opts.ScaleX)
height = int(float64(height) * *opts.YScale) height = int(float64(height) * opts.ScaleY)
colStart, rowStart, colEnd, rowEnd, x2, y2 := f.positionObjectPixels(sheet, colIdx, rowIdx, opts.OffsetX, opts.OffsetY, width, height) colStart, rowStart, colEnd, rowEnd, x2, y2 := f.positionObjectPixels(sheet, colIdx, rowIdx, opts.OffsetX, opts.OffsetY, width, height)
content, cNvPrID, err := f.drawingParser(drawingXML) content, cNvPrID, err := f.drawingParser(drawingXML)
if err != nil { if err != nil {
@ -1304,7 +1304,7 @@ func (f *File) addDrawingChart(sheet, drawingXML, cell string, width, height, rI
// addSheetDrawingChart provides a function to add chart graphic frame for // addSheetDrawingChart provides a function to add chart graphic frame for
// chartsheet by given sheet, drawingXML, width, height, relationship index // chartsheet by given sheet, drawingXML, width, height, relationship index
// and format sets. // and format sets.
func (f *File) addSheetDrawingChart(drawingXML string, rID int, opts *PictureOptions) error { func (f *File) addSheetDrawingChart(drawingXML string, rID int, opts *GraphicOptions) error {
content, cNvPrID, err := f.drawingParser(drawingXML) content, cNvPrID, err := f.drawingParser(drawingXML)
if err != nil { if err != nil {
return err return err

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
// //
// See https://xuri.me/excelize for more information about this package. // See https://xuri.me/excelize for more information about this package.
package excelize package excelize
@ -37,15 +37,15 @@ type File struct {
sheetMap map[string]string sheetMap map[string]string
streams map[string]*StreamWriter streams map[string]*StreamWriter
tempFiles sync.Map tempFiles sync.Map
sharedStringsMap map[string]int
sharedStringItem [][]uint
sharedStringTemp *os.File
CalcChain *xlsxCalcChain CalcChain *xlsxCalcChain
Comments map[string]*xlsxComments Comments map[string]*xlsxComments
ContentTypes *xlsxTypes ContentTypes *xlsxTypes
Drawings sync.Map Drawings sync.Map
Path string Path string
SharedStrings *xlsxSST SharedStrings *xlsxSST
sharedStringsMap map[string]int
sharedStringItem [][]uint
sharedStringTemp *os.File
Sheet sync.Map Sheet sync.Map
SheetCount int SheetCount int
Styles *xlsxStyleSheet Styles *xlsxStyleSheet
@ -58,6 +58,8 @@ type File struct {
CharsetReader charsetTranscoderFn CharsetReader charsetTranscoderFn
} }
// charsetTranscoderFn set user-defined codepage transcoder function for open
// the spreadsheet from non-UTF-8 encoding.
type charsetTranscoderFn func(charset string, input io.Reader) (rdr io.Reader, err error) type charsetTranscoderFn func(charset string, input io.Reader) (rdr io.Reader, err error)
// Options define the options for open and reading spreadsheet. // Options define the options for open and reading spreadsheet.
@ -92,9 +94,6 @@ type Options struct {
// password protection: // password protection:
// //
// f, err := excelize.OpenFile("Book1.xlsx", excelize.Options{Password: "password"}) // f, err := excelize.OpenFile("Book1.xlsx", excelize.Options{Password: "password"})
// if err != nil {
// return
// }
// //
// Close the file by Close function after opening the spreadsheet. // Close the file by Close function after opening the spreadsheet.
func OpenFile(filename string, opts ...Options) (*File, error) { func OpenFile(filename string, opts ...Options) (*File, error) {

View File

@ -353,9 +353,8 @@ func TestNewFile(t *testing.T) {
f.SetActiveSheet(0) f.SetActiveSheet(0)
// Test add picture to sheet with scaling and positioning // Test add picture to sheet with scaling and positioning
scale := 0.5
assert.NoError(t, f.AddPicture("Sheet1", "H2", filepath.Join("test", "images", "excel.gif"), assert.NoError(t, f.AddPicture("Sheet1", "H2", filepath.Join("test", "images", "excel.gif"),
&PictureOptions{XScale: &scale, YScale: &scale, Positioning: "absolute"})) &GraphicOptions{ScaleX: 0.5, ScaleY: 0.5, Positioning: "absolute"}))
// Test add picture to worksheet without options // Test add picture to worksheet without options
assert.NoError(t, f.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), nil)) assert.NoError(t, f.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), nil))
@ -1283,7 +1282,7 @@ func TestHSL(t *testing.T) {
func TestProtectSheet(t *testing.T) { func TestProtectSheet(t *testing.T) {
f := NewFile() f := NewFile()
sheetName := f.GetSheetName(0) sheetName := f.GetSheetName(0)
assert.NoError(t, f.ProtectSheet(sheetName, nil)) assert.EqualError(t, f.ProtectSheet(sheetName, nil), ErrParameterInvalid.Error())
// Test protect worksheet with XOR hash algorithm // Test protect worksheet with XOR hash algorithm
assert.NoError(t, f.ProtectSheet(sheetName, &SheetProtectionOptions{ assert.NoError(t, f.ProtectSheet(sheetName, &SheetProtectionOptions{
Password: "password", Password: "password",
@ -1517,13 +1516,13 @@ func prepareTestBook1() (*File, error) {
} }
if err = f.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"), if err = f.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"),
&PictureOptions{OffsetX: 140, OffsetY: 120, Hyperlink: "#Sheet2!D8", HyperlinkType: "Location"}); err != nil { &GraphicOptions{OffsetX: 140, OffsetY: 120, Hyperlink: "#Sheet2!D8", HyperlinkType: "Location"}); err != nil {
return nil, err return nil, err
} }
// Test add picture to worksheet with offset, external hyperlink and positioning // Test add picture to worksheet with offset, external hyperlink and positioning
if err := f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.png"), if err := f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.png"),
&PictureOptions{ &GraphicOptions{
OffsetX: 10, OffsetX: 10,
OffsetY: 10, OffsetY: 10,
Hyperlink: "https://github.com/xuri/excelize", Hyperlink: "https://github.com/xuri/excelize",
@ -1562,9 +1561,8 @@ func prepareTestBook3() (*File, error) {
return nil, err return nil, err
} }
f.SetActiveSheet(0) f.SetActiveSheet(0)
scale := 0.5
if err := f.AddPicture("Sheet1", "H2", filepath.Join("test", "images", "excel.gif"), if err := f.AddPicture("Sheet1", "H2", filepath.Join("test", "images", "excel.gif"),
&PictureOptions{XScale: &scale, YScale: &scale, Positioning: "absolute"}); err != nil { &GraphicOptions{ScaleX: 0.5, ScaleY: 0.5, Positioning: "absolute"}); err != nil {
return nil, err return nil, err
} }
if err := f.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), nil); err != nil { if err := f.AddPicture("Sheet1", "C2", filepath.Join("test", "images", "excel.png"), nil); err != nil {

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

6
go.mod
View File

@ -8,10 +8,10 @@ require (
github.com/stretchr/testify v1.8.0 github.com/stretchr/testify v1.8.0
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 github.com/xuri/efp v0.0.0-20220603152613-6918739fd470
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22
golang.org/x/crypto v0.2.0 golang.org/x/crypto v0.4.0
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 golang.org/x/image v0.0.0-20220902085622-e7cb96979f69
golang.org/x/net v0.2.0 golang.org/x/net v0.4.0
golang.org/x/text v0.4.0 golang.org/x/text v0.5.0
) )
require github.com/richardlehane/msoleps v1.0.3 // indirect require github.com/richardlehane/msoleps v1.0.3 // indirect

17
go.sum
View File

@ -22,16 +22,17 @@ github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.2.0 h1:BRXPfhNivWL5Yq0BGQ39a2sW6t44aODpfxkWjYdzewE= golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
golang.org/x/crypto v0.2.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 h1:Lj6HJGCSn5AjxRAH2+r35Mir4icalbqku+CLUtjnvXY= golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 h1:Lj6HJGCSn5AjxRAH2+r35Mir4icalbqku+CLUtjnvXY=
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY= golang.org/x/image v0.0.0-20220902085622-e7cb96979f69/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -39,15 +40,15 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=

4
lib.go
View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -23,28 +23,28 @@ import (
"strings" "strings"
) )
// parsePictureOptions provides a function to parse the format settings of // parseGraphicOptions provides a function to parse the format settings of
// the picture with default value. // the picture with default value.
func parsePictureOptions(opts *PictureOptions) *PictureOptions { func parseGraphicOptions(opts *GraphicOptions) *GraphicOptions {
if opts == nil { if opts == nil {
return &PictureOptions{ return &GraphicOptions{
PrintObject: boolPtr(true), PrintObject: boolPtr(true),
Locked: boolPtr(false), Locked: boolPtr(true),
XScale: float64Ptr(defaultPictureScale), ScaleX: defaultPictureScale,
YScale: float64Ptr(defaultPictureScale), ScaleY: defaultPictureScale,
} }
} }
if opts.PrintObject == nil { if opts.PrintObject == nil {
opts.PrintObject = boolPtr(true) opts.PrintObject = boolPtr(true)
} }
if opts.Locked == nil { if opts.Locked == nil {
opts.Locked = boolPtr(false) opts.Locked = boolPtr(true)
} }
if opts.XScale == nil { if opts.ScaleX == 0 {
opts.XScale = float64Ptr(defaultPictureScale) opts.ScaleX = defaultPictureScale
} }
if opts.YScale == nil { if opts.ScaleY == 0 {
opts.YScale = float64Ptr(defaultPictureScale) opts.ScaleY = defaultPictureScale
} }
return opts return opts
} }
@ -67,25 +67,32 @@ func parsePictureOptions(opts *PictureOptions) *PictureOptions {
// //
// func main() { // func main() {
// f := excelize.NewFile() // f := excelize.NewFile()
// defer func() {
// if err := f.Close(); err != nil {
// fmt.Println(err)
// }
// }()
// // Insert a picture. // // Insert a picture.
// if err := f.AddPicture("Sheet1", "A2", "image.jpg", nil); err != nil { // if err := f.AddPicture("Sheet1", "A2", "image.jpg", nil); err != nil {
// fmt.Println(err) // fmt.Println(err)
// return
// } // }
// // Insert a picture scaling in the cell with location hyperlink. // // Insert a picture scaling in the cell with location hyperlink.
// enable, scale := true, 0.5 // enable := true
// if err := f.AddPicture("Sheet1", "D2", "image.png", // if err := f.AddPicture("Sheet1", "D2", "image.png",
// &excelize.PictureOptions{ // &excelize.GraphicOptions{
// XScale: &scale, // ScaleX: 0.5,
// YScale: &scale, // ScaleY: 0.5,
// Hyperlink: "#Sheet2!D8", // Hyperlink: "#Sheet2!D8",
// HyperlinkType: "Location", // HyperlinkType: "Location",
// }, // },
// ); err != nil { // ); err != nil {
// fmt.Println(err) // fmt.Println(err)
// return
// } // }
// // Insert a picture offset in the cell with external hyperlink, printing and positioning support. // // Insert a picture offset in the cell with external hyperlink, printing and positioning support.
// if err := f.AddPicture("Sheet1", "H2", "image.gif", // if err := f.AddPicture("Sheet1", "H2", "image.gif",
// &excelize.PictureOptions{ // &excelize.GraphicOptions{
// PrintObject: &enable, // PrintObject: &enable,
// LockAspectRatio: false, // LockAspectRatio: false,
// OffsetX: 15, // OffsetX: 15,
@ -96,6 +103,7 @@ func parsePictureOptions(opts *PictureOptions) *PictureOptions {
// }, // },
// ); err != nil { // ); err != nil {
// fmt.Println(err) // fmt.Println(err)
// return
// } // }
// if err := f.SaveAs("Book1.xlsx"); err != nil { // if err := f.SaveAs("Book1.xlsx"); err != nil {
// fmt.Println(err) // fmt.Println(err)
@ -129,15 +137,15 @@ func parsePictureOptions(opts *PictureOptions) *PictureOptions {
// The optional parameter "OffsetX" specifies the horizontal offset of the // The optional parameter "OffsetX" specifies the horizontal offset of the
// image with the cell, the default value of that is 0. // image with the cell, the default value of that is 0.
// //
// The optional parameter "XScale" specifies the horizontal scale of images, // The optional parameter "ScaleX" specifies the horizontal scale of images,
// the default value of that is 1.0 which presents 100%. // the default value of that is 1.0 which presents 100%.
// //
// The optional parameter "OffsetY" specifies the vertical offset of the // The optional parameter "OffsetY" specifies the vertical offset of the
// image with the cell, the default value of that is 0. // image with the cell, the default value of that is 0.
// //
// The optional parameter "YScale" specifies the vertical scale of images, // The optional parameter "ScaleY" specifies the vertical scale of images,
// the default value of that is 1.0 which presents 100%. // the default value of that is 1.0 which presents 100%.
func (f *File) AddPicture(sheet, cell, picture string, opts *PictureOptions) error { func (f *File) AddPicture(sheet, cell, picture string, opts *GraphicOptions) error {
var err error var err error
// Check picture exists first. // Check picture exists first.
if _, err = os.Stat(picture); os.IsNotExist(err) { if _, err = os.Stat(picture); os.IsNotExist(err) {
@ -170,26 +178,32 @@ func (f *File) AddPicture(sheet, cell, picture string, opts *PictureOptions) err
// //
// func main() { // func main() {
// f := excelize.NewFile() // f := excelize.NewFile()
// // defer func() {
// if err := f.Close(); err != nil {
// fmt.Println(err)
// }
// }()
// file, err := os.ReadFile("image.jpg") // file, err := os.ReadFile("image.jpg")
// if err != nil { // if err != nil {
// fmt.Println(err) // fmt.Println(err)
// return
// } // }
// if err := f.AddPictureFromBytes("Sheet1", "A2", "Excel Logo", ".jpg", file, nil); err != nil { // if err := f.AddPictureFromBytes("Sheet1", "A2", "Excel Logo", ".jpg", file, nil); err != nil {
// fmt.Println(err) // fmt.Println(err)
// return
// } // }
// if err := f.SaveAs("Book1.xlsx"); err != nil { // if err := f.SaveAs("Book1.xlsx"); err != nil {
// fmt.Println(err) // fmt.Println(err)
// } // }
// } // }
func (f *File) AddPictureFromBytes(sheet, cell, name, extension string, file []byte, opts *PictureOptions) error { func (f *File) AddPictureFromBytes(sheet, cell, name, extension string, file []byte, opts *GraphicOptions) error {
var drawingHyperlinkRID int var drawingHyperlinkRID int
var hyperlinkType string var hyperlinkType string
ext, ok := supportedImageTypes[extension] ext, ok := supportedImageTypes[extension]
if !ok { if !ok {
return ErrImgExt return ErrImgExt
} }
options := parsePictureOptions(opts) options := parseGraphicOptions(opts)
img, _, err := image.DecodeConfig(bytes.NewReader(file)) img, _, err := image.DecodeConfig(bytes.NewReader(file))
if err != nil { if err != nil {
return err return err
@ -305,7 +319,7 @@ func (f *File) countDrawings() int {
// addDrawingPicture provides a function to add picture by given sheet, // addDrawingPicture provides a function to add picture by given sheet,
// drawingXML, cell, file name, width, height relationship index and format // drawingXML, cell, file name, width, height relationship index and format
// sets. // sets.
func (f *File) addDrawingPicture(sheet, drawingXML, cell, file, ext string, rID, hyperlinkRID int, img image.Config, opts *PictureOptions) error { func (f *File) addDrawingPicture(sheet, drawingXML, cell, file, ext string, rID, hyperlinkRID int, img image.Config, opts *GraphicOptions) error {
col, row, err := CellNameToCoordinates(cell) col, row, err := CellNameToCoordinates(cell)
if err != nil { if err != nil {
return err return err
@ -317,8 +331,8 @@ func (f *File) addDrawingPicture(sheet, drawingXML, cell, file, ext string, rID,
return err return err
} }
} else { } else {
width = int(float64(width) * *opts.XScale) width = int(float64(width) * opts.ScaleX)
height = int(float64(height) * *opts.YScale) height = int(float64(height) * opts.ScaleY)
} }
col-- col--
row-- row--
@ -711,7 +725,7 @@ func (f *File) drawingsWriter() {
} }
// drawingResize calculate the height and width after resizing. // drawingResize calculate the height and width after resizing.
func (f *File) drawingResize(sheet, cell string, width, height float64, opts *PictureOptions) (w, h, c, r int, err error) { func (f *File) drawingResize(sheet, cell string, width, height float64, opts *GraphicOptions) (w, h, c, r int, err error) {
var mergeCells []MergeCell var mergeCells []MergeCell
mergeCells, err = f.GetMergeCells(sheet) mergeCells, err = f.GetMergeCells(sheet)
if err != nil { if err != nil {
@ -754,6 +768,6 @@ func (f *File) drawingResize(sheet, cell string, width, height float64, opts *Pi
height, width = float64(cellHeight), width*asp height, width = float64(cellHeight), width*asp
} }
width, height = width-float64(opts.OffsetX), height-float64(opts.OffsetY) width, height = width-float64(opts.OffsetX), height-float64(opts.OffsetY)
w, h = int(width**opts.XScale), int(height**opts.YScale) w, h = int(width*opts.ScaleX), int(height*opts.ScaleY)
return return
} }

View File

@ -37,24 +37,24 @@ func TestAddPicture(t *testing.T) {
// Test add picture to worksheet with offset and location hyperlink // Test add picture to worksheet with offset and location hyperlink
assert.NoError(t, f.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"), assert.NoError(t, f.AddPicture("Sheet2", "I9", filepath.Join("test", "images", "excel.jpg"),
&PictureOptions{OffsetX: 140, OffsetY: 120, Hyperlink: "#Sheet2!D8", HyperlinkType: "Location"})) &GraphicOptions{OffsetX: 140, OffsetY: 120, Hyperlink: "#Sheet2!D8", HyperlinkType: "Location"}))
// Test add picture to worksheet with offset, external hyperlink and positioning // Test add picture to worksheet with offset, external hyperlink and positioning
assert.NoError(t, f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"), assert.NoError(t, f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"),
&PictureOptions{OffsetX: 10, OffsetY: 10, Hyperlink: "https://github.com/xuri/excelize", HyperlinkType: "External", Positioning: "oneCell"})) &GraphicOptions{OffsetX: 10, OffsetY: 10, Hyperlink: "https://github.com/xuri/excelize", HyperlinkType: "External", Positioning: "oneCell"}))
file, err := os.ReadFile(filepath.Join("test", "images", "excel.png")) file, err := os.ReadFile(filepath.Join("test", "images", "excel.png"))
assert.NoError(t, err) assert.NoError(t, err)
// Test add picture to worksheet with autofit // Test add picture to worksheet with autofit
assert.NoError(t, f.AddPicture("Sheet1", "A30", filepath.Join("test", "images", "excel.jpg"), &PictureOptions{AutoFit: true})) assert.NoError(t, f.AddPicture("Sheet1", "A30", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{AutoFit: true}))
assert.NoError(t, f.AddPicture("Sheet1", "B30", filepath.Join("test", "images", "excel.jpg"), &PictureOptions{OffsetX: 10, OffsetY: 10, AutoFit: true})) assert.NoError(t, f.AddPicture("Sheet1", "B30", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{OffsetX: 10, OffsetY: 10, AutoFit: true}))
_, err = f.NewSheet("AddPicture") _, err = f.NewSheet("AddPicture")
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, f.SetRowHeight("AddPicture", 10, 30)) assert.NoError(t, f.SetRowHeight("AddPicture", 10, 30))
assert.NoError(t, f.MergeCell("AddPicture", "B3", "D9")) assert.NoError(t, f.MergeCell("AddPicture", "B3", "D9"))
assert.NoError(t, f.MergeCell("AddPicture", "B1", "D1")) assert.NoError(t, f.MergeCell("AddPicture", "B1", "D1"))
assert.NoError(t, f.AddPicture("AddPicture", "C6", filepath.Join("test", "images", "excel.jpg"), &PictureOptions{AutoFit: true})) assert.NoError(t, f.AddPicture("AddPicture", "C6", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{AutoFit: true}))
assert.NoError(t, f.AddPicture("AddPicture", "A1", filepath.Join("test", "images", "excel.jpg"), &PictureOptions{AutoFit: true})) assert.NoError(t, f.AddPicture("AddPicture", "A1", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{AutoFit: true}))
// Test add picture to worksheet from bytes // Test add picture to worksheet from bytes
assert.NoError(t, f.AddPictureFromBytes("Sheet1", "Q1", "Excel Logo", ".png", file, nil)) assert.NoError(t, f.AddPictureFromBytes("Sheet1", "Q1", "Excel Logo", ".png", file, nil))
@ -105,8 +105,7 @@ func TestAddPictureErrors(t *testing.T) {
assert.NoError(t, f.AddPicture("Sheet1", "Q7", filepath.Join("test", "images", "excel.wmf"), nil)) assert.NoError(t, f.AddPicture("Sheet1", "Q7", filepath.Join("test", "images", "excel.wmf"), nil))
assert.NoError(t, f.AddPicture("Sheet1", "Q13", filepath.Join("test", "images", "excel.emz"), nil)) assert.NoError(t, f.AddPicture("Sheet1", "Q13", filepath.Join("test", "images", "excel.emz"), nil))
assert.NoError(t, f.AddPicture("Sheet1", "Q19", filepath.Join("test", "images", "excel.wmz"), nil)) assert.NoError(t, f.AddPicture("Sheet1", "Q19", filepath.Join("test", "images", "excel.wmz"), nil))
xScale := 2.1 assert.NoError(t, f.AddPicture("Sheet1", "Q25", "excelize.svg", &GraphicOptions{ScaleX: 2.1}))
assert.NoError(t, f.AddPicture("Sheet1", "Q25", "excelize.svg", &PictureOptions{XScale: &xScale}))
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddPicture2.xlsx"))) assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddPicture2.xlsx")))
assert.NoError(t, f.Close()) assert.NoError(t, f.Close())
} }
@ -198,7 +197,7 @@ func TestGetPicture(t *testing.T) {
func TestAddDrawingPicture(t *testing.T) { func TestAddDrawingPicture(t *testing.T) {
// Test addDrawingPicture with illegal cell reference // Test addDrawingPicture with illegal cell reference
f := NewFile() f := NewFile()
opts := &PictureOptions{PrintObject: boolPtr(true), Locked: boolPtr(false), XScale: float64Ptr(defaultPictureScale), YScale: float64Ptr(defaultPictureScale)} opts := &GraphicOptions{PrintObject: boolPtr(true), Locked: boolPtr(false)}
assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", "", 0, 0, image.Config{}, opts), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error()) assert.EqualError(t, f.addDrawingPicture("sheet1", "", "A", "", "", 0, 0, image.Config{}, opts), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
path := "xl/drawings/drawing1.xml" path := "xl/drawings/drawing1.xml"
@ -254,7 +253,7 @@ func TestDrawingResize(t *testing.T) {
ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml") ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml")
assert.True(t, ok) assert.True(t, ok)
ws.(*xlsxWorksheet).MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:A"}}} ws.(*xlsxWorksheet).MergeCells = &xlsxMergeCells{Cells: []*xlsxMergeCell{{Ref: "A:A"}}}
assert.EqualError(t, f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.jpg"), &PictureOptions{AutoFit: true}), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error()) assert.EqualError(t, f.AddPicture("Sheet1", "A1", filepath.Join("test", "images", "excel.jpg"), &GraphicOptions{AutoFit: true}), newCellNameToCoordinatesError("A", newInvalidCellNameError("A")).Error())
} }
func TestSetContentTypePartImageExtensions(t *testing.T) { func TestSetContentTypePartImageExtensions(t *testing.T) {

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -96,6 +96,11 @@ type PivotTableField struct {
// //
// func main() { // func main() {
// f := excelize.NewFile() // f := excelize.NewFile()
// defer func() {
// if err := f.Close(); err != nil {
// fmt.Println(err)
// }
// }()
// // Create some data in a sheet // // Create some data in a sheet
// month := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"} // month := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
// year := []int{2017, 2018, 2019} // year := []int{2017, 2018, 2019}

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -795,11 +795,11 @@ func (r *xlsxRow) hasAttr() bool {
// //
// For example set style of row 1 on Sheet1: // For example set style of row 1 on Sheet1:
// //
// err = f.SetRowStyle("Sheet1", 1, 1, styleID) // err := f.SetRowStyle("Sheet1", 1, 1, styleID)
// //
// Set style of rows 1 to 10 on Sheet1: // Set style of rows 1 to 10 on Sheet1:
// //
// err = f.SetRowStyle("Sheet1", 1, 10, styleID) // err := f.SetRowStyle("Sheet1", 1, 10, styleID)
func (f *File) SetRowStyle(sheet string, start, end, styleID int) error { func (f *File) SetRowStyle(sheet string, start, end, styleID int) error {
if end < start { if end < start {
start, end = end, start start, end = end, start

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -22,11 +22,11 @@ func parseShapeOptions(opts *Shape) (*Shape, error) {
if opts == nil { if opts == nil {
return nil, ErrParameterInvalid return nil, ErrParameterInvalid
} }
if opts.Width == nil { if opts.Width == 0 {
opts.Width = intPtr(defaultShapeSize) opts.Width = defaultShapeSize
} }
if opts.Height == nil { if opts.Height == 0 {
opts.Height = intPtr(defaultShapeSize) opts.Height = defaultShapeSize
} }
if opts.Format.PrintObject == nil { if opts.Format.PrintObject == nil {
opts.Format.PrintObject = boolPtr(true) opts.Format.PrintObject = boolPtr(true)
@ -34,11 +34,11 @@ func parseShapeOptions(opts *Shape) (*Shape, error) {
if opts.Format.Locked == nil { if opts.Format.Locked == nil {
opts.Format.Locked = boolPtr(false) opts.Format.Locked = boolPtr(false)
} }
if opts.Format.XScale == nil { if opts.Format.ScaleX == 0 {
opts.Format.XScale = float64Ptr(defaultPictureScale) opts.Format.ScaleX = defaultPictureScale
} }
if opts.Format.YScale == nil { if opts.Format.ScaleY == 0 {
opts.Format.YScale = float64Ptr(defaultPictureScale) opts.Format.ScaleY = defaultPictureScale
} }
if opts.Line.Width == nil { if opts.Line.Width == nil {
opts.Line.Width = float64Ptr(defaultShapeLineWidth) opts.Line.Width = float64Ptr(defaultShapeLineWidth)
@ -51,7 +51,7 @@ func parseShapeOptions(opts *Shape) (*Shape, error) {
// print settings) and properties set. For example, add text box (rect shape) // print settings) and properties set. For example, add text box (rect shape)
// in Sheet1: // in Sheet1:
// //
// width, height, lineWidth := 180, 90, 1.2 // lineWidth := 1.2
// err := f.AddShape("Sheet1", "G6", // err := f.AddShape("Sheet1", "G6",
// &excelize.Shape{ // &excelize.Shape{
// Type: "rect", // Type: "rect",
@ -63,14 +63,14 @@ func parseShapeOptions(opts *Shape) (*Shape, error) {
// Bold: true, // Bold: true,
// Italic: true, // Italic: true,
// Family: "Times New Roman", // Family: "Times New Roman",
// Size: 36, // Size: 18,
// Color: "#777777", // Color: "#777777",
// Underline: "sng", // Underline: "sng",
// }, // },
// }, // },
// }, // },
// Width: &width, // Width: 180,
// Height: &height, // Height: 40,
// Line: excelize.ShapeLine{Width: &lineWidth}, // Line: excelize.ShapeLine{Width: &lineWidth},
// }, // },
// ) // )
@ -329,8 +329,8 @@ func (f *File) addDrawingShape(sheet, drawingXML, cell string, opts *Shape) erro
colIdx := fromCol - 1 colIdx := fromCol - 1
rowIdx := fromRow - 1 rowIdx := fromRow - 1
width := int(float64(*opts.Width) * *opts.Format.XScale) width := int(float64(opts.Width) * opts.Format.ScaleX)
height := int(float64(*opts.Height) * *opts.Format.YScale) height := int(float64(opts.Height) * opts.Format.ScaleY)
colStart, rowStart, colEnd, rowEnd, x2, y2 := f.positionObjectPixels(sheet, colIdx, rowIdx, opts.Format.OffsetX, opts.Format.OffsetY, colStart, rowStart, colEnd, rowEnd, x2, y2 := f.positionObjectPixels(sheet, colIdx, rowIdx, opts.Format.OffsetX, opts.Format.OffsetY,
width, height) width, height)

View File

@ -46,7 +46,7 @@ func TestAddShape(t *testing.T) {
// Test add first shape for given sheet // Test add first shape for given sheet
f = NewFile() f = NewFile()
width, height := 1.2, 90 lineWidth := 1.2
assert.NoError(t, f.AddShape("Sheet1", "A1", assert.NoError(t, f.AddShape("Sheet1", "A1",
&Shape{ &Shape{
Type: "ellipseRibbon", Type: "ellipseRibbon",
@ -63,8 +63,8 @@ func TestAddShape(t *testing.T) {
}, },
}, },
}, },
Height: &height, Height: 90,
Line: ShapeLine{Width: &width}, Line: ShapeLine{Width: &lineWidth},
})) }))
assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddShape2.xlsx"))) assert.NoError(t, f.SaveAs(filepath.Join("test", "TestAddShape2.xlsx")))
// Test add shape with invalid sheet name // Test add shape with invalid sheet name
@ -86,13 +86,11 @@ func TestAddDrawingShape(t *testing.T) {
f.Pkg.Store(path, MacintoshCyrillicCharset) f.Pkg.Store(path, MacintoshCyrillicCharset)
assert.EqualError(t, f.addDrawingShape("sheet1", path, "A1", assert.EqualError(t, f.addDrawingShape("sheet1", path, "A1",
&Shape{ &Shape{
Width: intPtr(defaultShapeSize), Width: defaultShapeSize,
Height: intPtr(defaultShapeSize), Height: defaultShapeSize,
Format: PictureOptions{ Format: GraphicOptions{
PrintObject: boolPtr(true), PrintObject: boolPtr(true),
Locked: boolPtr(false), Locked: boolPtr(false),
XScale: float64Ptr(defaultPictureScale),
YScale: float64Ptr(defaultPictureScale),
}, },
}, },
), "XML syntax error on line 1: invalid UTF-8") ), "XML syntax error on line 1: invalid UTF-8")

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -642,9 +642,12 @@ func (f *File) deleteSheetFromContentTypes(target string) error {
// workbooks that contain tables, charts or pictures. For Example: // workbooks that contain tables, charts or pictures. For Example:
// //
// // Sheet1 already exists... // // Sheet1 already exists...
// index := f.NewSheet("Sheet2") // index, err := f.NewSheet("Sheet2")
// if err != nil {
// fmt.Println(err)
// return
// }
// err := f.CopySheet(1, index) // err := f.CopySheet(1, index)
// return err
func (f *File) CopySheet(from, to int) error { func (f *File) CopySheet(from, to int) error {
if from < 0 || to < 0 || from == to || f.GetSheetName(from) == "" || f.GetSheetName(to) == "" { if from < 0 || to < 0 || from == to || f.GetSheetName(from) == "" || f.GetSheetName(to) == "" {
return ErrSheetIdx return ErrSheetIdx
@ -878,7 +881,6 @@ func (ws *xlsxWorksheet) setPanes(panes *Panes) error {
// TopLeftCell: "N57", // TopLeftCell: "N57",
// ActivePane: "bottomLeft", // ActivePane: "bottomLeft",
// Panes: []excelize.PaneOptions{ // Panes: []excelize.PaneOptions{
// {SQRef: "G33", ActiveCell: "G33", Pane: "topRight"},
// {SQRef: "I36", ActiveCell: "I36"}, // {SQRef: "I36", ActiveCell: "I36"},
// {SQRef: "G33", ActiveCell: "G33", Pane: "topRight"}, // {SQRef: "G33", ActiveCell: "G33", Pane: "topRight"},
// {SQRef: "J60", ActiveCell: "J60", Pane: "bottomLeft"}, // {SQRef: "J60", ActiveCell: "J60", Pane: "bottomLeft"},
@ -1215,7 +1217,9 @@ func (f *File) SetHeaderFooter(sheet string, settings *HeaderFooterOptions) erro
// err := f.ProtectSheet("Sheet1", &excelize.SheetProtectionOptions{ // err := f.ProtectSheet("Sheet1", &excelize.SheetProtectionOptions{
// AlgorithmName: "SHA-512", // AlgorithmName: "SHA-512",
// Password: "password", // Password: "password",
// EditScenarios: false, // SelectLockedCells: true,
// SelectUnlockedCells: true,
// EditScenarios: true,
// }) // })
func (f *File) ProtectSheet(sheet string, opts *SheetProtectionOptions) error { func (f *File) ProtectSheet(sheet string, opts *SheetProtectionOptions) error {
ws, err := f.workSheetReader(sheet) ws, err := f.workSheetReader(sheet)
@ -1223,29 +1227,25 @@ func (f *File) ProtectSheet(sheet string, opts *SheetProtectionOptions) error {
return err return err
} }
if opts == nil { if opts == nil {
opts = &SheetProtectionOptions{ return ErrParameterInvalid
EditObjects: true,
EditScenarios: true,
SelectLockedCells: true,
}
} }
ws.SheetProtection = &xlsxSheetProtection{ ws.SheetProtection = &xlsxSheetProtection{
AutoFilter: opts.AutoFilter, AutoFilter: !opts.AutoFilter,
DeleteColumns: opts.DeleteColumns, DeleteColumns: !opts.DeleteColumns,
DeleteRows: opts.DeleteRows, DeleteRows: !opts.DeleteRows,
FormatCells: opts.FormatCells, FormatCells: !opts.FormatCells,
FormatColumns: opts.FormatColumns, FormatColumns: !opts.FormatColumns,
FormatRows: opts.FormatRows, FormatRows: !opts.FormatRows,
InsertColumns: opts.InsertColumns, InsertColumns: !opts.InsertColumns,
InsertHyperlinks: opts.InsertHyperlinks, InsertHyperlinks: !opts.InsertHyperlinks,
InsertRows: opts.InsertRows, InsertRows: !opts.InsertRows,
Objects: opts.EditObjects, Objects: !opts.EditObjects,
PivotTables: opts.PivotTables, PivotTables: !opts.PivotTables,
Scenarios: opts.EditScenarios, Scenarios: !opts.EditScenarios,
SelectLockedCells: opts.SelectLockedCells, SelectLockedCells: !opts.SelectLockedCells,
SelectUnlockedCells: opts.SelectUnlockedCells, SelectUnlockedCells: !opts.SelectUnlockedCells,
Sheet: true, Sheet: true,
Sort: opts.Sort, Sort: !opts.Sort,
} }
if opts.Password != "" { if opts.Password != "" {
if opts.AlgorithmName == "" { if opts.AlgorithmName == "" {
@ -1532,7 +1532,7 @@ func (f *File) GetPageLayout(sheet string) (PageLayoutOptions, error) {
// or worksheet. If not specified scope, the default scope is workbook. // or worksheet. If not specified scope, the default scope is workbook.
// For example: // For example:
// //
// f.SetDefinedName(&excelize.DefinedName{ // err := f.SetDefinedName(&excelize.DefinedName{
// Name: "Amount", // Name: "Amount",
// RefersTo: "Sheet1!$A$2:$D$5", // RefersTo: "Sheet1!$A$2:$D$5",
// Comment: "defined name comment", // Comment: "defined name comment",
@ -1579,7 +1579,7 @@ func (f *File) SetDefinedName(definedName *DefinedName) error {
// workbook or worksheet. If not specified scope, the default scope is // workbook or worksheet. If not specified scope, the default scope is
// workbook. For example: // workbook. For example:
// //
// f.DeleteDefinedName(&excelize.DefinedName{ // err := f.DeleteDefinedName(&excelize.DefinedName{
// Name: "Amount", // Name: "Amount",
// Scope: "Sheet2", // Scope: "Sheet2",
// }) // })

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -56,10 +56,12 @@ type StreamWriter struct {
// streamWriter, err := file.NewStreamWriter("Sheet1") // streamWriter, err := file.NewStreamWriter("Sheet1")
// if err != nil { // if err != nil {
// fmt.Println(err) // fmt.Println(err)
// return
// } // }
// styleID, err := file.NewStyle(&excelize.Style{Font: &excelize.Font{Color: "#777777"}}) // styleID, err := file.NewStyle(&excelize.Style{Font: &excelize.Font{Color: "#777777"}})
// if err != nil { // if err != nil {
// fmt.Println(err) // fmt.Println(err)
// return
// } // }
// if err := streamWriter.SetRow("A1", // if err := streamWriter.SetRow("A1",
// []interface{}{ // []interface{}{
@ -71,6 +73,7 @@ type StreamWriter struct {
// }, // },
// excelize.RowOpts{Height: 45, Hidden: false}); err != nil { // excelize.RowOpts{Height: 45, Hidden: false}); err != nil {
// fmt.Println(err) // fmt.Println(err)
// return
// } // }
// for rowID := 2; rowID <= 102400; rowID++ { // for rowID := 2; rowID <= 102400; rowID++ {
// row := make([]interface{}, 50) // row := make([]interface{}, 50)
@ -80,10 +83,12 @@ type StreamWriter struct {
// cell, _ := excelize.CoordinatesToCellName(1, rowID) // cell, _ := excelize.CoordinatesToCellName(1, rowID)
// if err := streamWriter.SetRow(cell, row); err != nil { // if err := streamWriter.SetRow(cell, row); err != nil {
// fmt.Println(err) // fmt.Println(err)
// return
// } // }
// } // }
// if err := streamWriter.Flush(); err != nil { // if err := streamWriter.Flush(); err != nil {
// fmt.Println(err) // fmt.Println(err)
// return
// } // }
// if err := file.SaveAs("Book1.xlsx"); err != nil { // if err := file.SaveAs("Book1.xlsx"); err != nil {
// fmt.Println(err) // fmt.Println(err)
@ -155,9 +160,9 @@ func (f *File) NewStreamWriter(sheet string) (*StreamWriter, error) {
// called after the rows are written but before Flush. // called after the rows are written but before Flush.
// //
// See File.AddTable for details on the table format. // See File.AddTable for details on the table format.
func (sw *StreamWriter) AddTable(reference string, opts *TableOptions) error { func (sw *StreamWriter) AddTable(rangeRef string, opts *TableOptions) error {
options := parseTableOptions(opts) options := parseTableOptions(opts)
coordinates, err := rangeRefToCoordinates(reference) coordinates, err := rangeRefToCoordinates(rangeRef)
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -1966,9 +1966,21 @@ func parseFormatStyleSet(style *Style) (*Style, error) {
// as date type in Uruguay (Spanish) format for Sheet1!A6: // as date type in Uruguay (Spanish) format for Sheet1!A6:
// //
// f := excelize.NewFile() // f := excelize.NewFile()
// f.SetCellValue("Sheet1", "A6", 42920.5) // defer func() {
// if err := f.Close(); err != nil {
// fmt.Println(err)
// }
// }()
// if err := f.SetCellValue("Sheet1", "A6", 42920.5); err != nil {
// fmt.Println(err)
// return
// }
// exp := "[$-380A]dddd\\,\\ dd\" de \"mmmm\" de \"yyyy;@" // exp := "[$-380A]dddd\\,\\ dd\" de \"mmmm\" de \"yyyy;@"
// style, err := f.NewStyle(&excelize.Style{CustomNumFmt: &exp}) // style, err := f.NewStyle(&excelize.Style{CustomNumFmt: &exp})
// if err != nil {
// fmt.Println(err)
// return
// }
// err = f.SetCellStyle("Sheet1", "A6", "A6", style) // err = f.SetCellStyle("Sheet1", "A6", "A6", style)
// //
// Cell Sheet1!A6 in the Excel Application: martes, 04 de Julio de 2017 // Cell Sheet1!A6 in the Excel Application: martes, 04 de Julio de 2017
@ -2978,8 +2990,8 @@ func (f *File) SetCellStyle(sheet, hCell, vCell string, styleID int) error {
// }, // },
// ) // )
// //
// type: minimum - The minimum parameter is used to set the lower limiting value // type: Minimum - The 'Minimum' parameter is used to set the lower limiting
// when the criteria is either "between" or "not between". // value when the criteria is either "between" or "not between".
// //
// // Highlight cells rules: between... // // Highlight cells rules: between...
// err := f.SetConditionalFormat("Sheet1", "A1:A10", // err := f.SetConditionalFormat("Sheet1", "A1:A10",
@ -2994,9 +3006,9 @@ func (f *File) SetCellStyle(sheet, hCell, vCell string, styleID int) error {
// }, // },
// ) // )
// //
// type: maximum - The maximum parameter is used to set the upper limiting value // type: Maximum - The 'Maximum' parameter is used to set the upper limiting
// when the criteria is either "between" or "not between". See the previous // value when the criteria is either "between" or "not between". See the
// example. // previous example.
// //
// type: average - The average type is used to specify Excel's "Average" style // type: average - The average type is used to specify Excel's "Average" style
// conditional format: // conditional format:
@ -3178,7 +3190,7 @@ func (f *File) SetCellStyle(sheet, hCell, vCell string, styleID int) error {
// MaxColor - Same as MinColor, see above. // MaxColor - Same as MinColor, see above.
// //
// BarColor - Used for data_bar. Same as MinColor, see above. // BarColor - Used for data_bar. Same as MinColor, see above.
func (f *File) SetConditionalFormat(sheet, reference string, opts []ConditionalFormatOptions) error { func (f *File) SetConditionalFormat(sheet, rangeRef string, opts []ConditionalFormatOptions) error {
drawContFmtFunc := map[string]func(p int, ct string, fmtCond *ConditionalFormatOptions) *xlsxCfRule{ drawContFmtFunc := map[string]func(p int, ct string, fmtCond *ConditionalFormatOptions) *xlsxCfRule{
"cellIs": drawCondFmtCellIs, "cellIs": drawCondFmtCellIs,
"top10": drawCondFmtTop10, "top10": drawCondFmtTop10,
@ -3214,7 +3226,7 @@ func (f *File) SetConditionalFormat(sheet, reference string, opts []ConditionalF
} }
ws.ConditionalFormatting = append(ws.ConditionalFormatting, &xlsxConditionalFormatting{ ws.ConditionalFormatting = append(ws.ConditionalFormatting, &xlsxConditionalFormatting{
SQRef: reference, SQRef: rangeRef,
CfRule: cfRule, CfRule: cfRule,
}) })
return err return err
@ -3367,13 +3379,13 @@ func (f *File) GetConditionalFormats(sheet string) (map[string][]ConditionalForm
// UnsetConditionalFormat provides a function to unset the conditional format // UnsetConditionalFormat provides a function to unset the conditional format
// by given worksheet name and range reference. // by given worksheet name and range reference.
func (f *File) UnsetConditionalFormat(sheet, reference string) error { func (f *File) UnsetConditionalFormat(sheet, rangeRef string) error {
ws, err := f.workSheetReader(sheet) ws, err := f.workSheetReader(sheet)
if err != nil { if err != nil {
return err return err
} }
for i, cf := range ws.ConditionalFormatting { for i, cf := range ws.ConditionalFormatting {
if cf.SQRef == reference { if cf.SQRef == rangeRef {
ws.ConditionalFormatting = append(ws.ConditionalFormatting[:i], ws.ConditionalFormatting[i+1:]...) ws.ConditionalFormatting = append(ws.ConditionalFormatting[:i], ws.ConditionalFormatting[i+1:]...)
return nil return nil
} }

View File

@ -158,9 +158,9 @@ func TestSetConditionalFormat(t *testing.T) {
for _, testCase := range cases { for _, testCase := range cases {
f := NewFile() f := NewFile()
const sheet = "Sheet1" const sheet = "Sheet1"
const cellRange = "A1:A1" const rangeRef = "A1:A1"
err := f.SetConditionalFormat(sheet, cellRange, testCase.format) err := f.SetConditionalFormat(sheet, rangeRef, testCase.format)
if err != nil { if err != nil {
t.Fatalf("%s", err) t.Fatalf("%s", err)
} }
@ -170,7 +170,7 @@ func TestSetConditionalFormat(t *testing.T) {
cf := ws.ConditionalFormatting cf := ws.ConditionalFormatting
assert.Len(t, cf, 1, testCase.label) assert.Len(t, cf, 1, testCase.label)
assert.Len(t, cf[0].CfRule, 1, testCase.label) assert.Len(t, cf[0].CfRule, 1, testCase.label)
assert.Equal(t, cellRange, cf[0].SQRef, testCase.label) assert.Equal(t, rangeRef, cf[0].SQRef, testCase.label)
assert.EqualValues(t, testCase.rules, cf[0].CfRule, testCase.label) assert.EqualValues(t, testCase.rules, cf[0].CfRule, testCase.label)
} }
} }

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -39,6 +39,7 @@ func parseTableOptions(opts *TableOptions) *TableOptions {
// //
// Create a table of F2:H6 on Sheet2 with format set: // Create a table of F2:H6 on Sheet2 with format set:
// //
// disable := false
// err := f.AddTable("Sheet2", "F2:H6", &excelize.TableOptions{ // err := f.AddTable("Sheet2", "F2:H6", &excelize.TableOptions{
// Name: "table", // Name: "table",
// StyleName: "TableStyleMedium2", // StyleName: "TableStyleMedium2",
@ -60,10 +61,10 @@ func parseTableOptions(opts *TableOptions) *TableOptions {
// TableStyleLight1 - TableStyleLight21 // TableStyleLight1 - TableStyleLight21
// TableStyleMedium1 - TableStyleMedium28 // TableStyleMedium1 - TableStyleMedium28
// TableStyleDark1 - TableStyleDark11 // TableStyleDark1 - TableStyleDark11
func (f *File) AddTable(sheet, reference string, opts *TableOptions) error { func (f *File) AddTable(sheet, rangeRef string, opts *TableOptions) error {
options := parseTableOptions(opts) options := parseTableOptions(opts)
// Coordinate conversion, convert C1:B3 to 2,0,1,2. // Coordinate conversion, convert C1:B3 to 2,0,1,2.
coordinates, err := rangeRefToCoordinates(reference) coordinates, err := rangeRefToCoordinates(rangeRef)
if err != nil { if err != nil {
return err return err
} }
@ -261,8 +262,8 @@ func (f *File) addTable(sheet, tableXML string, x1, y1, x2, y2, i int, opts *Tab
// x < 2000 // x < 2000
// col < 2000 // col < 2000
// Price < 2000 // Price < 2000
func (f *File) AutoFilter(sheet, reference string, opts *AutoFilterOptions) error { func (f *File) AutoFilter(sheet, rangeRef string, opts *AutoFilterOptions) error {
coordinates, err := rangeRefToCoordinates(reference) coordinates, err := rangeRefToCoordinates(rangeRef)
if err != nil { if err != nil {
return err return err
} }
@ -302,13 +303,13 @@ func (f *File) AutoFilter(sheet, reference string, opts *AutoFilterOptions) erro
wb.DefinedNames.DefinedName = append(wb.DefinedNames.DefinedName, d) wb.DefinedNames.DefinedName = append(wb.DefinedNames.DefinedName, d)
} }
} }
refRange := coordinates[2] - coordinates[0] columns := coordinates[2] - coordinates[0]
return f.autoFilter(sheet, ref, refRange, coordinates[0], opts) return f.autoFilter(sheet, ref, columns, coordinates[0], opts)
} }
// autoFilter provides a function to extract the tokens from the filter // autoFilter provides a function to extract the tokens from the filter
// expression. The tokens are mainly non-whitespace groups. // expression. The tokens are mainly non-whitespace groups.
func (f *File) autoFilter(sheet, ref string, refRange, col int, opts *AutoFilterOptions) error { func (f *File) autoFilter(sheet, ref string, columns, col int, opts *AutoFilterOptions) error {
ws, err := f.workSheetReader(sheet) ws, err := f.workSheetReader(sheet)
if err != nil { if err != nil {
return err return err
@ -330,7 +331,7 @@ func (f *File) autoFilter(sheet, ref string, refRange, col int, opts *AutoFilter
return err return err
} }
offset := fsCol - col offset := fsCol - col
if offset < 0 || offset > refRange { if offset < 0 || offset > columns {
return fmt.Errorf("incorrect index of column '%s'", opts.Column) return fmt.Errorf("incorrect index of column '%s'", opts.Column)
} }

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
// //
// This file contains default templates for XML files we don't yet populated // This file contains default templates for XML files we don't yet populated
// based on content. // based on content.

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -534,8 +534,8 @@ type ChartAxis struct {
// ChartDimension directly maps the dimension of the chart. // ChartDimension directly maps the dimension of the chart.
type ChartDimension struct { type ChartDimension struct {
Width *int Width uint
Height *int Height uint
} }
// ChartPlotArea directly maps the format settings of the plot area. // ChartPlotArea directly maps the format settings of the plot area.
@ -552,7 +552,7 @@ type ChartPlotArea struct {
type Chart struct { type Chart struct {
Type string Type string
Series []ChartSeries Series []ChartSeries
Format PictureOptions Format GraphicOptions
Dimension ChartDimension Dimension ChartDimension
Legend ChartLegend Legend ChartLegend
Title ChartTitle Title ChartTitle
@ -567,8 +567,7 @@ type Chart struct {
// ChartLegend directly maps the format settings of the chart legend. // ChartLegend directly maps the format settings of the chart legend.
type ChartLegend struct { type ChartLegend struct {
None bool Position string
Position *string
ShowLegendKey bool ShowLegendKey bool
} }

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -9,7 +9,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize
@ -561,16 +561,16 @@ type xdrTxBody struct {
P []*aP `xml:"a:p"` P []*aP `xml:"a:p"`
} }
// PictureOptions directly maps the format settings of the picture. // GraphicOptions directly maps the format settings of the picture.
type PictureOptions struct { type GraphicOptions struct {
PrintObject *bool PrintObject *bool
Locked *bool Locked *bool
LockAspectRatio bool LockAspectRatio bool
AutoFit bool AutoFit bool
OffsetX int OffsetX int
OffsetY int OffsetY int
XScale *float64 ScaleX float64
YScale *float64 ScaleY float64
Hyperlink string Hyperlink string
HyperlinkType string HyperlinkType string
Positioning string Positioning string
@ -580,9 +580,9 @@ type PictureOptions struct {
type Shape struct { type Shape struct {
Macro string Macro string
Type string Type string
Width *int Width uint
Height *int Height uint
Format PictureOptions Format GraphicOptions
Color ShapeColor Color ShapeColor
Line ShapeLine Line ShapeLine
Paragraph []ShapeParagraph Paragraph []ShapeParagraph

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize

View File

@ -1,4 +1,4 @@
// Copyright 2016 - 2022 The excelize Authors. All rights reserved. Use of // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
// this source code is governed by a BSD-style license that can be found in // this source code is governed by a BSD-style license that can be found in
// the LICENSE file. // the LICENSE file.
// //
@ -7,7 +7,7 @@
// writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
// Supports complex components by high compatibility, and provided streaming // Supports complex components by high compatibility, and provided streaming
// API for generating or reading data from a worksheet with huge amounts of // API for generating or reading data from a worksheet with huge amounts of
// data. This library needs Go version 1.15 or later. // data. This library needs Go version 1.16 or later.
package excelize package excelize