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
This commit is contained in:
xuri 2022-10-13 00:02:53 +08:00
parent 0e657c887b
commit 7363c1e333
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
15 changed files with 109 additions and 67 deletions

View File

@ -5,7 +5,7 @@ jobs:
test: test:
strategy: strategy:
matrix: 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] os: [ubuntu-latest, macos-latest, windows-latest]
targetplatform: [x86, x64] targetplatform: [x86, x64]

View File

@ -13,7 +13,7 @@
## Introduction ## 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 ## Basic Usage

View File

@ -13,7 +13,7 @@
## 简介 ## 简介
Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376ISO/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-376ISO/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/)。
## 快速上手 ## 快速上手

View File

@ -12,7 +12,7 @@
package excelize package excelize
import ( import (
"io/ioutil" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
@ -32,7 +32,7 @@ func TestEncrypt(t *testing.T) {
assert.Equal(t, "SECRET", cell) assert.Equal(t, "SECRET", cell)
assert.NoError(t, f.Close()) assert.NoError(t, f.Close())
// Test decrypt spreadsheet with unsupported encrypt mechanism // 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) assert.NoError(t, err)
raw[2050] = 3 raw[2050] = 3
_, err = Decrypt(raw, &Options{Password: "password"}) _, err = Decrypt(raw, &Options{Password: "password"})

View File

@ -18,7 +18,6 @@ import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@ -137,7 +136,7 @@ func newFile() *File {
// OpenReader read data stream from io.Reader and return a populated // OpenReader read data stream from io.Reader and return a populated
// spreadsheet file. // spreadsheet file.
func OpenReader(r io.Reader, opts ...Options) (*File, error) { func OpenReader(r io.Reader, opts ...Options) (*File, error) {
b, err := ioutil.ReadAll(r) b, err := io.ReadAll(r)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -488,7 +487,7 @@ func (f *File) AddVBAProject(bin string) error {
Type: SourceRelationshipVBAProject, Type: SourceRelationshipVBAProject,
}) })
} }
file, _ := ioutil.ReadFile(filepath.Clean(bin)) file, _ := os.ReadFile(filepath.Clean(bin))
f.Pkg.Store("xl/vbaProject.bin", file) f.Pkg.Store("xl/vbaProject.bin", file)
return err return err
} }

View File

