From 7363c1e3337c5f0d9c70cc8af7504b3f8c092ab4 Mon Sep 17 00:00:00 2001 From: xuri Date: Thu, 13 Oct 2022 00:02:53 +0800 Subject: [PATCH] Go 1.16 and later required, migration of deprecation package `ioutil` - Improving performance for stream writer `SetRow` function, reduces memory usage over and speedup about 19% - Update dependencies module - Update GitHub workflow --- .github/workflows/go.yml | 2 +- README.md | 2 +- README_zh.md | 2 +- crypt_test.go | 4 +-- excelize.go | 5 ++- excelize_test.go | 3 +- go.mod | 17 +++++----- go.sum | 40 +++++++++++++++++------ lib.go | 5 ++- picture.go | 9 +++--- picture_test.go | 12 +++---- rows.go | 3 +- sheet.go | 3 +- stream.go | 68 +++++++++++++++++++++++++++++----------- stream_test.go | 3 +- 15 files changed, 110 insertions(+), 68 deletions(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 4026b719ba..46f92f5fe4 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -5,7 +5,7 @@ jobs: test: strategy: matrix: - go-version: [1.15.x, 1.16.x, 1.17.x, 1.18.x, 1.19.x] + go-version: [1.16.x, 1.17.x, 1.18.x, 1.19.x] os: [ubuntu-latest, macos-latest, windows-latest] targetplatform: [x86, x64] diff --git a/README.md b/README.md index 6ab549edf8..008efc51b5 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ ## Introduction -Excelize is a library written in pure Go providing a set of functions that allow you to write to and read from XLAM / XLSM / XLSX / XLTM / XLTX files. Supports reading and writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. Supports complex components by high compatibility, and provided streaming API for generating or reading data from a worksheet with huge amounts of data. This library needs Go version 1.15 or later. The full API docs can be seen using go's built-in documentation tool, or online at [go.dev](https://pkg.go.dev/github.com/xuri/excelize/v2) and [docs reference](https://xuri.me/excelize/). +Excelize is a library written in pure Go providing a set of functions that allow you to write to and read from XLAM / XLSM / XLSX / XLTM / XLTX files. Supports reading and writing spreadsheet documents generated by Microsoft Excel™ 2007 and later. Supports complex components by high compatibility, and provided streaming API for generating or reading data from a worksheet with huge amounts of data. This library needs Go version 1.16 or later. The full docs can be seen using go's built-in documentation tool, or online at [go.dev](https://pkg.go.dev/github.com/xuri/excelize/v2) and [docs reference](https://xuri.me/excelize/). ## Basic Usage diff --git a/README_zh.md b/README_zh.md index d67b63cb03..212bf79be6 100644 --- a/README_zh.md +++ b/README_zh.md @@ -13,7 +13,7 @@ ## 简介 -Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档。支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式,高度兼容带有样式、图片(表)、透视表、切片器等复杂组件的文档,并提供流式读写 API,用于处理包含大规模数据的工作簿。可应用于各类报表平台、云计算、边缘计算等系统。使用本类库要求使用的 Go 语言为 1.15 或更高版本,完整的 API 使用文档请访问 [go.dev](https://pkg.go.dev/github.com/xuri/excelize/v2) 或查看 [参考文档](https://xuri.me/excelize/)。 +Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档。支持 XLAM / XLSM / XLSX / XLTM / XLTX 等多种文档格式,高度兼容带有样式、图片(表)、透视表、切片器等复杂组件的文档,并提供流式读写函数,用于处理包含大规模数据的工作簿。可应用于各类报表平台、云计算、边缘计算等系统。使用本类库要求使用的 Go 语言为 1.16 或更高版本,完整的使用文档请访问 [go.dev](https://pkg.go.dev/github.com/xuri/excelize/v2) 或查看 [参考文档](https://xuri.me/excelize/)。 ## 快速上手 diff --git a/crypt_test.go b/crypt_test.go index 95b6f52cc4..a4a510e2a8 100644 --- a/crypt_test.go +++ b/crypt_test.go @@ -12,7 +12,7 @@ package excelize import ( - "io/ioutil" + "os" "path/filepath" "strings" "testing" @@ -32,7 +32,7 @@ func TestEncrypt(t *testing.T) { assert.Equal(t, "SECRET", cell) assert.NoError(t, f.Close()) // Test decrypt spreadsheet with unsupported encrypt mechanism - raw, err := ioutil.ReadFile(filepath.Join("test", "encryptAES.xlsx")) + raw, err := os.ReadFile(filepath.Join("test", "encryptAES.xlsx")) assert.NoError(t, err) raw[2050] = 3 _, err = Decrypt(raw, &Options{Password: "password"}) diff --git a/excelize.go b/excelize.go index 94d10885ac..987314bf81 100644 --- a/excelize.go +++ b/excelize.go @@ -18,7 +18,6 @@ import ( "encoding/xml" "fmt" "io" - "io/ioutil" "os" "path" "path/filepath" @@ -137,7 +136,7 @@ func newFile() *File { // OpenReader read data stream from io.Reader and return a populated // spreadsheet file. func OpenReader(r io.Reader, opts ...Options) (*File, error) { - b, err := ioutil.ReadAll(r) + b, err := io.ReadAll(r) if err != nil { return nil, err } @@ -488,7 +487,7 @@ func (f *File) AddVBAProject(bin string) error { Type: SourceRelationshipVBAProject, }) } - file, _ := ioutil.ReadFile(filepath.Clean(bin)) + file, _ := os.ReadFile(filepath.Clean(bin)) f.Pkg.Store("xl/vbaProject.bin", file) return err } diff --git a/excelize_test.go b/excelize_test.go index e685b669ee..12d155d6c4 100644 --- a/excelize_test.go +++ b/excelize_test.go @@ -10,7 +10,6 @@ import ( _ "image/gif" _ "image/jpeg" _ "image/png" - "io/ioutil" "math" "os" "path/filepath" @@ -1388,7 +1387,7 @@ func prepareTestBook1() (*File, error) { return nil, err } - file, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.jpg")) + file, err := os.ReadFile(filepath.Join("test", "images", "excel.jpg")) if err != nil { return nil, err } diff --git a/go.mod b/go.mod index 1ce8df3813..644a6aaad5 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,17 @@ module github.com/xuri/excelize/v2 -go 1.15 +go 1.16 require ( - github.com/davecgh/go-spew v1.1.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 github.com/richardlehane/mscfb v1.0.4 - github.com/richardlehane/msoleps v1.0.3 // indirect - github.com/stretchr/testify v1.7.1 + github.com/stretchr/testify v1.8.0 github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 - golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b - golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 - golang.org/x/net v0.0.0-20221004154528-8021a29435af - golang.org/x/text v0.3.7 - gopkg.in/yaml.v3 v3.0.0 // indirect + golang.org/x/crypto v0.0.0-20221012134737-56aed061732a + golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 + golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458 + golang.org/x/text v0.3.8 ) + +require github.com/richardlehane/msoleps v1.0.3 // indirect diff --git a/go.sum b/go.sum index b30b6c14ba..69d81ecaa8 100644 --- a/go.sum +++ b/go.sum @@ -11,31 +11,51 @@ github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTK github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM= github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c= github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M= github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= -golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b h1:huxqepDufQpLLIRXiVkTvnxrzJlpwmIWAObmcCcUFr0= -golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE= -golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +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.0.0-20221012134737-56aed061732a h1:NmSIgad6KjE6VvHciPZuNRTKxGhlPfD6OA87W/PLkqg= +golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +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/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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20221004154528-8021a29435af h1:wv66FM3rLZGPdxpYL+ApnDe2HzHcTFta3z5nsc13wI4= -golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458 h1:MgJ6t2zo8v0tbmLCueaCbF1RM+TtB0rs3Lv8DGtOIpY= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +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/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/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/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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= 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= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA= -gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lib.go b/lib.go index 7f388e0154..685571c487 100644 --- a/lib.go +++ b/lib.go @@ -18,7 +18,6 @@ import ( "encoding/xml" "fmt" "io" - "io/ioutil" "math/big" "os" "regexp" @@ -73,7 +72,7 @@ func (f *File) ReadZipReader(r *zip.Reader) (map[string][]byte, int, error) { // unzipToTemp unzip the zip entity to the system temporary directory and // returned the unzipped file path. func (f *File) unzipToTemp(zipFile *zip.File) (string, error) { - tmp, err := ioutil.TempFile(os.TempDir(), "excelize-") + tmp, err := os.CreateTemp(os.TempDir(), "excelize-") if err != nil { return "", err } @@ -111,7 +110,7 @@ func (f *File) readBytes(name string) []byte { if err != nil { return content } - content, _ = ioutil.ReadAll(file) + content, _ = io.ReadAll(file) f.Pkg.Store(name, content) _ = file.Close() return content diff --git a/picture.go b/picture.go index aceb3f43bd..05e4a51644 100644 --- a/picture.go +++ b/picture.go @@ -17,7 +17,6 @@ import ( "encoding/xml" "image" "io" - "io/ioutil" "os" "path" "path/filepath" @@ -115,7 +114,7 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error { if !ok { return ErrImgExt } - file, _ := ioutil.ReadFile(filepath.Clean(picture)) + file, _ := os.ReadFile(filepath.Clean(picture)) _, name := filepath.Split(picture) return f.AddPictureFromBytes(sheet, cell, format, name, ext, file) } @@ -129,7 +128,7 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error { // import ( // "fmt" // _ "image/jpeg" -// "io/ioutil" +// "os" // // "github.com/xuri/excelize/v2" // ) @@ -137,7 +136,7 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error { // func main() { // f := excelize.NewFile() // -// file, err := ioutil.ReadFile("image.jpg") +// file, err := os.ReadFile("image.jpg") // if err != nil { // fmt.Println(err) // } @@ -486,7 +485,7 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string { // fmt.Println(err) // return // } -// if err := ioutil.WriteFile(file, raw, 0644); err != nil { +// if err := os.WriteFile(file, raw, 0644); err != nil { // fmt.Println(err) // } func (f *File) GetPicture(sheet, cell string) (string, []byte, error) { diff --git a/picture_test.go b/picture_test.go index d419378ba5..e90de20a35 100644 --- a/picture_test.go +++ b/picture_test.go @@ -7,7 +7,7 @@ import ( _ "image/jpeg" _ "image/png" "io" - "io/ioutil" + "os" "path/filepath" "strings" "testing" @@ -19,7 +19,7 @@ import ( func BenchmarkAddPictureFromBytes(b *testing.B) { f := NewFile() - imgFile, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.png")) + imgFile, err := os.ReadFile(filepath.Join("test", "images", "excel.png")) if err != nil { b.Error("unable to load image for benchmark") } @@ -42,7 +42,7 @@ func TestAddPicture(t *testing.T) { assert.NoError(t, f.AddPicture("Sheet1", "F21", filepath.Join("test", "images", "excel.jpg"), `{"x_offset": 10, "y_offset": 10, "hyperlink": "https://github.com/xuri/excelize", "hyperlink_type": "External", "positioning": "oneCell"}`)) - file, err := ioutil.ReadFile(filepath.Join("test", "images", "excel.png")) + file, err := os.ReadFile(filepath.Join("test", "images", "excel.png")) assert.NoError(t, err) // Test add picture to worksheet with autofit. @@ -114,7 +114,7 @@ func TestGetPicture(t *testing.T) { file, raw, err := f.GetPicture("Sheet1", "F21") assert.NoError(t, err) if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) || - !assert.NoError(t, ioutil.WriteFile(filepath.Join("test", file), raw, 0o644)) { + !assert.NoError(t, os.WriteFile(filepath.Join("test", file), raw, 0o644)) { t.FailNow() } @@ -148,7 +148,7 @@ func TestGetPicture(t *testing.T) { file, raw, err = f.GetPicture("Sheet1", "F21") assert.NoError(t, err) if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) || - !assert.NoError(t, ioutil.WriteFile(filepath.Join("test", file), raw, 0o644)) { + !assert.NoError(t, os.WriteFile(filepath.Join("test", file), raw, 0o644)) { t.FailNow() } @@ -180,7 +180,7 @@ func TestAddDrawingPicture(t *testing.T) { func TestAddPictureFromBytes(t *testing.T) { f := NewFile() - imgFile, err := ioutil.ReadFile("logo.png") + imgFile, err := os.ReadFile("logo.png") assert.NoError(t, err, "Unable to load logo for test") assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 1), "", "logo", ".png", imgFile)) assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), "", "logo", ".png", imgFile)) diff --git a/rows.go b/rows.go index 2960aa461b..1fd6825ba9 100644 --- a/rows.go +++ b/rows.go @@ -16,7 +16,6 @@ import ( "encoding/xml" "fmt" "io" - "io/ioutil" "log" "math" "os" @@ -296,7 +295,7 @@ func (f *File) getFromStringItem(index int) string { defer tempFile.Close() } f.sharedStringItem = [][]uint{} - f.sharedStringTemp, _ = ioutil.TempFile(os.TempDir(), "excelize-") + f.sharedStringTemp, _ = os.CreateTemp(os.TempDir(), "excelize-") f.tempFiles.Store(defaultTempFileSST, f.sharedStringTemp.Name()) var ( inElement string diff --git a/sheet.go b/sheet.go index 71123d7675..ecd39f069a 100644 --- a/sheet.go +++ b/sheet.go @@ -17,7 +17,6 @@ import ( "encoding/xml" "fmt" "io" - "io/ioutil" "log" "os" "path" @@ -479,7 +478,7 @@ func (f *File) SetSheetBackground(sheet, picture string) error { if !ok { return ErrImgExt } - file, _ := ioutil.ReadFile(filepath.Clean(picture)) + file, _ := os.ReadFile(filepath.Clean(picture)) name := f.addMedia(file, ext) sheetXMLPath, _ := f.getSheetXMLPath(sheet) sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetXMLPath, "xl/worksheets/") + ".rels" diff --git a/stream.go b/stream.go index 9f477628fb..62470b59bb 100644 --- a/stream.go +++ b/stream.go @@ -16,7 +16,6 @@ import ( "encoding/xml" "fmt" "io" - "io/ioutil" "os" "reflect" "strconv" @@ -30,7 +29,7 @@ type StreamWriter struct { Sheet string SheetID int sheetWritten bool - cols string + cols strings.Builder worksheet *xlsxWorksheet rawData bufferedWriter mergeCellsCount int @@ -310,24 +309,32 @@ type RowOpts struct { } // marshalAttrs prepare attributes of the row. -func (r *RowOpts) marshalAttrs() (attrs string, err error) { +func (r *RowOpts) marshalAttrs() (strings.Builder, error) { + var ( + err error + attrs strings.Builder + ) if r == nil { - return + return attrs, err } if r.Height > MaxRowHeight { err = ErrMaxRowHeight - return + return attrs, err } if r.StyleID > 0 { - attrs += fmt.Sprintf(` s="%d" customFormat="true"`, r.StyleID) + attrs.WriteString(` s="`) + attrs.WriteString(strconv.Itoa(r.StyleID)) + attrs.WriteString(`" customFormat="1"`) } if r.Height > 0 { - attrs += fmt.Sprintf(` ht="%v" customHeight="true"`, r.Height) + attrs.WriteString(` ht="`) + attrs.WriteString(strconv.FormatFloat(r.Height, 'f', -1, 64)) + attrs.WriteString(`" customHeight="1"`) } if r.Hidden { - attrs += ` hidden="true"` + attrs.WriteString(` hidden="1"`) } - return + return attrs, err } // parseRowOpts provides a function to parse the optional settings for @@ -357,7 +364,11 @@ func (sw *StreamWriter) SetRow(cell string, values []interface{}, opts ...RowOpt if err != nil { return err } - _, _ = fmt.Fprintf(&sw.rawData, ``, row, attrs) + sw.rawData.WriteString(``) for i, val := range values { if val == nil { continue @@ -405,7 +416,14 @@ func (sw *StreamWriter) SetColWidth(min, max int, width float64) error { if min > max { min, max = max, min } - sw.cols += fmt.Sprintf(``, min, max, width) + + sw.cols.WriteString(``) return nil } @@ -515,14 +533,24 @@ func setCellIntFunc(c *xlsxC, val interface{}) (err error) { func writeCell(buf *bufferedWriter, c xlsxC) { _, _ = buf.WriteString(``) if c.F != nil { @@ -549,8 +577,10 @@ func writeCell(buf *bufferedWriter, c xlsxC) { func (sw *StreamWriter) writeSheetData() { if !sw.sheetWritten { bulkAppendFields(&sw.rawData, sw.worksheet, 4, 5) - if len(sw.cols) > 0 { - _, _ = sw.rawData.WriteString("" + sw.cols + "") + if sw.cols.Len() > 0 { + _, _ = sw.rawData.WriteString("") + _, _ = sw.rawData.WriteString(sw.cols.String()) + _, _ = sw.rawData.WriteString("") } _, _ = sw.rawData.WriteString(``) sw.sheetWritten = true @@ -642,7 +672,7 @@ func (bw *bufferedWriter) Sync() (err error) { return nil } if bw.tmp == nil { - bw.tmp, err = ioutil.TempFile(os.TempDir(), "excelize-") + bw.tmp, err = os.CreateTemp(os.TempDir(), "excelize-") if err != nil { // can not use local storage return nil diff --git a/stream_test.go b/stream_test.go index 91aa58099e..c399d63391 100644 --- a/stream_test.go +++ b/stream_test.go @@ -3,7 +3,6 @@ package excelize import ( "encoding/xml" "fmt" - "io/ioutil" "math/rand" "os" "path/filepath" @@ -95,7 +94,7 @@ func TestStreamWriter(t *testing.T) { assert.NoError(t, streamWriter.rawData.Close()) assert.Error(t, streamWriter.Flush()) - streamWriter.rawData.tmp, err = ioutil.TempFile(os.TempDir(), "excelize-") + streamWriter.rawData.tmp, err = os.CreateTemp(os.TempDir(), "excelize-") assert.NoError(t, err) _, err = streamWriter.rawData.Reader() assert.NoError(t, err)