This closes #1584, fix graphic object counter issues

- Optimize number format parser
- Update documentation for the `AddFormControl` function
- Update unit tests
- Upgrade dependencies package
This commit is contained in:
xuri 2023-07-25 00:08:24 +08:00
parent 8d996ca138
commit 7f3d663628
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
6 changed files with 52 additions and 52 deletions

8
go.mod
View File

@ -7,11 +7,11 @@ require (
github.com/richardlehane/mscfb v1.0.4
github.com/stretchr/testify v1.8.0
github.com/xuri/efp v0.0.0-20230422071738-01f4e37c47e9
github.com/xuri/nfp v0.0.0-20230503010013-3f38cdbb0b83
golang.org/x/crypto v0.9.0
github.com/xuri/nfp v0.0.0-20230723160540-a7d120392641
golang.org/x/crypto v0.11.0
golang.org/x/image v0.5.0
golang.org/x/net v0.10.0
golang.org/x/text v0.9.0
golang.org/x/net v0.12.0
golang.org/x/text v0.11.0
)
require github.com/richardlehane/msoleps v1.0.3 // indirect

16
go.sum
View File

@ -17,13 +17,13 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/xuri/efp v0.0.0-20230422071738-01f4e37c47e9 h1:ge5g8vsTQclA5lXDi+PuiAFw5GMIlMHOB/5e1hsf96E=
github.com/xuri/efp v0.0.0-20230422071738-01f4e37c47e9/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI=
github.com/xuri/nfp v0.0.0-20230503010013-3f38cdbb0b83 h1:xVwnvkzzi+OiwhIkWOXvh1skFI6bagk8OvGuazM80Rw=
github.com/xuri/nfp v0.0.0-20230503010013-3f38cdbb0b83/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
github.com/xuri/nfp v0.0.0-20230723160540-a7d120392641 h1:1SQuQwUorWlROdGAbsAJrMInj02yCUsYFNi/MzTJ6cA=
github.com/xuri/nfp v0.0.0-20230723160540-a7d120392641/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
golang.org/x/image v0.5.0/go.mod h1:FVC7BI/5Ym8R25iw5OLsgshdUBbT1h5jZTpA+mvAdZ4=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@ -32,8 +32,9 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
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.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -44,16 +45,19 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.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-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
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.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
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.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=

View File

