package excel_generator import ( "fmt" "github.com/go-kratos/kratos/v2/log" "github.com/xuri/excelize/v2" ) // Client Excel 生成器 type Client struct{} func New() *Client { return &Client{} } // Call 根据模板和数据生成 Excel 字节流 func (g *Client) Call(req *ExcelGeneratorRequest) ([]byte, error) { if req.StartRow <= 0 { req.StartRow = 2 } if req.StyleRow <= 0 { req.StyleRow = 2 } f, err := excelize.OpenFile(req.TemplatePath) if err != nil { return nil, err } defer f.Close() sheet := f.GetSheetName(0) // 若提供标题,替换第一行表格标题 if len(req.Title) > 0 { f.SetCellValue(sheet, "A1", req.Title) } // 获取样式和行高 styleID, err := f.GetCellStyle(sheet, fmt.Sprintf("A%d", req.StyleRow)) if err != nil { log.Errorf("获取样式失败: %v", err) styleID = 0 } rowHeight, err := f.GetRowHeight(sheet, req.StyleRow) if err != nil { log.Errorf("获取行高失败: %v", err) rowHeight = 31 // 默认高度 } row := req.StartRow for i, item := range req.ExcelData { currentRow := row + i // 设置行高 f.SetRowHeight(sheet, currentRow, rowHeight) // 填充数据 for col, value := range item { cell := fmt.Sprintf("%c%d", 'A'+col, currentRow) f.SetCellValue(sheet, cell, value) } // 设置样式 if styleID != 0 { endCol := 'A' + len(item) - 1 f.SetCellStyle(sheet, fmt.Sprintf("A%d", currentRow), fmt.Sprintf("%c%d", endCol, currentRow), styleID) } } buf, err := f.WriteToBuffer() if err != nil { return nil, err } return buf.Bytes(), nil }