package api import ( "fmt" "strconv" "strings" "github.com/xuri/excelize/v2" ) // 生产成本表 type PlanProcessTrackExcel struct { Row int Title string Excel *excelize.File SheetName string AlignCenterStyle int Content []*PlanStatusInfo RowMap map[string]int RowWidthArray []float64 RowsHeightArray []map[int]float64 } // 批量设置行高 func (b *PlanProcessTrackExcel) setRowsHeight() { for _, rowHeight := range b.RowsHeightArray { for row, height := range rowHeight { b.Excel.SetRowHeight(b.SheetName, row, height) } } } // 获取范围内单元格的宽度 A:F func (b *PlanProcessTrackExcel) getRangeWidth(r string) float64 { rg := strings.Split(r, ":") if len(rg) == 1 { start := b.RowMap[rg[0]] return b.RowWidthArray[start] } else if len(rg) == 2 { start := b.RowMap[rg[0]] end := b.RowMap[rg[1]] rowr := b.RowWidthArray[start : end+1] width := 0.0 for _, v := range rowr { width += v } return width } return 0.0 } func (b *PlanProcessTrackExcel) drawTitle() error { b.Row++ startCell := fmt.Sprintf("A%d", b.Row) // A1:S2 b.Row++ err := b.Excel.MergeCell(b.SheetName, startCell, fmt.Sprintf("S%d", b.Row)) if err != nil { return err } style, err := b.Excel.NewStyle(&excelize.Style{ Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true}, Font: &excelize.Font{Bold: true, Size: 18}}) if err != nil { return err } err = b.Excel.SetCellStyle(b.SheetName, startCell, startCell, style) if err != nil { return err } b.Excel.SetCellValue(b.SheetName, startCell, "2024月饼礼盒加工追踪表") return nil } func (b *PlanProcessTrackExcel) drawTableTitle() error { b.Row++ var drawCol = func(prefix string, value string) error { left1Cell := fmt.Sprintf("%s%d", prefix, b.Row) left2Cell := fmt.Sprintf("%s%d", prefix, b.Row+1) err := b.Excel.MergeCell(b.SheetName, left1Cell, left2Cell) if err != nil { return err } err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left2Cell, b.AlignCenterStyle) if err != nil { return err } return b.Excel.SetCellValue(b.SheetName, left1Cell, value) } var drawMergeCol = func(prefix1 string, prefix2 string, value string) error { startCell := fmt.Sprintf("%s%d", prefix1, b.Row) endCell := fmt.Sprintf("%s%d", prefix2, b.Row) err := b.Excel.MergeCell(b.SheetName, startCell, endCell) if err != nil { return err } err = b.Excel.SetCellStyle(b.SheetName, startCell, endCell, b.AlignCenterStyle) if err != nil { return err } b.Excel.SetCellValue(b.SheetName, startCell, value) return nil } var drawCell = func(prefix string, value string) error { cell := fmt.Sprintf("%s%d", prefix, b.Row+1) err := b.Excel.SetCellStyle(b.SheetName, cell, cell, b.AlignCenterStyle) if err != nil { return err } b.Excel.SetCellValue(b.SheetName, cell, value) return nil } drawCol("A", "序号") drawCol("B", "品名") drawCol("C", "箱规") drawCol("D", "数量合计(盒)") drawCell("E", "部件") drawCell("F", "下单") drawCell("G", "纸张") drawCell("H", "印刷") drawCell("I", "覆膜") drawCell("J", "烫金") drawCell("K", "丝印") drawCell("L", "对裱") drawCell("M", "压纹") drawCell("N", "裱瓦") drawCell("O", "模切") drawCell("P", "粘盒") drawCell("Q", "组装") drawMergeCol("E", "Q", "包装追踪") drawCol("R", "交货") drawCol("S", "备注") b.Row++ return nil } func (b *PlanProcessTrackExcel) drawAllContent() error { b.Row++ style, _ := b.Excel.NewStyle(&excelize.Style{ Border: []excelize.Border{ { Type: "left", Color: "FF000000", Style: 1, }, { Type: "right", Color: "FF000000", Style: 1, }, { Type: "top", Color: "FF000000", Style: 1, }, { Type: "bottom", Color: "FF000000", Style: 1, }, }, Fill: excelize.Fill{ Type: "pattern", Pattern: 1, // 1 表示实心填充 Color: []string{CELL_BACKGROUND}, }, }) var drawRow = func(rowIndex int, values ...string) float64 { charas := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S"} // 获取改行最大行高 max := getRowHeight(values[0], b.getRangeWidth(charas[0])) for i, c := range charas { v := "" if i < len(values) { v = values[i] } // 设置背景色 if v == CELL_BACKGROUND { b.Excel.SetCellStyle(b.SheetName, fmt.Sprintf("%s%d", c, rowIndex), fmt.Sprintf("%s%d", c, rowIndex), style) } else { // 填充cell b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("%s%d", c, rowIndex), v) val2Cel := fmt.Sprintf("%s%d", c, rowIndex) b.Excel.SetCellStyle(b.SheetName, val2Cel, val2Cel, b.AlignCenterStyle) } if getRowHeight(v, b.getRangeWidth(c)) > max { max = getRowHeight(v, b.getRangeWidth(c)) } } return max } for _, planStatusInfo := range b.Content { // 对应产品下部件's的状态 for _, compStatus := range planStatusInfo.PlanCompStatus { _row := compStatus["行数"] row, _ := strconv.Atoi(_row) rowMaxHeight := drawRow(row, "", "", "", "", compStatus["部件"], compStatus["下单"], compStatus["纸张"], compStatus["印刷"], compStatus["覆膜"], compStatus["烫金"], compStatus["丝印"], compStatus["对裱"], compStatus["压纹"], compStatus["裱瓦"], compStatus["模切"], compStatus["粘盒"], compStatus["组装"], compStatus["交货"]) b.RowsHeightArray = append(b.RowsHeightArray, map[int]float64{row: rowMaxHeight}) } } for index, planStatusInfo := range b.Content { fmt.Println(planStatusInfo.PlanRowStart) fmt.Println(planStatusInfo.PlanRowEnd) fmt.Println(planStatusInfo.PlanName) b.Excel.MergeCell(b.SheetName, fmt.Sprintf("%s%d", "A", planStatusInfo.PlanRowStart), fmt.Sprintf("%s%d", "A", planStatusInfo.PlanRowEnd)) b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("%s%d", "A", planStatusInfo.PlanRowStart), index+1) // 品名 b.Excel.MergeCell(b.SheetName, fmt.Sprintf("%s%d", "B", planStatusInfo.PlanRowStart), fmt.Sprintf("%s%d", "B", planStatusInfo.PlanRowEnd)) b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("%s%d", "B", planStatusInfo.PlanRowStart), planStatusInfo.PlanName) // 箱规 b.Excel.MergeCell(b.SheetName, fmt.Sprintf("%s%d", "C", planStatusInfo.PlanRowStart), fmt.Sprintf("%s%d", "C", planStatusInfo.PlanRowEnd)) b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("%s%d", "C", planStatusInfo.PlanRowStart), planStatusInfo.PlanUnit) // 数量合计 b.Excel.MergeCell(b.SheetName, fmt.Sprintf("%s%d", "D", planStatusInfo.PlanRowStart), fmt.Sprintf("%s%d", "D", planStatusInfo.PlanRowEnd)) b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("%s%d", "D", planStatusInfo.PlanRowStart), planStatusInfo.PlanCount) } return nil } func (b *PlanProcessTrackExcel) Draws() { b.drawTitle() b.drawTableTitle() b.drawAllContent() // 根据类容设置最大行高 b.setRowsHeight() } func NewPlanProcessTrackExcel(f *excelize.File) *PlanProcessTrackExcel { border := []excelize.Border{ {Type: "top", Style: 1, Color: "000000"}, {Type: "left", Style: 1, Color: "000000"}, {Type: "right", Style: 1, Color: "000000"}, {Type: "bottom", Style: 1, Color: "000000"}, } styleLeft, _ := f.NewStyle(&excelize.Style{ Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true}, Border: border, Font: &excelize.Font{Size: 10}, }) b := &PlanProcessTrackExcel{ Title: "2024月饼礼盒加工追踪表", Row: 0, SheetName: "Sheet1", Excel: f, AlignCenterStyle: styleLeft, Content: make([]*PlanStatusInfo, 0), RowMap: map[string]int{"A": 0, "B": 1, "C": 2, "D": 3, "E": 4, "F": 5, "G": 6, "H": 7, "I": 8, "J": 9, "K": 10, "L": 11, "M": 12, "N": 13, "O": 14, "P": 15, "Q": 16, "R": 17, "S": 18}, RowWidthArray: []float64{6, 12, 12, 12, 16, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 12, 12}, RowsHeightArray: make([]map[int]float64, 0), } // 初始化批量设置列宽 for index, cw := range b.RowWidthArray { for k, v := range b.RowMap { if v == index { fmt.Println(index) fmt.Println(k, cw) b.Excel.SetColWidth(b.SheetName, k, k, cw) } } } f.SetPageMargins(b.SheetName, excelize.PageMarginTop(0), excelize.PageMarginLeft(0), excelize.PageMarginRight(0)) return b }