@ -308,23 +308,20 @@ func (f *File) addSheetPicture(sheet string, rID int) error {
// countDrawings provides a function to get drawing files count storage in the
// folder xl/drawings.
func (f *File) countDrawings() int {
var c1, c2 int
drawings := map[string]struct{}{}
f.Pkg.Range(func(k, v interface{}) bool {
if strings.Contains(k.(string), "xl/drawings/drawing") {
c1++
drawings[k.(string)] = struct{}{}
}
return true
})
f.Drawings.Range(func(rel, value interface{}) bool {
if strings.Contains(rel.(string), "xl/drawings/drawing") {
c2++
drawings[rel.(string)] = struct{}{}
}
return true
})
if c1 < c2 {
return c2
}
return c1
return len(drawings)
}
// addDrawingPicture provides a function to add picture by given sheet,

View File

@ -113,7 +113,7 @@ func TestAddPivotTable(t *testing.T) {
assert.NoError(t, err)
assert.NoError(t, f.AddPivotTable(&PivotTableOptions{
DataRange: "Sheet1!$A$1:$E$31",
PivotTableRange: "Sheet2!$A$1:$AR$15",
PivotTableRange: "Sheet2!$A$1:$AN$17",
Rows: []PivotTableField{{Data: "Month"}},
Columns: []PivotTableField{{Data: "Region", DefaultSubtotal: true}, {Data: "Type", DefaultSubtotal: true}, {Data: "Year"}},
Data: []PivotTableField{{Data: "Sales", Subtotal: "Min", Name: "Summarize by Min"}},
@ -126,7 +126,7 @@ func TestAddPivotTable(t *testing.T) {
}))
assert.NoError(t, f.AddPivotTable(&PivotTableOptions{
DataRange: "Sheet1!$A$1:$E$31",
PivotTableRange: "Sheet2!$A$18:$AR$54",
PivotTableRange: "Sheet2!$A$20:$AR$60",
Rows: []PivotTableField{{Data: "Month", DefaultSubtotal: true}, {Data: "Type"}},
Columns: []PivotTableField{{Data: "Region", DefaultSubtotal: true}, {Data: "Year"}},
Data: []PivotTableField{{Data: "Sales", Subtotal: "Product", Name: "Summarize by Product"}},
@ -146,7 +146,7 @@ func TestAddPivotTable(t *testing.T) {
}))
assert.NoError(t, f.AddPivotTable(&PivotTableOptions{
DataRange: "dataRange",
PivotTableRange: "Sheet2!$A$57:$AJ$91",
PivotTableRange: "Sheet2!$A$65:$AJ$100",
Rows: []PivotTableField{{Data: "Month", DefaultSubtotal: true}, {Data: "Year"}},
Columns: []PivotTableField{{Data: "Region", DefaultSubtotal: true}, {Data: "Type"}},
Data: []PivotTableField{{Data: "Sales", Subtotal: "Sum", Name: "Sum of Sales"}, {Data: "Sales", Subtotal: "Average", Name: "Average of Sales"}},

View File

@ -50,13 +50,13 @@ func parseShapeOptions(opts *Shape) (*Shape, error) {
}
// AddShape provides the method to add shape in a sheet by given worksheet
// index, shape format set (such as offset, scale, aspect ratio setting and
// print settings) and properties set. For example, add text box (rect shape)
// in Sheet1:
// name and shape format set (such as offset, scale, aspect ratio setting and
// print settings). For example, add text box (rect shape) in Sheet1:
//
// lineWidth := 1.2
// err := f.AddShape("Sheet1", "G6",
// err := f.AddShape("Sheet1",
// &excelize.Shape{
// Cell: "G6",
// Type: "rect",
// Line: excelize.ShapeLine{Color: "4286F4", Width: &lineWidth},
// Fill: excelize.Fill{Color: []string{"8EB9FF"}, Pattern: 1},

55
vml.go
View File

@ -229,22 +229,19 @@ func (f *File) addComment(commentsXML string, opts vmlOptions) error {
// countComments provides a function to get comments files count storage in
// the folder xl.
func (f *File) countComments() int {
c1, c2 := 0, 0
comments := map[string]struct{}{}
f.Pkg.Range(func(k, v interface{}) bool {
if strings.Contains(k.(string), "xl/comments") {
c1++
comments[k.(string)] = struct{}{}
}
return true
})
for rel := range f.Comments {
if strings.Contains(rel, "xl/comments") {
c2++
comments[rel] = struct{}{}
}
}
if c1 < c2 {
return c2
}
return c1
return len(comments)
}
// commentsReader provides a function to get the pointer to the structure
@ -281,12 +278,12 @@ func (f *File) commentsWriter() {
// XLSM or XLTM. Scroll value must be between 0 and 30000.
//
// Example 1, add button form control with macro, rich-text, custom button size,
// print property on Sheet1!A1, and let the button do not move or size with
// print property on Sheet1!A2, and let the button do not move or size with
// cells:
//
// enable := true
// err := f.AddFormControl("Sheet1", excelize.FormControl{
// Cell: "A1",
// Cell: "A2",
// Type: excelize.FormControlButton,
// Macro: "Button1_Click",
// Width: 140,
@ -321,12 +318,14 @@ func (f *File) commentsWriter() {
// Checked: true,
// })
//
// Example 3, add spin button form control on Sheet1!A2 to increase or decrease
// Example 3, add spin button form control on Sheet1!B1 to increase or decrease
// the value of Sheet1!A1:
//
// err := f.AddFormControl("Sheet1", excelize.FormControl{
// Cell: "A2",
// Cell: "B1",
// Type: excelize.FormControlSpinButton,
// Width: 15,
// Height: 40,
// CurrentVal: 7,
// MinVal: 5,
// MaxVal: 10,
@ -338,14 +337,17 @@ func (f *File) commentsWriter() {
// the value of Sheet1!A1 by click the scroll arrows or drag the scroll box:
//
// err := f.AddFormControl("Sheet1", excelize.FormControl{
// Cell: "A2",
// Type: excelize.FormControlScrollBar,
// CurrentVal: 50,
// MinVal: 10,
// MaxVal: 100,
// IncChange: 1,
// PageChange: 1,
// CellLink: "A1",
// Cell: "A2",
// Type: excelize.FormControlScrollBar,
// Width: 140,
// Height: 20,
// CurrentVal: 50,
// MinVal: 10,
// MaxVal: 100,
// IncChange: 1,
// PageChange: 1,
// CellLink: "A1",
// Horizontally: true,
// })
func (f *File) AddFormControl(sheet string, opts FormControl) error {
return f.addVMLObject(vmlOptions{
@ -355,9 +357,9 @@ func (f *File) AddFormControl(sheet string, opts FormControl) error {
// DeleteFormControl provides the method to delete form control in a worksheet
// by given worksheet name and cell reference. For example, delete the form
// control in Sheet1!$A$30:
// control in Sheet1!$A$1:
//
// err := f.DeleteFormControl("Sheet1", "A30")
// err := f.DeleteFormControl("Sheet1", "A1")
func (f *File) DeleteFormControl(sheet, cell string) error {
ws, err := f.workSheetReader(sheet)
if err != nil {
@ -430,22 +432,19 @@ func (f *File) DeleteFormControl(sheet, cell string) error {
// countVMLDrawing provides a function to get VML drawing files count storage
// in the folder xl/drawings.
func (f *File) countVMLDrawing() int {
c1, c2 := 0, 0
drawings := map[string]struct{}{}
f.Pkg.Range(func(k, v interface{}) bool {
if strings.Contains(k.(string), "xl/drawings/vmlDrawing") {
c1++
drawings[k.(string)] = struct{}{}
}
return true
})
for rel := range f.VMLDrawing {
if strings.Contains(rel, "xl/drawings/vmlDrawing") {
c2++
drawings[rel] = struct{}{}
}
}
if c1 < c2 {
return c2
}
return c1
return len(drawings)
}
// decodeVMLDrawingReader provides a function to get the pointer to the