123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- package excelutil
- import (
- "bytes"
- "context"
- "fmt"
- "github.com/xuri/excelize/v2"
- "io"
- "time"
- "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/errors"
- )
- func ExportExcel(ctx context.Context, titles []interface{}, values [][]interface{}, cellFunc ExcelCellOptionFunc, opts ...ExcelOptionFunc) (io.Reader, error) {
- if len(titles) == 0 {
- return nil, errors.New("表头为空")
- }
- file := excelize.NewFile()
- defer func() {
- if err := file.Close(); err != nil {
- fmt.Println(err)
- }
- }()
- streamWriter, err := file.NewStreamWriter("Sheet1")
- if err != nil {
- return nil, errors.WithStack(err)
- }
- for _, opt := range opts {
- if err = opt(file, streamWriter); err != nil {
- return nil, err
- }
- }
- // 写入标题
- titleStyleID, err := getDefaultTitleStyleId(file)
- if err != nil {
- return nil, errors.WithStackOnce(err)
- }
- for i, v := range titles {
- cell := excelize.Cell{}
- if val, ok := v.(excelize.Cell); ok {
- cell = val
- } else {
- cell = excelize.Cell{StyleID: titleStyleID, Value: v}
- }
- if cellFunc != nil {
- if err = cellFunc(0, i, &cell); err != nil {
- return nil, errors.WithStack(err)
- }
- }
- titles[i] = cell
- }
- if err = streamWriter.SetRow("A1", titles, excelize.RowOpts{Height: 20}); err != nil {
- return nil, errors.WithStack(err)
- }
- // 写入内容
- valueStyleID, err := GetDefaultValueStyleId(file)
- if err != nil {
- return nil, errors.WithStackOnce(err)
- }
- timeStyleID, err := getDefaultTimeStyleId(file)
- if err != nil {
- return nil, errors.WithStackOnce(err)
- }
- for rowID := 0; rowID < len(values); rowID++ {
- row := values[rowID]
- for i, v := range row {
- cell := excelize.Cell{}
- if val, ok := v.(excelize.Cell); ok {
- cell = val
- } else if _, ok := v.(time.Time); ok {
- cell = excelize.Cell{StyleID: timeStyleID, Value: v}
- } else {
- cell = excelize.Cell{StyleID: valueStyleID, Value: v}
- }
- if cellFunc != nil {
- if err = cellFunc(rowID+1, i, &cell); err != nil {
- return nil, errors.WithStack(err)
- }
- }
- row[i] = cell
- }
- cell, _ := excelize.CoordinatesToCellName(1, rowID+2)
- if err := streamWriter.SetRow(cell, row); err != nil {
- return nil, errors.WithStack(err)
- }
- }
- if err := streamWriter.Flush(); err != nil {
- return nil, errors.WithStack(err)
- }
- buf := bytes.NewBuffer([]byte{})
- if err = file.Write(buf); err != nil {
- return nil, errors.WithStack(err)
- }
- return buf, nil
- }
- func getDefaultTitleStyleId(file *excelize.File) (int, error) {
- styleID, err := file.NewStyle(&excelize.Style{
- // 标题加粗
- Font: &excelize.Font{
- Bold: true,
- Color: "FFFFFF",
- },
- // 设置边框
- Border: []excelize.Border{
- {Type: "left", Color: "000000", Style: 1},
- {Type: "top", Color: "000000", Style: 1},
- {Type: "bottom", Color: "000000", Style: 1},
- {Type: "right", Color: "000000", Style: 1},
- },
- // 图案填充-绿色
- Fill: excelize.Fill{
- Pattern: 1,
- Type: "pattern",
- Color: []string{"2EA121"},
- },
- // 居中
- Alignment: &excelize.Alignment{
- // 水平对齐:
- Horizontal: "center",
- // 垂直对齐
- Vertical: "center",
- },
- })
- return styleID, err
- }
- func GetYellowStyleId(file *excelize.File) (int, error) {
- styleID, err := file.NewStyle(&excelize.Style{
- // 标题加粗
- Font: &excelize.Font{
- Bold: true,
- Color: "FFFFFF",
- },
- // 设置边框
- Border: []excelize.Border{
- {Type: "left", Color: "000000", Style: 1},
- {Type: "top", Color: "000000", Style: 1},
- {Type: "bottom", Color: "000000", Style: 1},
- {Type: "right", Color: "000000", Style: 1},
- },
- // 图案填充-黄色
- Fill: excelize.Fill{
- Pattern: 1,
- Type: "pattern",
- Color: []string{"FFC60A"},
- },
- // 居中
- Alignment: &excelize.Alignment{
- // 水平对齐:
- Horizontal: "center",
- // 垂直对齐
- Vertical: "center",
- },
- })
- return styleID, err
- }
- func GetDefaultValueStyleId(file *excelize.File) (int, error) {
- styleID, err := file.NewStyle(&excelize.Style{
- // 设置边框
- //Border: []excelize.Border{
- // {Type: "left", Color: "000000", Style: 1},
- // {Type: "top", Color: "000000", Style: 1},
- // {Type: "bottom", Color: "000000", Style: 1},
- // {Type: "right", Color: "000000", Style: 1},
- //},
- // 居中
- Alignment: &excelize.Alignment{
- // 水平对齐:
- Horizontal: "center",
- // 垂直对齐
- Vertical: "center",
- },
- })
- return styleID, err
- }
- func getDefaultTimeStyleId(file *excelize.File) (int, error) {
- styleID, err := file.NewStyle(&excelize.Style{
- // 设置边框
- Border: []excelize.Border{
- {Type: "left", Color: "000000", Style: 1},
- {Type: "top", Color: "000000", Style: 1},
- {Type: "bottom", Color: "000000", Style: 1},
- {Type: "right", Color: "000000", Style: 1},
- },
- // 居中
- Alignment: &excelize.Alignment{
- // 水平对齐:
- Horizontal: "center",
- // 垂直对齐
- Vertical: "center",
- },
- NumFmt: 22,
- })
- return styleID, err
- }
- type ExcelOptionFunc func(*excelize.File, *excelize.StreamWriter) error
- type ExcelCellOptionFunc func(rowIndex, cellIndex int, cell *excelize.Cell) error
|