cutego/pkg/excels/export.go

144 lines
4.1 KiB
Go
Raw Normal View History

2022-03-01 13:50:13 +08:00
package excels
import (
"github.com/druidcaesa/gotool"
"github.com/xuri/excelize/v2"
"reflect"
"strconv"
)
// 获取title头list
func getTitle(list []map[string]string) []string {
titleList := make([]string, 0)
for _, item := range list {
for _, s := range item {
titleList = append(titleList, s)
}
}
return titleList
}
// ExportExcel 导出excel
func ExportExcel(list []interface{}, title string) (error, *excelize.File) {
// 获取标题
headerList, expList := ExcelCreate(list[0])
headers := getTitle(headerList)
// 默认存在第一个工作簿是 Sheet1 首字母要大写, 否则会报错。
// 如果想额外的创建工作簿, 可以使用, sheet2 := file.NewSheet("Sheet2"), 工作簿的名称不区分大小写。
// 如果有多个工作簿, 可以使用 file.SetActiveSheet(index) 来指定打开文件时focus到哪个工作簿
sheet1 := "Sheet1"
files := excelize.NewFile()
character := string(65 + len(headers) - 1)
/* -------------------- 第一行大标题 -------------------- */
// 设置行高
err := files.SetRowHeight(sheet1, 1, 25)
if err != nil {
return err, nil
}
// 合并单元格
err = files.MergeCell(sheet1, "A1", character+"1")
if err != nil {
return err, nil
}
// 设置单元格样式:对齐;字体, 大小;单元格边框
styleTitle, _ := files.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},"font":{"bold":true,"italic":false,"family":"Calibri","size":16,"color":"#000000"},"border":[{"type":"left","color":"#3FAD08","style":0},{"type":"top","color":"#3FAD08","style":0},{"type":"bottom","color":"#3FAD08","style":2},{"type":"right","color":"#3FAD08","style":0}]}`)
err = files.SetCellStyle(sheet1, "A1", character+"1", styleTitle)
if err != nil {
return err, nil
}
err = files.SetCellValue(sheet1, "A1", title)
if err != nil {
return err, nil
}
/* -------------------- 字段标题 -------------------- */
styleHeader, _ := files.NewStyle(`{"alignment":{"horizontal":"center","vertical":"center"},"font":{"bold":false,"italic":false,"family":"Calibri","size":10,"color":"#000000"}}`)
err = files.SetCellStyle(sheet1, "A2", character+"2", styleHeader)
if err != nil {
return err, nil
}
for k, v := range headers {
err = files.SetCellValue(sheet1, string(65+k)+"2", v)
if err != nil {
return err, nil
}
}
// 设置最后一列宽度
err = files.SetColWidth(sheet1, "C", character, 20)
if err != nil {
return err, nil
}
// 冻结窗口:冻结第一行和第二行
err = files.SetPanes(sheet1, `{"freeze":true,"split":false,"x_split":0,"y_split":2}`)
if err != nil {
return err, nil
}
///* -------------------- 填充行数据 -------------------- */
line := 3
for _, v := range list {
var num = 0
lineChr := strconv.Itoa(line)
// 设置样式
err = files.SetCellStyle(sheet1, "A"+lineChr, character+lineChr, styleHeader)
if err != nil {
return err, nil
}
// 反射获取数据和类型
getValue := reflect.ValueOf(v)
getType := reflect.TypeOf(v)
n := getValue.NumField()
for i := 0; i < n; i++ {
val := getValue.Field(i)
name := getType.Field(i).Name
if !getIsTitle(name, headerList) {
continue
}
err = files.SetCellValue(sheet1, string(65+num)+lineChr, getExp(name, expList, val.Interface()))
if err != nil {
return err, nil
}
num++
}
line++
}
return nil, files
}
func getIsTitle(name string, headerList []map[string]string) bool {
flag := false
for _, m := range headerList {
if gotool.StrUtils.HasNotEmpty(m[name]) {
flag = true
}
}
return flag
}
func getExp(name string, expList []map[string][]map[string]string, value interface{}) interface{} {
for _, m := range expList {
if len(m[name]) > 0 {
maps := m[name]
for _, m2 := range maps {
if gotool.StrUtils.HasNotEmpty(m2[interfaceToString(value)]) {
value = m2[interfaceToString(value)]
}
}
}
}
return value
}
func interfaceToString(inter interface{}) string {
switch inter.(type) {
case string:
return inter.(string)
case int:
return strconv.Itoa(inter.(int))
case int64:
return strconv.FormatInt(inter.(int64), 10)
default:
return inter.(string)
}
}