Files

287 lines
5.6 KiB
Go
Raw Normal View History

2022-03-28 07:01:33 +08:00
package lib
import (
"SciencesServer/utils"
"errors"
"fmt"
"github.com/tealeg/xlsx"
2022-04-14 18:34:12 +08:00
"reflect"
"strings"
2022-03-28 07:01:33 +08:00
)
type Excel struct {
File *xlsx.File
name string
sheet string
2022-04-14 18:34:12 +08:00
header string
2022-03-28 07:01:33 +08:00
title []string
content *ExcelContent
2022-04-14 18:34:12 +08:00
2022-04-14 22:42:09 +08:00
body []map[string]string
2022-03-28 07:01:33 +08:00
}
type ExcelContent struct {
Kind ExcelContentKind
Content []interface{}
}
type ExcelContentKind int
const (
ExcelContentKindForStruct ExcelContentKind = iota + 1
ExcelContentKindForSlice
ExcelContentKindForText
)
type OptionExcel func(excel *Excel)
func WithExcelName(name string) OptionExcel {
return func(excel *Excel) {
excel.name = name
}
}
func WithExcelSheet(sheet string) OptionExcel {
return func(excel *Excel) {
excel.sheet = sheet
}
}
2022-04-14 18:34:12 +08:00
func WithExcelHeader(header string) OptionExcel {
2022-03-28 07:01:33 +08:00
return func(excel *Excel) {
2022-04-14 18:34:12 +08:00
excel.header = header
2022-03-28 07:01:33 +08:00
}
}
2022-04-14 18:34:12 +08:00
func WithExcelTitle(title []string) OptionExcel {
2022-03-28 07:01:33 +08:00
return func(excel *Excel) {
2022-04-14 18:34:12 +08:00
excel.title = title
2022-03-28 07:01:33 +08:00
}
}
2022-04-14 18:34:12 +08:00
func WithExcelContent(content *ExcelContent) OptionExcel {
2022-03-28 07:01:33 +08:00
return func(excel *Excel) {
2022-04-14 18:34:12 +08:00
excel.content = content
2022-03-28 07:01:33 +08:00
}
}
// Export 导出
func (this *Excel) Export() error {
this.File = xlsx.NewFile()
sheet, _ := this.File.AddSheet(this.sheet)
2022-04-14 18:34:12 +08:00
row := new(xlsx.Row)
2022-03-28 07:01:33 +08:00
cell := new(xlsx.Cell)
2022-04-14 18:34:12 +08:00
style := xlsx.NewStyle()
style.Alignment = xlsx.Alignment{
Horizontal: "center",
Vertical: "center",
}
if this.header != "" {
row = sheet.AddRow()
row.SetHeight(28.0)
cell = row.AddCell()
cell.HMerge = 1 // 横向合并
//cell.VMerge = 1 // 纵向合并
cell.Value = this.header
cell.SetStyle(style)
if this.title != nil && len(this.title) > 0 {
cell.HMerge = len(this.title) - 1
}
2022-03-28 07:01:33 +08:00
}
if this.title != nil && len(this.title) > 0 {
2022-04-14 18:34:12 +08:00
row = sheet.AddRow()
2022-03-28 07:01:33 +08:00
for _, v := range this.title {
cell = row.AddCell()
cell.Value = v
}
}
if this.content != nil {
for _, v := range this.content.Content {
row = sheet.AddRow()
if this.content.Kind == ExcelContentKindForStruct {
row.WriteStruct(v, -1)
continue
}
if this.content.Kind == ExcelContentKindForSlice {
row.WriteSlice(v, -1)
continue
}
for i := 0; i < len(this.title); i++ {
cell = row.AddCell()
// TODO存在不同类型请自行加判断
switch v.(type) {
case []string:
cell.Value = v.([]string)[i]
break
case []int:
cell.Value = fmt.Sprintf("%v", v.([]int)[i])
break
case []interface{}:
cell.Value = fmt.Sprintf("%v", v.([]interface{})[i])
break
default:
return errors.New("未知数据类型")
}
}
}
}
return nil
}
2022-04-14 18:34:12 +08:00
// Import 导入
// @file文件信息
2022-04-14 22:42:09 +08:00
// @headers头部标题数量
// @sheet读取的sheet0第一页
func (this *Excel) Import(file string, headers, sheet int) error {
2022-04-14 18:34:12 +08:00
_file, err := xlsx.OpenFile(file)
if err != nil {
return err
}
2022-04-14 22:42:09 +08:00
if len(_file.Sheets) < sheet {
return errors.New("异常sheet")
}
out := make([]map[string]string, 0)
2022-04-14 18:34:12 +08:00
2022-04-14 22:42:09 +08:00
_sheet := _file.Sheets[sheet]
2022-04-14 18:34:12 +08:00
2022-04-14 22:42:09 +08:00
local := 0
2022-04-14 18:34:12 +08:00
2022-04-14 22:42:09 +08:00
if headers > 0 {
local += headers
}
for i := local + 1; i < len(_sheet.Rows); i++ {
body := _sheet.Rows[i].Cells
_data := make(map[string]string, 0)
for key, cell := range _sheet.Rows[local].Cells {
_data[cell.String()] = body[key].String()
2022-04-14 18:34:12 +08:00
}
2022-04-14 22:42:09 +08:00
out = append(out, _data)
2022-04-14 18:34:12 +08:00
}
this.body = out
return nil
}
2022-04-14 22:42:09 +08:00
// Import 导入
// @file文件信息
// @headers标题数量
//func (this *Excel) Import(file string, headers int) error {
// _file, err := xlsx.OpenFile(file)
//
// if err != nil {
// return err
// }
// out := make(map[string][]map[string]string, 0)
// // 循环Sheet
// for _, sheet := range _file.Sheets {
// data := make([]map[string]string, 0)
//
// local := 0
//
// if headers > 0 {
// local += headers
// }
// for i := local + 1; i < len(sheet.Rows); i++ {
// body := sheet.Rows[i].Cells
// _data := make(map[string]string, 0)
//
// for key, cell := range sheet.Rows[local].Cells {
// _data[cell.String()] = body[key].String()
// }
// data = append(data, _data)
// }
// out[sheet.Name] = data
// }
// this.body = out
//
// return nil
//}
2022-03-28 07:01:33 +08:00
// Save 保存
func (this *Excel) Save(path string) error {
return this.File.Save(this.name + ".xlsx")
isExist, err := utils.PathExists(path)
if err != nil {
return err
}
if !isExist {
if err = utils.MkdirAll(path); err != nil {
return err
}
}
fmt.Printf("%s/%s.xlsx", path, this.name)
return nil
//return this.Save(fmt.Sprintf("%s\%s.xlsx", path, this.name))
}
2022-04-14 18:34:12 +08:00
// Analysis 解析
2022-04-14 22:42:09 +08:00
func (this *Excel) Analysis(src interface{}) []interface{} {
if src == nil {
return nil
}
out := make([]interface{}, 0)
// 原指针
_src := reflect.TypeOf(src)
2022-04-14 18:34:12 +08:00
2022-04-14 22:42:09 +08:00
// 指针类型获取真正type需要调用Elem
if _src.Kind() == reflect.Ptr {
_src = _src.Elem()
}
for _, val := range this.body {
tRef := reflect.New(_src)
2022-04-14 18:34:12 +08:00
2022-04-14 22:42:09 +08:00
fieldNum := tRef.Elem().NumField()
2022-04-14 18:34:12 +08:00
2022-04-14 22:42:09 +08:00
for k, v := range val {
for i := 0; i < fieldNum; i++ {
// 匹配结构字段名称
if k != strings.ToLower(tRef.Elem().Type().Field(i).Tag.Get("xlsx")) {
continue
}
vRef := tRef.Elem().FieldByName(tRef.Elem().Type().Field(i).Name)
2022-04-14 18:34:12 +08:00
2022-04-14 22:42:09 +08:00
if !vRef.CanSet() {
continue
}
switch vRef.Type().String() {
case "string":
vRef.SetString(v)
break
case "int", "int32", "int64":
vRef.SetInt(utils.StringToInt64(v))
break
case "uint", "uint32", "uint64":
vRef.SetUint(utils.StringToUnit64(v))
break
case "float", "float32", "float64":
f, _ := utils.StringToFloat(v)
vRef.SetFloat(f)
break
default:
break
}
2022-04-14 18:34:12 +08:00
}
}
2022-04-14 22:42:09 +08:00
out = append(out, tRef.Interface())
2022-04-14 18:34:12 +08:00
}
2022-04-14 22:42:09 +08:00
return out
2022-04-14 18:34:12 +08:00
}
2022-03-28 07:01:33 +08:00
func NewExcel(options ...OptionExcel) *Excel {
out := new(Excel)
for _, opt := range options {
opt(out)
}
return out
}