@ -10,7 +10,6 @@ import (
_ "image/gif" _ "image/gif"
_ "image/jpeg" _ "image/jpeg"
_ "image/png" _ "image/png"
"io/ioutil"
"math" "math"
"os" "os"
"path/filepath" "path/filepath"
@ -1388,7 +1387,7 @@ func prepareTestBook1() (*File, error) {
return nil, err 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 { if err != nil {
return nil, err return nil, err
} }

17
go.mod
View File

@ -1,18 +1,17 @@
module github.com/xuri/excelize/v2 module github.com/xuri/excelize/v2
go 1.15 go 1.16
require ( require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/richardlehane/mscfb v1.0.4 github.com/richardlehane/mscfb v1.0.4
github.com/richardlehane/msoleps v1.0.3 // indirect github.com/stretchr/testify v1.8.0
github.com/stretchr/testify v1.7.1
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.0.0-20221005025214-4161e89ecf1b golang.org/x/crypto v0.0.0-20221012134737-56aed061732a
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 golang.org/x/image v0.0.0-20220902085622-e7cb96979f69
golang.org/x/net v0.0.0-20221004154528-8021a29435af golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458
golang.org/x/text v0.3.7 golang.org/x/text v0.3.8
gopkg.in/yaml.v3 v3.0.0 // indirect
) )
require github.com/richardlehane/msoleps v1.0.3 // indirect

40
go.sum
View File

@ -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 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN0AQoVM=
github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= 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/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.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 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c=
github.com/xuri/efp v0.0.0-20220603152613-6918739fd470/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= 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 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M=
github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= 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= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= 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-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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20221004154528-8021a29435af/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= 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-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-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-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/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-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/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.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.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-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 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 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-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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

5
lib.go
View File

@ -18,7 +18,6 @@ import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"math/big" "math/big"
"os" "os"
"regexp" "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 // unzipToTemp unzip the zip entity to the system temporary directory and
// returned the unzipped file path. // returned the unzipped file path.
func (f *File) unzipToTemp(zipFile *zip.File) (string, error) { 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 { if err != nil {
return "", err return "", err
} }
@ -111,7 +110,7 @@ func (f *File) readBytes(name string) []byte {
if err != nil { if err != nil {
return content return content
} }
content, _ = ioutil.ReadAll(file) content, _ = io.ReadAll(file)
f.Pkg.Store(name, content) f.Pkg.Store(name, content)
_ = file.Close() _ = file.Close()
return content return content

View File

@ -17,7 +17,6 @@ import (
"encoding/xml" "encoding/xml"
"image" "image"
"io" "io"
"io/ioutil"
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
@ -115,7 +114,7 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
if !ok { if !ok {
return ErrImgExt return ErrImgExt
} }
file, _ := ioutil.ReadFile(filepath.Clean(picture)) file, _ := os.ReadFile(filepath.Clean(picture))
_, name := filepath.Split(picture) _, name := filepath.Split(picture)
return f.AddPictureFromBytes(sheet, cell, format, name, ext, file) return f.AddPictureFromBytes(sheet, cell, format, name, ext, file)
} }
@ -129,7 +128,7 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
// import ( // import (
// "fmt" // "fmt"
// _ "image/jpeg" // _ "image/jpeg"
// "io/ioutil" // "os"
// //
// "github.com/xuri/excelize/v2" // "github.com/xuri/excelize/v2"
// ) // )
@ -137,7 +136,7 @@ func (f *File) AddPicture(sheet, cell, picture, format string) error {
// func main() { // func main() {
// f := excelize.NewFile() // f := excelize.NewFile()
// //
// file, err := ioutil.ReadFile("image.jpg") // file, err := os.ReadFile("image.jpg")
// if err != nil { // if err != nil {
// fmt.Println(err) // fmt.Println(err)
// } // }
@ -486,7 +485,7 @@ func (f *File) getSheetRelationshipsTargetByID(sheet, rID string) string {
// fmt.Println(err) // fmt.Println(err)
// return // return
// } // }
// if err := ioutil.WriteFile(file, raw, 0644); err != nil { // if err := os.WriteFile(file, raw, 0644); err != nil {
// fmt.Println(err) // fmt.Println(err)
// } // }
func (f *File) GetPicture(sheet, cell string) (string, []byte, error) { func (f *File) GetPicture(sheet, cell string) (string, []byte, error) {

View File

@ -7,7 +7,7 @@ import (
_ "image/jpeg" _ "image/jpeg"
_ "image/png" _ "image/png"
"io" "io"
"io/ioutil" "os"
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
@ -19,7 +19,7 @@ import (
func BenchmarkAddPictureFromBytes(b *testing.B) { func BenchmarkAddPictureFromBytes(b *testing.B) {
f := NewFile() 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 { if err != nil {
b.Error("unable to load image for benchmark") 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"), 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"}`)) `{"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) assert.NoError(t, err)
// Test add picture to worksheet with autofit. // Test add picture to worksheet with autofit.
@ -114,7 +114,7 @@ func TestGetPicture(t *testing.T) {
file, raw, err := f.GetPicture("Sheet1", "F21") file, raw, err := f.GetPicture("Sheet1", "F21")
assert.NoError(t, err) assert.NoError(t, err)
if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) || 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() t.FailNow()
} }
@ -148,7 +148,7 @@ func TestGetPicture(t *testing.T) {
file, raw, err = f.GetPicture("Sheet1", "F21") file, raw, err = f.GetPicture("Sheet1", "F21")
assert.NoError(t, err) assert.NoError(t, err)
if !assert.NotEmpty(t, filepath.Join("test", file)) || !assert.NotEmpty(t, raw) || 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() t.FailNow()
} }
@ -180,7 +180,7 @@ func TestAddDrawingPicture(t *testing.T) {
func TestAddPictureFromBytes(t *testing.T) { func TestAddPictureFromBytes(t *testing.T) {
f := NewFile() 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, 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", 1), "", "logo", ".png", imgFile))
assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), "", "logo", ".png", imgFile)) assert.NoError(t, f.AddPictureFromBytes("Sheet1", fmt.Sprint("A", 50), "", "logo", ".png", imgFile))

View File

@ -16,7 +16,6 @@ import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"math" "math"
"os" "os"
@ -296,7 +295,7 @@ func (f *File) getFromStringItem(index int) string {
defer tempFile.Close() defer tempFile.Close()
} }
f.sharedStringItem = [][]uint{} f.sharedStringItem = [][]uint{}
f.sharedStringTemp, _ = ioutil.TempFile(os.TempDir(), "excelize-") f.sharedStringTemp, _ = os.CreateTemp(os.TempDir(), "excelize-")
f.tempFiles.Store(defaultTempFileSST, f.sharedStringTemp.Name()) f.tempFiles.Store(defaultTempFileSST, f.sharedStringTemp.Name())
var ( var (
inElement string inElement string

View File

@ -17,7 +17,6 @@ import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"log" "log"
"os" "os"
"path" "path"
@ -479,7 +478,7 @@ func (f *File) SetSheetBackground(sheet, picture string) error {
if !ok { if !ok {
return ErrImgExt return ErrImgExt
} }
file, _ := ioutil.ReadFile(filepath.Clean(picture)) file, _ := os.ReadFile(filepath.Clean(picture))
name := f.addMedia(file, ext) name := f.addMedia(file, ext)
sheetXMLPath, _ := f.getSheetXMLPath(sheet) sheetXMLPath, _ := f.getSheetXMLPath(sheet)
sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetXMLPath, "xl/worksheets/") + ".rels" sheetRels := "xl/worksheets/_rels/" + strings.TrimPrefix(sheetXMLPath, "xl/worksheets/") + ".rels"

View File

@ -16,7 +16,6 @@ import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"io" "io"
"io/ioutil"
"os" "os"
"reflect" "reflect"
"strconv" "strconv"
@ -30,7 +29,7 @@ type StreamWriter struct {
Sheet string Sheet string
SheetID int SheetID int
sheetWritten bool sheetWritten bool
cols string cols strings.Builder
worksheet *xlsxWorksheet worksheet *xlsxWorksheet
rawData bufferedWriter rawData bufferedWriter
mergeCellsCount int mergeCellsCount int
@ -310,24 +309,32 @@ type RowOpts struct {
} }
// marshalAttrs prepare attributes of the row. // 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 { if r == nil {
return return attrs, err
} }
if r.Height > MaxRowHeight { if r.Height > MaxRowHeight {
err = ErrMaxRowHeight err = ErrMaxRowHeight
return return attrs, err
} }
if r.StyleID > 0 { 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 { 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 { if r.Hidden {
attrs += ` hidden="true"` attrs.WriteString(` hidden="1"`)
} }
return return attrs, err
} }
// parseRowOpts provides a function to parse the optional settings for // 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 { if err != nil {
return err return err
} }
_, _ = fmt.Fprintf(&sw.rawData, `<row r="%d"%s>`, row, attrs) sw.rawData.WriteString(`<row r="`)
sw.rawData.WriteString(strconv.Itoa(row))
sw.rawData.WriteString(`"`)
sw.rawData.WriteString(attrs.String())
sw.rawData.WriteString(`>`)
for i, val := range values { for i, val := range values {
if val == nil { if val == nil {
continue continue
@ -405,7 +416,14 @@ func (sw *StreamWriter) SetColWidth(min, max int, width float64) error {
if min > max { if min > max {
min, max = max, min min, max = max, min
} }
sw.cols += fmt.Sprintf(`<col min="%d" max="%d" width="%f" customWidth="1"/>`, min, max, width)
sw.cols.WriteString(`<col min="`)
sw.cols.WriteString(strconv.Itoa(min))
sw.cols.WriteString(`" max="`)
sw.cols.WriteString(strconv.Itoa(max))
sw.cols.WriteString(`" width="`)
sw.cols.WriteString(strconv.FormatFloat(width, 'f', -1, 64))
sw.cols.WriteString(`" customWidth="1"/>`)
return nil return nil
} }
@ -515,14 +533,24 @@ func setCellIntFunc(c *xlsxC, val interface{}) (err error) {
func writeCell(buf *bufferedWriter, c xlsxC) { func writeCell(buf *bufferedWriter, c xlsxC) {
_, _ = buf.WriteString(`<c`) _, _ = buf.WriteString(`<c`)
if c.XMLSpace.Value != "" { if c.XMLSpace.Value != "" {
fmt.Fprintf(buf, ` xml:%s="%s"`, c.XMLSpace.Name.Local, c.XMLSpace.Value) _, _ = buf.WriteString(` xml:`)
_, _ = buf.WriteString(c.XMLSpace.Name.Local)
_, _ = buf.WriteString(`="`)
_, _ = buf.WriteString(c.XMLSpace.Value)
_, _ = buf.WriteString(`"`)
} }
fmt.Fprintf(buf, ` r="%s"`, c.R) _, _ = buf.WriteString(` r="`)
_, _ = buf.WriteString(c.R)
_, _ = buf.WriteString(`"`)
if c.S != 0 { if c.S != 0 {
fmt.Fprintf(buf, ` s="%d"`, c.S) _, _ = buf.WriteString(` s="`)
_, _ = buf.WriteString(strconv.Itoa(c.S))
_, _ = buf.WriteString(`"`)
} }
if c.T != "" { if c.T != "" {
fmt.Fprintf(buf, ` t="%s"`, c.T) _, _ = buf.WriteString(` t="`)
_, _ = buf.WriteString(c.T)
_, _ = buf.WriteString(`"`)
} }
_, _ = buf.WriteString(`>`) _, _ = buf.WriteString(`>`)
if c.F != nil { if c.F != nil {
@ -549,8 +577,10 @@ func writeCell(buf *bufferedWriter, c xlsxC) {
func (sw *StreamWriter) writeSheetData() { func (sw *StreamWriter) writeSheetData() {
if !sw.sheetWritten { if !sw.sheetWritten {
bulkAppendFields(&sw.rawData, sw.worksheet, 4, 5) bulkAppendFields(&sw.rawData, sw.worksheet, 4, 5)
if len(sw.cols) > 0 { if sw.cols.Len() > 0 {
_, _ = sw.rawData.WriteString("<cols>" + sw.cols + "</cols>") _, _ = sw.rawData.WriteString("<cols>")
_, _ = sw.rawData.WriteString(sw.cols.String())
_, _ = sw.rawData.WriteString("</cols>")
} }
_, _ = sw.rawData.WriteString(`<sheetData>`) _, _ = sw.rawData.WriteString(`<sheetData>`)
sw.sheetWritten = true sw.sheetWritten = true
@ -642,7 +672,7 @@ func (bw *bufferedWriter) Sync() (err error) {
return nil return nil
} }
if bw.tmp == nil { if bw.tmp == nil {
bw.tmp, err = ioutil.TempFile(os.TempDir(), "excelize-") bw.tmp, err = os.CreateTemp(os.TempDir(), "excelize-")
if err != nil { if err != nil {
// can not use local storage // can not use local storage
return nil return nil

View File

@ -3,7 +3,6 @@ package excelize
import ( import (
"encoding/xml" "encoding/xml"
"fmt" "fmt"
"io/ioutil"
"math/rand" "math/rand"
"os" "os"
"path/filepath" "path/filepath"
@ -95,7 +94,7 @@ func TestStreamWriter(t *testing.T) {
assert.NoError(t, streamWriter.rawData.Close()) assert.NoError(t, streamWriter.rawData.Close())
assert.Error(t, streamWriter.Flush()) 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) assert.NoError(t, err)
_, err = streamWriter.rawData.Reader() _, err = streamWriter.rawData.Reader()
assert.NoError(t, err) assert.NoError(t, err)