diff --git a/.gitignore b/.gitignore index a6b542a..b941df8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ *.dll *.so *.dylib +*.xlsx # Test binary, built with `go test -c` *.test diff --git a/excel/create.go b/excel/create.go new file mode 100644 index 0000000..3e0497c --- /dev/null +++ b/excel/create.go @@ -0,0 +1,82 @@ +// Package excel... +// +// Description : excel... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-11-19 12:25 下午 +package excel + +import ( + "fmt" + + "github.com/xuri/excelize/v2" +) + +// NewExcel 获取excel实例 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:28 下午 2021/11/19 +func NewExcel() *Create { + return &Create{ + fileHandler: excelize.NewFile(), + } +} + +// Create 创建excel +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:27 下午 2021/11/19 +type Create struct { + // fileHandler excel文件处理句柄 + fileHandler *excelize.File +} + +// GenerateSheet 生成sheet +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:43 下午 2021/11/19 +func (c *Create) GenerateSheet(sheetList []SheetData) error { + for _, sheet := range sheetList { + sheetIndex := c.fileHandler.NewSheet(sheet.Name) + if sheet.IsDefault { + // 设置活跃 + c.fileHandler.SetActiveSheet(sheetIndex) + } + for lineIdx, colList := range sheet.Data { + for colIdx, col := range colList { + position := c.getColPosition(colIdx, lineIdx) + if err := c.fileHandler.SetCellValue(sheet.Name, position, col); nil != err { + return err + } + } + } + } + return nil +} + +// Save 保存文件 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:04 下午 2021/11/19 +func (c *Create) Save(fullFilePath string) error { + return c.fileHandler.SaveAs(fullFilePath) +} + +// getColPosition 获取列名 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 3:14 下午 2021/11/19 +func (c *Create) getColPosition(colIndex int, dataLineIndex int) string { + realIndex := colIndex % 26 + first := colIndex / 26 + if first == 0 { + return fmt.Sprintf("%s%d", WordMap[realIndex], dataLineIndex+1) + } + return fmt.Sprintf("%s%s%d", WordMap[first], WordMap[realIndex], dataLineIndex+1) +} diff --git a/excel/define.go b/excel/define.go new file mode 100644 index 0000000..40c9bfe --- /dev/null +++ b/excel/define.go @@ -0,0 +1,61 @@ +// Package excel... +// +// Description : excel... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-11-19 11:57 上午 +package excel + +// ReadResult ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 11:57 上午 2021/11/19 +type ReadResult struct { + Error error // 异常信息 + Result map[string][]map[string]interface{} // 查询结果 sheet => dataList +} + +// SheetData ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:35 下午 2021/11/19 +type SheetData struct { + IsDefault bool // 是否默认工作表 + Name string // sheet 名称 + Data [][]interface{} // 数据列表 +} + +var ( + // WordMap 单元格序号映射 + WordMap = map[int]string{ + 0: "A", + 1: "B", + 2: "C", + 3: "D", + 4: "E", + 5: "F", + 6: "G", + 7: "H", + 8: "I", + 9: "J", + 10: "K", + 11: "L", + 12: "M", + 13: "N", + 14: "O", + 15: "P", + 16: "Q", + 17: "R", + 18: "S", + 19: "T", + 20: "U", + 21: "V", + 22: "W", + 23: "X", + 24: "Y", + 25: "Z", + } +) diff --git a/excel/read.go b/excel/read.go new file mode 100644 index 0000000..7c4a462 --- /dev/null +++ b/excel/read.go @@ -0,0 +1,102 @@ +// Package excel... +// +// Description : excel... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-11-19 3:59 下午 +package excel + +import ( + "github.com/xuri/excelize/v2" +) + +// NewRead 获取读取实例 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:00 下午 2021/11/19 +func NewRead(fullFilePath string, filePassword string) (*Read, error) { + var err error + read := &Read{} + if read.fileHandler, err = excelize.OpenFile(fullFilePath, excelize.Options{Password: filePassword}); nil != err { + return nil, err + } + return read, nil +} + +// Read ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:03 下午 2021/11/19 +type Read struct { + fileHandler *excelize.File +} + +// GetAllSheetList ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:06 下午 2021/11/19 +func (r *Read) GetAllSheetList() []string { + return r.fileHandler.GetSheetList() +} + +// GetAllData 读取全部数据 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:07 下午 2021/11/19 +func (r *Read) GetAllData() (map[string][][]string, error) { + var ( + sheetList []string + result map[string][][]string + err error + ) + sheetList = r.GetAllSheetList() + result = make(map[string][][]string) + for _, sheetName := range sheetList { + if result[sheetName], err = r.fileHandler.GetRows(sheetName); nil != err { + return nil, err + } + } + return result, nil +} + +// GetAllDataToMap 读取全部数据,并返回map结构 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 4:20 下午 2021/11/19 +func (r *Read) GetAllDataToMap(fieldList []string) (map[string][]map[string]string, error) { + var ( + allData map[string][][]string + err error + formatResult map[string][]map[string]string + ) + formatResult = make(map[string][]map[string]string) + if allData, err = r.GetAllData(); nil != err { + return nil, err + } + for sheetName, sheetData := range allData { + formatResult[sheetName] = make([]map[string]string, 0) + for _, lineData := range sheetData { + tmpResult := make(map[string]string) + for idx, colData := range lineData { + if idx >= len(fieldList) { + // 指定的字段列表较短, 自动剔除后面的字段 + break + } + tmpResult[fieldList[idx]] = colData + } + // 字段列表较长, 单元格不足, 自动补齐空字符串 + for i := len(lineData); i < len(fieldList); i++ { + tmpResult[fieldList[i]] = "" + } + formatResult[sheetName] = append(formatResult[sheetName], tmpResult) + } + } + // 格式化数据 + return formatResult, nil +} diff --git a/go.mod b/go.mod index 9b7fcb3..51a1e8d 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.7.0 github.com/tidwall/gjson v1.9.0 + github.com/xuri/excelize/v2 v2.4.1 github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 go.uber.org/zap v1.19.1 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df @@ -54,19 +55,24 @@ require ( github.com/mattn/go-isatty v0.0.12 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/pierrec/lz4 v2.6.0+incompatible // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/richardlehane/mscfb v1.0.3 // indirect + github.com/richardlehane/msoleps v1.0.1 // indirect github.com/tidwall/match v1.0.3 // indirect github.com/tidwall/pretty v1.1.0 // indirect github.com/tklauser/go-sysconf v0.3.9 // indirect github.com/tklauser/numcpus v0.3.0 // indirect github.com/ugorji/go/codec v1.1.7 // indirect + github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect - golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect - golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect + golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect + golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4 // indirect golang.org/x/sys v0.0.0-20211103235746-7861aae1554b // indirect + golang.org/x/text v0.3.7 // indirect google.golang.org/protobuf v1.26.0 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect diff --git a/go.sum b/go.sum index 6e620fb..28ae40c 100644 --- a/go.sum +++ b/go.sum @@ -121,6 +121,8 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OH github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -143,6 +145,10 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/richardlehane/mscfb v1.0.3 h1:rD8TBkYWkObWO0oLDFCbwMeZ4KoalxQy+QgniCj3nKI= +github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= +github.com/richardlehane/msoleps v1.0.1 h1:RfrALnSNXzmXLbGct/P2b4xkFz4e8Gmj/0Vj9M9xC1o= +github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/shirou/gopsutil v3.21.9+incompatible h1:LTLpUnfX81MkHeCtSrwNKZwuW5Id6kCa7/P43NdcNn4= github.com/shirou/gopsutil v3.21.9+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -170,6 +176,10 @@ github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/xdg/scram v1.0.3/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= github.com/xdg/stringprep v1.0.3/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= +github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3 h1:EpI0bqf/eX9SdZDwlMmahKM+CDBgNbsXMhsN28XrM8o= +github.com/xuri/efp v0.0.0-20210322160811-ab561f5b45e3/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/excelize/v2 v2.4.1 h1:veeeFLAJwsNEBPBlDepzPIYS1eLyBVcXNZUW79exZ1E= +github.com/xuri/excelize/v2 v2.4.1/go.mod h1:rSu0C3papjzxQA3sdK8cU544TebhrPUoTOaGPIh0Q1A= github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2 h1:zzrxE1FKn5ryBNl9eKOeqQ58Y/Qpo3Q9QNxKHX5uzzQ= github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2/go.mod h1:hzfGeIUDq/j97IG+FhNqkowIyEcD88LrW6fyU3K3WqY= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -187,8 +197,12 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI= +golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk= +golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -203,8 +217,11 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4 h1:DZshvxDdVoeKIbudAdFEKi+f70l51luSy/7b76ibTY0= +golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -233,8 +250,9 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= 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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=