导出新增了合并单元格,样式处理
This commit is contained in:
+303
-227
@@ -2,109 +2,40 @@ package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/xuri/excelize/v2"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// func Export(widths []int) (bool, error) {
|
||||
// f := excelize.NewFile()
|
||||
// defer func() {
|
||||
// _ = f.Close()
|
||||
// }()
|
||||
//
|
||||
// // 创建一个工作表
|
||||
// index, err := f.NewSheet("Sheet1")
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 设置工作簿的默认工作表
|
||||
// f.SetActiveSheet(index)
|
||||
//
|
||||
// // 单元格对齐样式
|
||||
// alignment := &excelize.Alignment{
|
||||
// Horizontal: "center",
|
||||
// Vertical: "center",
|
||||
// }
|
||||
//
|
||||
// // 单元格颜色填充样式
|
||||
// fill := excelize.Fill{
|
||||
// Type: "pattern",
|
||||
// Pattern: 1,
|
||||
// Color: []string{"#c9daf8"},
|
||||
// Shading: 0,
|
||||
// }
|
||||
//
|
||||
// // 第一行的左、右、下边框
|
||||
// border := []excelize.Border{
|
||||
// {
|
||||
// Type: "left,right,bottom",
|
||||
// Color: "",
|
||||
// Style: 1,
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// // 工作表样式
|
||||
// style, err := f.NewStyle(
|
||||
// &excelize.Style{
|
||||
// Fill: fill,
|
||||
// Alignment: alignment,
|
||||
// Border: border,
|
||||
// },
|
||||
// )
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 依次设置每一列的列宽
|
||||
// widths = []int{18, 18, 18, 18, 18, 20, 23, 46, 18, 30, 30, 18, 18, 30, 18, 30}
|
||||
// for col, width := range widths {
|
||||
// // 获取列名
|
||||
// colName, err := excelize.ColumnNumberToName(col + 1)
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 设置列宽
|
||||
// err = f.SetColWidth("Sheet1", colName, colName, float64(width))
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 设置列背景颜色
|
||||
// err = f.SetCellStyle("Sheet1", colName+"1", colName+"1", style)
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 设置行高
|
||||
// err = f.SetRowStyle("Sheet1", 1, 10, style)
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// if err := f.SaveAs("output.xlsx"); err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// return true, nil
|
||||
// }
|
||||
|
||||
// HeaderCellData 表头内容
|
||||
type HeaderCellData struct {
|
||||
Value string // 值
|
||||
CellType string // 类型
|
||||
NumberFmt string // 格式化方式
|
||||
ColWidth int // 列宽
|
||||
Colour string // 颜色
|
||||
}
|
||||
|
||||
func Export(header []HeaderCellData, data []interface{}) (*bytes.Buffer, error) {
|
||||
sheetName := "Sheet1"
|
||||
// GenerateSheet 生成表格
|
||||
func GenerateSheet(header []HeaderCellData, sheetName string) (f *excelize.File, err error) {
|
||||
// 创建工作表
|
||||
err, f = createSheet(sheetName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
f := excelize.NewFile()
|
||||
// 设置表头
|
||||
if err := setHeader(f, sheetName, header); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
// 创建工作表
|
||||
func createSheet(sheetName string) (err error, f *excelize.File) {
|
||||
f = excelize.NewFile()
|
||||
defer func() {
|
||||
_ = f.Close()
|
||||
}()
|
||||
@@ -112,7 +43,7 @@ func Export(header []HeaderCellData, data []interface{}) (*bytes.Buffer, error)
|
||||
// 创建一个工作表
|
||||
index, err := f.NewSheet(sheetName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err, nil
|
||||
}
|
||||
|
||||
// 设置工作簿的默认工作表
|
||||
@@ -121,178 +52,323 @@ func Export(header []HeaderCellData, data []interface{}) (*bytes.Buffer, error)
|
||||
// 设置工作表默认字体
|
||||
err = f.SetDefaultFont("宋体")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 统一单元格对齐样式
|
||||
alignment := &excelize.Alignment{
|
||||
Horizontal: "center",
|
||||
Vertical: "center",
|
||||
return err, nil
|
||||
}
|
||||
|
||||
// 设置行高 35-第一行
|
||||
err = f.SetRowHeight(sheetName, 1, 35)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err, nil
|
||||
}
|
||||
|
||||
// 处理工作表表头
|
||||
return nil, f
|
||||
}
|
||||
|
||||
// 设置表头
|
||||
func setHeader(f *excelize.File, sheetName string, header []HeaderCellData) error {
|
||||
for c, cell := range header {
|
||||
// 获取列名
|
||||
colName, err := excelize.ColumnNumberToName(c + 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
// 添加单元格的值
|
||||
err = f.SetCellValue(sheetName, colName+"1", cell.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if err := f.SetCellValue(sheetName, colName+"1", cell.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 单元格颜色填充样式
|
||||
fill := excelize.Fill{
|
||||
Type: "pattern",
|
||||
Pattern: 1,
|
||||
Color: []string{"#c9daf8"},
|
||||
Shading: 0,
|
||||
var fill excelize.Fill
|
||||
if cell.Colour != "" {
|
||||
fill = excelize.Fill{
|
||||
Type: "pattern",
|
||||
Pattern: 1,
|
||||
Color: []string{cell.Colour},
|
||||
Shading: 0,
|
||||
}
|
||||
}
|
||||
|
||||
// 第一行的左、右、下边框
|
||||
border := []excelize.Border{
|
||||
{
|
||||
Type: "left",
|
||||
Color: "#000000",
|
||||
Style: 1,
|
||||
},
|
||||
{
|
||||
Type: "right",
|
||||
Color: "#000000",
|
||||
Style: 1,
|
||||
},
|
||||
{
|
||||
Type: "bottom",
|
||||
Color: "#000000",
|
||||
Style: 1,
|
||||
},
|
||||
{Type: "left", Color: "#000000", Style: 1},
|
||||
{Type: "right", Color: "#000000", Style: 1},
|
||||
{Type: "bottom", Color: "#000000", Style: 1},
|
||||
}
|
||||
|
||||
// 设置单元格值类型和格式
|
||||
style, _ := f.NewStyle(&excelize.Style{
|
||||
Alignment: alignment, // 字体居中
|
||||
Fill: fill, // 背景颜色
|
||||
Border: border, // 边框
|
||||
style, err := f.NewStyle(&excelize.Style{
|
||||
Alignment: &excelize.Alignment{
|
||||
Horizontal: "center",
|
||||
Vertical: "center",
|
||||
},
|
||||
Fill: fill,
|
||||
Border: border,
|
||||
})
|
||||
err = f.SetCellStyle(sheetName, colName+"1", colName+"1", style)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
|
||||
// 设置列宽
|
||||
err = f.SetColWidth(sheetName, colName, colName, float64(cell.ColWidth))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if err := f.SetCellStyle(sheetName, colName+"1", colName+"1", style); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := f.SetColWidth(sheetName, colName, colName, float64(cell.ColWidth)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// 设置单元格格式
|
||||
row := len(data)
|
||||
for i, cell := range header {
|
||||
// 获取列名
|
||||
colName, err := excelize.ColumnNumberToName(i + 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 字体居中
|
||||
style := &excelize.Style{}
|
||||
style = &excelize.Style{
|
||||
Alignment: alignment,
|
||||
}
|
||||
|
||||
if cell.CellType == "float" {
|
||||
style.NumFmt = 2
|
||||
customNumFmt := "0.000"
|
||||
style.CustomNumFmt = &customNumFmt
|
||||
}
|
||||
|
||||
if cell.CellType == "date" {
|
||||
style.NumFmt = 22
|
||||
customNumFmt := "yyyy-mm-dd hh:mm:ss"
|
||||
style.CustomNumFmt = &customNumFmt
|
||||
}
|
||||
|
||||
newStyle, _ := f.NewStyle(style)
|
||||
err = f.SetCellStyle(sheetName, colName+"2", colName+strconv.Itoa(row), newStyle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// 填充数据
|
||||
for r, rowData := range data {
|
||||
rv := reflect.ValueOf(rowData)
|
||||
for c := 0; c < rv.NumField(); c++ {
|
||||
cellValue := rv.Field(c).Interface()
|
||||
// 获取列名
|
||||
colName, err := excelize.ColumnNumberToName(c + 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
axis := colName + fmt.Sprintf("%d", r+2)
|
||||
|
||||
// 设置单元格值
|
||||
err = f.SetCellValue(sheetName, axis, cellValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 设置单元格值类型
|
||||
cellType := header[c].CellType
|
||||
|
||||
// 字体居中
|
||||
style := &excelize.Style{}
|
||||
style = &excelize.Style{
|
||||
Alignment: alignment,
|
||||
}
|
||||
|
||||
if cellType == "float" {
|
||||
style.NumFmt = 2
|
||||
customNumFmt := "0.000"
|
||||
style.CustomNumFmt = &customNumFmt
|
||||
}
|
||||
|
||||
if cellType == "date" {
|
||||
style.NumFmt = 22
|
||||
customNumFmt := "yyyy-mm-dd hh:mm:ss"
|
||||
style.CustomNumFmt = &customNumFmt
|
||||
}
|
||||
|
||||
newStyle, _ := f.NewStyle(style)
|
||||
err = f.SetCellStyle(sheetName, axis, axis, newStyle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 设置行高 35-第一行
|
||||
err = f.SetRowHeight(sheetName, r+2, 35)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer, err := f.WriteToBuffer()
|
||||
// Export 导出
|
||||
func Export(header []HeaderCellData, data []interface{}) (b *bytes.Buffer, err error) {
|
||||
sheetName := "Sheet1"
|
||||
// 生成表格
|
||||
f, err := GenerateSheet(header, sheetName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buffer, nil
|
||||
alignment := &excelize.Alignment{
|
||||
Horizontal: "center",
|
||||
Vertical: "center",
|
||||
}
|
||||
|
||||
row := 1
|
||||
for _, item := range data {
|
||||
var err error
|
||||
row, err = fillDataWithMerge(f, sheetName, header, item, row, alignment)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
//buffer, err := f.WriteToBuffer()
|
||||
//if err != nil {
|
||||
// return nil, err
|
||||
//}
|
||||
|
||||
//return buffer, nil
|
||||
|
||||
// 保存文件
|
||||
// if err := f.SaveAs("output.xlsx"); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return nil, errors.New("已导出文件")
|
||||
if err := f.SaveAs("output.xlsx"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errors.New("已导出文件")
|
||||
}
|
||||
|
||||
// 填充数据
|
||||
func fillDataWithMerge(f *excelize.File, sheetName string, header []HeaderCellData, data interface{}, row int, alignment *excelize.Alignment) (int, error) {
|
||||
v := reflect.ValueOf(data)
|
||||
|
||||
// 判断是否是结构体或指向结构体的指针
|
||||
if v.Kind() == reflect.Ptr {
|
||||
v = v.Elem()
|
||||
}
|
||||
if v.Kind() != reflect.Struct {
|
||||
panic("data must be a struct or a pointer to struct")
|
||||
}
|
||||
|
||||
var axis string // 坐标值
|
||||
|
||||
colOffset := 0 // 列偏移量
|
||||
mergeNum := 0 // 合并单元格数量。默认为0,每次+1,当存在切片时启用
|
||||
var mergeNumSlice []string // 需合并单元格列名。默认为空,当存在切片时启用["A","B"]
|
||||
filedNumSlice := 1 // 切片数量,默认为1,此数量为其余需合并的数量
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
field := v.Field(i)
|
||||
|
||||
// 获取字段类型
|
||||
valueType := field.Kind()
|
||||
if valueType != reflect.Slice {
|
||||
// 获取字段值
|
||||
cellValue := field.Interface()
|
||||
|
||||
// 获取列名
|
||||
colName, err := excelize.ColumnNumberToName(colOffset + 1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 获取坐标,+1表示去除header行
|
||||
axis = colName + fmt.Sprintf("%d", row+1)
|
||||
|
||||
// 填入值
|
||||
err = f.SetCellValue(sheetName, axis, cellValue)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 设置单元格样式
|
||||
err = setCellStyle(f, sheetName, axis, header[i], alignment)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 设置行高 35-第一行
|
||||
err = f.SetRowHeight(sheetName, row+1, 35)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 合并单元格数量
|
||||
mergeNum = mergeNum + 1
|
||||
mergeNumSlice = append(mergeNumSlice, colName)
|
||||
} else {
|
||||
var sliceFieldNum int // 切片字段数量
|
||||
|
||||
// 最大切片数量,此数量为其余需合并的数量
|
||||
if filedNumSlice < field.Len() {
|
||||
filedNumSlice = field.Len()
|
||||
}
|
||||
|
||||
for j := 0; j < field.Len(); j++ {
|
||||
item := field.Index(j).Interface()
|
||||
v1 := reflect.ValueOf(item)
|
||||
|
||||
for i2 := 0; i2 < field.Index(j).NumField(); i2++ {
|
||||
// 获取字段值
|
||||
cellValue := v1.Field(i2).Interface()
|
||||
|
||||
// 获取列名
|
||||
colName, err := excelize.ColumnNumberToName(i + i2 + 1)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 获取坐标,+1表示去除header行
|
||||
axis = colName + fmt.Sprintf("%d", row+j+1)
|
||||
|
||||
// 填入值
|
||||
err = f.SetCellValue(sheetName, axis, cellValue)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 设置单元格样式
|
||||
err = setCellStyle(f, sheetName, axis, header[i+i2], alignment)
|
||||
if err != nil {
|
||||
return row, err
|
||||
}
|
||||
|
||||
// 设置行高 35-第一行
|
||||
err = f.SetRowHeight(sheetName, row+j+1, 35)
|
||||
if err != nil {
|
||||
return row, err
|
||||
}
|
||||
|
||||
sliceFieldNum = i2
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 列偏移量需增加上切片字段数量
|
||||
colOffset = colOffset + sliceFieldNum
|
||||
}
|
||||
|
||||
colOffset++
|
||||
}
|
||||
|
||||
// 合并单元格
|
||||
if filedNumSlice > 1 {
|
||||
for _, s := range mergeNumSlice {
|
||||
// 设置单元格样式
|
||||
for i := 0; i < filedNumSlice; i++ {
|
||||
axis = s + fmt.Sprintf("%d", row+i+1)
|
||||
err := setCellStyle(f, sheetName, axis, header[row+i], alignment)
|
||||
if err != nil {
|
||||
return row, err
|
||||
}
|
||||
}
|
||||
|
||||
startCell := s + fmt.Sprintf("%d", row+1)
|
||||
endCell := s + fmt.Sprintf("%d", row+filedNumSlice)
|
||||
err := f.MergeCell(sheetName, startCell, endCell)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 行数 = 切片数量,如不存在切片filedNumSlice默认为1
|
||||
row = row + filedNumSlice
|
||||
|
||||
// 返回当前处理到的行数
|
||||
return row, nil
|
||||
}
|
||||
|
||||
// 设置单元格样式
|
||||
func setCellStyle(f *excelize.File, sheetName, axis string, header HeaderCellData, alignment *excelize.Alignment) error {
|
||||
// 获取现有样式id
|
||||
styleID, err := f.GetCellStyle(sheetName, axis)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 处理样式问题
|
||||
var style *excelize.Style
|
||||
if styleID == 0 {
|
||||
// 新样式
|
||||
style = &excelize.Style{
|
||||
Alignment: alignment,
|
||||
}
|
||||
} else {
|
||||
// 存在现有样式,直接获取
|
||||
style, err = f.GetStyle(styleID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if header.CellType == "float" {
|
||||
style.NumFmt = 2
|
||||
customNumFmt := "0.000"
|
||||
style.CustomNumFmt = &customNumFmt
|
||||
}
|
||||
|
||||
if header.CellType == "date" {
|
||||
style.NumFmt = 22
|
||||
customNumFmt := "yyyy-mm-dd hh:mm:ss"
|
||||
style.CustomNumFmt = &customNumFmt
|
||||
}
|
||||
|
||||
// 颜色-可用,但是目前无需使用
|
||||
if header.Colour != "" {
|
||||
// 单元格颜色
|
||||
//fill := excelize.Fill{
|
||||
// Type: "pattern",
|
||||
// Pattern: 1,
|
||||
// Color: []string{header.Colour},
|
||||
// Shading: 0,
|
||||
//}
|
||||
//
|
||||
//style.Fill = fill
|
||||
//
|
||||
//// 字体颜色
|
||||
//font := &excelize.Font{
|
||||
// Color: header.Colour,
|
||||
//}
|
||||
//
|
||||
//style.Font = font
|
||||
}
|
||||
|
||||
// 边框
|
||||
border := []excelize.Border{
|
||||
{Type: "left", Color: "#000000", Style: 1},
|
||||
{Type: "right", Color: "#000000", Style: 1},
|
||||
{Type: "bottom", Color: "#000000", Style: 1},
|
||||
}
|
||||
|
||||
style.Border = border
|
||||
|
||||
newStyle, err := f.NewStyle(style)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := f.SetCellStyle(sheetName, axis, axis, newStyle); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,298 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/xuri/excelize/v2"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// func Export(widths []int) (bool, error) {
|
||||
// f := excelize.NewFile()
|
||||
// defer func() {
|
||||
// _ = f.Close()
|
||||
// }()
|
||||
//
|
||||
// // 创建一个工作表
|
||||
// index, err := f.NewSheet("Sheet1")
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 设置工作簿的默认工作表
|
||||
// f.SetActiveSheet(index)
|
||||
//
|
||||
// // 单元格对齐样式
|
||||
// alignment := &excelize.Alignment{
|
||||
// Horizontal: "center",
|
||||
// Vertical: "center",
|
||||
// }
|
||||
//
|
||||
// // 单元格颜色填充样式
|
||||
// fill := excelize.Fill{
|
||||
// Type: "pattern",
|
||||
// Pattern: 1,
|
||||
// Color: []string{"#c9daf8"},
|
||||
// Shading: 0,
|
||||
// }
|
||||
//
|
||||
// // 第一行的左、右、下边框
|
||||
// border := []excelize.Border{
|
||||
// {
|
||||
// Type: "left,right,bottom",
|
||||
// Color: "",
|
||||
// Style: 1,
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// // 工作表样式
|
||||
// style, err := f.NewStyle(
|
||||
// &excelize.Style{
|
||||
// Fill: fill,
|
||||
// Alignment: alignment,
|
||||
// Border: border,
|
||||
// },
|
||||
// )
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 依次设置每一列的列宽
|
||||
// widths = []int{18, 18, 18, 18, 18, 20, 23, 46, 18, 30, 30, 18, 18, 30, 18, 30}
|
||||
// for col, width := range widths {
|
||||
// // 获取列名
|
||||
// colName, err := excelize.ColumnNumberToName(col + 1)
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 设置列宽
|
||||
// err = f.SetColWidth("Sheet1", colName, colName, float64(width))
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// // 设置列背景颜色
|
||||
// err = f.SetCellStyle("Sheet1", colName+"1", colName+"1", style)
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 设置行高
|
||||
// err = f.SetRowStyle("Sheet1", 1, 10, style)
|
||||
// if err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// if err := f.SaveAs("output.xlsx"); err != nil {
|
||||
// return false, err
|
||||
// }
|
||||
//
|
||||
// return true, nil
|
||||
// }
|
||||
|
||||
// HeaderCellData1 表头内容
|
||||
type HeaderCellData1 struct {
|
||||
Value string // 值
|
||||
CellType string // 类型
|
||||
NumberFmt string // 格式化方式
|
||||
ColWidth int // 列宽
|
||||
}
|
||||
|
||||
func Export2(header []HeaderCellData1, data []interface{}) (*bytes.Buffer, error) {
|
||||
sheetName := "Sheet1"
|
||||
|
||||
f := excelize.NewFile()
|
||||
defer func() {
|
||||
_ = f.Close()
|
||||
}()
|
||||
|
||||
// 创建一个工作表
|
||||
index, err := f.NewSheet(sheetName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 设置工作簿的默认工作表
|
||||
f.SetActiveSheet(index)
|
||||
|
||||
// 设置工作表默认字体
|
||||
err = f.SetDefaultFont("宋体")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 统一单元格对齐样式
|
||||
alignment := &excelize.Alignment{
|
||||
Horizontal: "center",
|
||||
Vertical: "center",
|
||||
}
|
||||
|
||||
// 设置行高 35-第一行
|
||||
err = f.SetRowHeight(sheetName, 1, 35)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 处理工作表表头
|
||||
for c, cell := range header {
|
||||
// 获取列名
|
||||
colName, err := excelize.ColumnNumberToName(c + 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 添加单元格的值
|
||||
err = f.SetCellValue(sheetName, colName+"1", cell.Value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 单元格颜色填充样式
|
||||
fill := excelize.Fill{
|
||||
Type: "pattern",
|
||||
Pattern: 1,
|
||||
Color: []string{"#c9daf8"},
|
||||
Shading: 0,
|
||||
}
|
||||
|
||||
// 第一行的左、右、下边框
|
||||
border := []excelize.Border{
|
||||
{
|
||||
Type: "left",
|
||||
Color: "#000000",
|
||||
Style: 1,
|
||||
},
|
||||
{
|
||||
Type: "right",
|
||||
Color: "#000000",
|
||||
Style: 1,
|
||||
},
|
||||
{
|
||||
Type: "bottom",
|
||||
Color: "#000000",
|
||||
Style: 1,
|
||||
},
|
||||
}
|
||||
|
||||
// 设置单元格值类型和格式
|
||||
style, _ := f.NewStyle(&excelize.Style{
|
||||
Alignment: alignment, // 字体居中
|
||||
Fill: fill, // 背景颜色
|
||||
Border: border, // 边框
|
||||
})
|
||||
err = f.SetCellStyle(sheetName, colName+"1", colName+"1", style)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 设置列宽
|
||||
err = f.SetColWidth(sheetName, colName, colName, float64(cell.ColWidth))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// 设置单元格格式
|
||||
row := len(data)
|
||||
for i, cell := range header {
|
||||
// 获取列名
|
||||
colName, err := excelize.ColumnNumberToName(i + 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 字体居中
|
||||
style := &excelize.Style{}
|
||||
style = &excelize.Style{
|
||||
Alignment: alignment,
|
||||
}
|
||||
|
||||
if cell.CellType == "float" {
|
||||
style.NumFmt = 2
|
||||
customNumFmt := "0.000"
|
||||
style.CustomNumFmt = &customNumFmt
|
||||
}
|
||||
|
||||
if cell.CellType == "date" {
|
||||
style.NumFmt = 22
|
||||
customNumFmt := "yyyy-mm-dd hh:mm:ss"
|
||||
style.CustomNumFmt = &customNumFmt
|
||||
}
|
||||
|
||||
newStyle, _ := f.NewStyle(style)
|
||||
err = f.SetCellStyle(sheetName, colName+"2", colName+strconv.Itoa(row), newStyle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// 填充数据
|
||||
for r, rowData := range data {
|
||||
rv := reflect.ValueOf(rowData)
|
||||
for c := 0; c < rv.NumField(); c++ {
|
||||
cellValue := rv.Field(c).Interface()
|
||||
// 获取列名
|
||||
colName, err := excelize.ColumnNumberToName(c + 1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
axis := colName + fmt.Sprintf("%d", r+2)
|
||||
|
||||
// 设置单元格值
|
||||
err = f.SetCellValue(sheetName, axis, cellValue)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 设置单元格值类型
|
||||
cellType := header[c].CellType
|
||||
|
||||
// 字体居中
|
||||
style := &excelize.Style{}
|
||||
style = &excelize.Style{
|
||||
Alignment: alignment,
|
||||
}
|
||||
|
||||
if cellType == "float" {
|
||||
style.NumFmt = 2
|
||||
customNumFmt := "0.000"
|
||||
style.CustomNumFmt = &customNumFmt
|
||||
}
|
||||
|
||||
if cellType == "date" {
|
||||
style.NumFmt = 22
|
||||
customNumFmt := "yyyy-mm-dd hh:mm:ss"
|
||||
style.CustomNumFmt = &customNumFmt
|
||||
}
|
||||
|
||||
newStyle, _ := f.NewStyle(style)
|
||||
err = f.SetCellStyle(sheetName, axis, axis, newStyle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 设置行高 35-第一行
|
||||
err = f.SetRowHeight(sheetName, r+2, 35)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buffer, err := f.WriteToBuffer()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buffer, nil
|
||||
|
||||
// 保存文件
|
||||
// if err := f.SaveAs("output.xlsx"); err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// return nil, errors.New("已导出文件")
|
||||
}
|
||||
Reference in New Issue
Block a user