package api import ( "fmt" "strings" "github.com/xuri/excelize/v2" ) // 生产成本表 type PlanSummaryExcel struct { Row int Title string Excel *excelize.File SheetName string AlignCenterStyle int Content *SupplierPlanSummary } func (b *PlanSummaryExcel) drawTitle() error { b.Row++ startCell := fmt.Sprintf("A%d", 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.SetRowHeight(b.SheetName, b.Row, 23) b.Excel.SetCellValue(b.SheetName, startCell, "汇总表") return nil } func (b *PlanSummaryExcel) 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 drawCol2 = func(prefix1 string, prefix2 string, value1 string, value2 string, value3 string) error { left1Cell := fmt.Sprintf("%s%d", prefix1, b.Row) left2Cell := fmt.Sprintf("%s%d", prefix2, b.Row) err := b.Excel.MergeCell(b.SheetName, left1Cell, left2Cell) if err != nil { return err } if err != nil { fmt.Println(err) return err } err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left2Cell, b.AlignCenterStyle) if err != nil { return err } b.Excel.SetCellValue(b.SheetName, left1Cell, value1) val2Cel := fmt.Sprintf("%s%d", prefix1, b.Row+1) b.Excel.SetCellStyle(b.SheetName, val2Cel, val2Cel, b.AlignCenterStyle) b.Excel.SetCellValue(b.SheetName, val2Cel, value2) val3Cel := fmt.Sprintf("%s%d", prefix2, b.Row+1) b.Excel.SetCellStyle(b.SheetName, val3Cel, val3Cel, b.AlignCenterStyle) b.Excel.SetCellValue(b.SheetName, val3Cel, value3) return nil } var drawCol3 = func(prefix1 string, prefix2 string, prefix3 string, value1 string, value2 string, value3 string, value4 string) error { left1Cell := fmt.Sprintf("%s%d", prefix1, b.Row) left3Cell := fmt.Sprintf("%s%d", prefix3, b.Row) err := b.Excel.MergeCell(b.SheetName, left1Cell, left3Cell) if err != nil { return err } if err != nil { fmt.Println(err) return err } err = b.Excel.SetCellStyle(b.SheetName, left1Cell, left3Cell, b.AlignCenterStyle) if err != nil { return err } b.Excel.SetCellValue(b.SheetName, left1Cell, value1) val2Cel := fmt.Sprintf("%s%d", prefix1, b.Row+1) b.Excel.SetCellStyle(b.SheetName, val2Cel, val2Cel, b.AlignCenterStyle) b.Excel.SetCellValue(b.SheetName, val2Cel, value2) val3Cel := fmt.Sprintf("%s%d", prefix2, b.Row+1) b.Excel.SetCellStyle(b.SheetName, val3Cel, val3Cel, b.AlignCenterStyle) b.Excel.SetCellValue(b.SheetName, val3Cel, value3) val4Cel := fmt.Sprintf("%s%d", prefix3, b.Row+1) b.Excel.SetCellStyle(b.SheetName, val4Cel, val4Cel, b.AlignCenterStyle) b.Excel.SetCellValue(b.SheetName, val4Cel, value4) return nil } drawCol("A", "产品名称") drawCol("B", "产品部件名称") drawCol2("C", "D", "类型/项目", "类型", "项目") drawCol("E", "下单数量") drawCol("F", "实际数量") drawCol("G", "状态") // 生成订单状态 审核状态 发送状态 完成状态 drawCol("H", "供应商名称") drawCol("I", "单价") drawCol3("J", "K", "L", "规格", "厚度(纸克)", "长", "宽") drawCol("M", "单位") drawCol("N", "下单单价") drawCol("O", "预算金额") drawCol("P", "实际金额") drawCol("Q", "订单编号") drawCol("R", "下单日期") drawCol("S", "备注") return nil } func (b *PlanSummaryExcel) drawRow(rowIndex int, values ...string) { charas := []string{"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S"} for i, c := range charas { v := "" if i < len(values) { v = values[i] } 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) b.Excel.SetRowHeight(b.SheetName, rowIndex, 32) } } func (b *PlanSummaryExcel) drawAllContent() error { b.Row += 2 // summaryPlans // 预算金额汇总 var totalBudgetPrice float64 = 0.00 // 实际金额汇总 var totalRealPrice float64 = 0.00 for _, splan := range b.Content.Plans { planStartRow := b.Row plan := splan.Plan comps := plan.Pack.Components // 预算金额汇总 var planBudgetPrice float64 = 0.00 // 实际金额汇总 var planRealPrice float64 = 0.00 if len(comps) > 0 { for _, comp := range comps { var perBudgetPrice float64 = 0.00 var perRealPrice float64 = 0.00 if len(comp.Stages) > 0 { startRow := b.Row cates := map[string][]int{} for _, stage := range comp.Stages { matHeigth := fmt.Sprintf("%d", stage.BatchSizeHeight) b.FormatToEmpty(&matHeigth) matWidth := fmt.Sprintf("%d", stage.BatchSizeWidth) b.FormatToEmpty(&matWidth) orderCount := fmt.Sprintf("%d", int(stage.OrderCount)) b.FormatToEmpty(&orderCount) // 实际数量 realCount := fmt.Sprintf("%d", stage.ConfirmCount) b.FormatToEmpty(&realCount) // 单价 price := fmt.Sprintf("%.3f", stage.OrderPrice) b.FormatToEmpty(&price) // 预算金额 budgetPrice := fmt.Sprintf("%.3f", stage.OrderPrice*float64(stage.OrderCount)) perBudgetPrice += stage.OrderPrice * float64(stage.OrderCount) b.FormatToEmpty(&budgetPrice) // 实际金额 perRealPrice += stage.OrderPrice * float64(stage.ConfirmCount) realPrice := fmt.Sprintf("%.3f", stage.OrderPrice*float64(stage.ConfirmCount)) b.FormatToEmpty(&realPrice) unit := stage.Unit if stage.Unit == "吨" || stage.Unit == "平方米" { unit = "张" } supplierName := "" if stage.SupplierInfo != nil { supplierName = stage.SupplierInfo.Name } stageType := "" if stage.BillType > 0 { stage.Type = stage.BillType } if stage.Type == 1 { stageType = "材料采购" } if stage.Type == 2 { stageType = "工艺" } if stage.Type == 3 { stageType = "成品采购" } // 状态 stageStatus := "" if len(stage.BillId) < 1 { stageStatus = "未生成订单" } else { if splan.State[stage.BillId] == "created" { stageStatus = "进行中" // 审核状态 if splan.Reviewed[stage.BillId] == 1 { stageStatus = "已审核" if splan.IsSend[stage.BillId] { stageStatus = "已发送" if splan.IsAck[stage.BillId] { stageStatus = "已接单" } else { stageStatus = "未接单" } } else { stageStatus = "未发送" } } else { stageStatus = "未审核" } } else if splan.State[stage.BillId] == "complete" { stageStatus = "已完成" } else { stageStatus = "未生成订单" } } // 订单存在时,订单号和下单时间// 合并相同的订单,记录row方便合并 if len(stage.BillId) == 24 { billFlag := fmt.Sprintf("%s_%s", splan.SerialNumber[stage.BillId], splan.CreateTimes[stage.BillId].Local().Format("2006-01-02")) cates[billFlag] = append(cates[billFlag], b.Row) } b.drawRow(b.Row, "", "", stageType, stage.Name, orderCount, realCount, stageStatus, supplierName, fmt.Sprintf("%.3f元/%s", stage.Price, stage.Unit), stage.Norm, matHeigth, matWidth, unit, price, budgetPrice, realPrice, "-", "-", stage.Remark) // if stage.SupplierInfo != nil { // cates[stage.SupplierInfo.Name] = append(cates[stage.SupplierInfo.Name], b.Row) // } b.Row++ } for billFlag, cate := range cates { billInfo := strings.Split(billFlag, "_") if len(billInfo) == 2 { mergeStartRow := cate[0] mergeEndRow := cate[len(cate)-1] b.Excel.MergeCell(b.SheetName, fmt.Sprintf("Q%d", mergeStartRow), fmt.Sprintf("Q%d", mergeEndRow)) b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("Q%d", mergeEndRow), billInfo[0]) b.Excel.MergeCell(b.SheetName, fmt.Sprintf("R%d", mergeStartRow), fmt.Sprintf("R%d", mergeEndRow)) b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("R%d", mergeEndRow), billInfo[1]) } } // for supplierName, cate := range cates { // mergeStartRow := cate[0] // mergeEndRow := cate[len(cate)-1] // b.Excel.MergeCell(b.SheetName, fmt.Sprintf("H%d", mergeStartRow), fmt.Sprintf("H%d", mergeEndRow)) // b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("H%d", mergeEndRow), supplierName) // } endRow := b.Row - 1 // 组件名字 startACell := fmt.Sprintf("%s%d", "B", startRow) endACell := fmt.Sprintf("%s%d", "B", endRow) b.Excel.MergeCell(b.SheetName, startACell, endACell) err := b.Excel.SetCellStyle(b.SheetName, startACell, endACell, b.AlignCenterStyle) if err != nil { return err } b.Excel.SetCellValue(b.SheetName, startACell, comp.Name) } // 预算 planBudgetPrice += perBudgetPrice // 实际金额 planRealPrice += perRealPrice } } totalBudgetPrice += planBudgetPrice totalRealPrice += planRealPrice // plan planEndRow := b.Row planStartACell := fmt.Sprintf("%s%d", "A", planStartRow) planEndACell := fmt.Sprintf("%s%d", "A", planEndRow-1) b.Excel.MergeCell(b.SheetName, planStartACell, planEndACell) err := b.Excel.SetCellStyle(b.SheetName, planStartACell, planEndACell, b.AlignCenterStyle) if err != nil { return err } b.Excel.SetCellValue(b.SheetName, planStartACell, fmt.Sprintf("%s(%d)", plan.Name, plan.Total)) } // summaryEndRow := b.Row // startACell := fmt.Sprintf("%s%d", "A", summaryEndRow) // endNell := fmt.Sprintf("%s%d", "N", summaryEndRow) // OCell := fmt.Sprintf("%s%d", "O", summaryEndRow) // PCell := fmt.Sprintf("%s%d", "P", summaryEndRow) // b.Excel.MergeCell(b.SheetName, startACell, endNell) // b.Excel.SetCellStyle(b.SheetName, startACell, endNell, b.AlignCenterStyle) // b.Excel.SetCellValue(b.SheetName, startACell, "生产计划汇总金额") // // 生产预算汇总 // b.Excel.SetCellStyle(b.SheetName, OCell, OCell, b.AlignCenterStyle) // totalOrderRealPrice := fmt.Sprintf("%.3f", totalBudgetPrice) // b.FormatToEmpty(&totalOrderRealPrice) // b.Excel.SetCellValue(b.SheetName, OCell, totalOrderRealPrice) // // 生产实际汇总 // b.Excel.SetCellStyle(b.SheetName, PCell, PCell, b.AlignCenterStyle) // totalRealPricef := fmt.Sprintf("%.3f", totalRealPrice) // b.FormatToEmpty(&totalRealPricef) // b.Excel.SetCellValue(b.SheetName, PCell, totalRealPricef) return nil } func (b *PlanSummaryExcel) drawSupplierContent() error { b.Row += 2 supplier := "" // summaryPlans // 预算金额汇总 var totalBudgetPrice float64 = 0.00 // 实际金额汇总 var totalRealPrice float64 = 0.00 for _, splan := range b.Content.Plans { planStartRow := b.Row plan := splan.Plan comps := plan.Pack.Components // 预算金额汇总 var planBudgetPrice float64 = 0.00 // 实际金额汇总 var planRealPrice float64 = 0.00 if len(comps) > 0 { for _, comp := range comps { var perBudgetPrice float64 = 0.00 var perRealPrice float64 = 0.00 if len(comp.Stages) > 0 { startRow := 0 cates := map[string][]int{} for _, stage := range comp.Stages { if stage.SupplierInfo != nil { if b.Content.SupplierId == stage.SupplierInfo.Id { supplier = stage.SupplierInfo.Name // 材料 if startRow == 0 { startRow = b.Row } matHeigth := fmt.Sprintf("%d", stage.BatchSizeHeight) b.FormatToEmpty(&matHeigth) matWidth := fmt.Sprintf("%d", stage.BatchSizeWidth) b.FormatToEmpty(&matWidth) orderCount := fmt.Sprintf("%d", int(stage.OrderCount)) b.FormatToEmpty(&orderCount) // 实际数量 realCount := fmt.Sprintf("%d", stage.ConfirmCount) b.FormatToEmpty(&realCount) // 单价 price := fmt.Sprintf("%.3f", stage.OrderPrice) b.FormatToEmpty(&price) // 预算金额 budgetPrice := fmt.Sprintf("%.3f", stage.OrderPrice*float64(stage.OrderCount)) perBudgetPrice += stage.OrderPrice * float64(stage.OrderCount) b.FormatToEmpty(&budgetPrice) // 实际金额 perRealPrice += stage.OrderPrice * float64(stage.ConfirmCount) realPrice := fmt.Sprintf("%.3f", stage.OrderPrice*float64(stage.ConfirmCount)) b.FormatToEmpty(&realPrice) unit := stage.Unit if stage.Unit == "吨" || stage.Unit == "平方米" { unit = "张" } supplierName := "" if stage.SupplierInfo != nil { supplierName = stage.SupplierInfo.Name } stageType := "" if stage.BillType > 0 { stage.Type = stage.BillType } if stage.Type == 1 { stageType = "材料采购" } if stage.Type == 2 { stageType = "工艺" } if stage.Type == 3 { stageType = "成品采购" } // 状态 stageStatus := "" if len(stage.BillId) < 1 { stageStatus = "未生成订单" } else { if splan.State[stage.BillId] == "created" { stageStatus = "进行中" // 审核状态 if splan.Reviewed[stage.BillId] == 1 { stageStatus = "已审核" if splan.IsSend[stage.BillId] { stageStatus = "已发送" if splan.IsAck[stage.BillId] { stageStatus = "已接单" } else { stageStatus = "未接单" } } else { stageStatus = "未发送" } } else { stageStatus = "未审核" } } else if splan.State[stage.BillId] == "complete" { stageStatus = "已完成" } else { stageStatus = "未生成订单" } } if len(stage.BillId) == 24 { billFlag := fmt.Sprintf("%s_%s", splan.SerialNumber[stage.BillId], splan.CreateTimes[stage.BillId].Local().Format("2006-01-02")) cates[billFlag] = append(cates[billFlag], b.Row) } b.drawRow(b.Row, "", "", stageType, stage.Name, orderCount, realCount, stageStatus, supplierName, fmt.Sprintf("%.3f元/%s", stage.Price, stage.Unit), stage.Norm, matHeigth, matWidth, unit, price, budgetPrice, realPrice, "-", "-", stage.Remark) // if stage.SupplierInfo != nil { // cates[stage.SupplierInfo.Name] = append(cates[stage.SupplierInfo.Name], b.Row) // } b.Row++ } } } for billFlag, cate := range cates { billInfo := strings.Split(billFlag, "_") if len(billInfo) == 2 { mergeStartRow := cate[0] mergeEndRow := cate[len(cate)-1] b.Excel.MergeCell(b.SheetName, fmt.Sprintf("Q%d", mergeStartRow), fmt.Sprintf("Q%d", mergeEndRow)) b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("Q%d", mergeEndRow), billInfo[0]) b.Excel.MergeCell(b.SheetName, fmt.Sprintf("R%d", mergeStartRow), fmt.Sprintf("R%d", mergeEndRow)) b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("R%d", mergeEndRow), billInfo[1]) } } // 合并同一供应商名 // for supplierName, cate := range cates { // mergeStartRow := cate[0] // mergeEndRow := cate[len(cate)-1] // b.Excel.MergeCell(b.SheetName, fmt.Sprintf("H%d", mergeStartRow), fmt.Sprintf("H%d", mergeEndRow)) // b.Excel.SetCellValue(b.SheetName, fmt.Sprintf("H%d", mergeEndRow), supplierName) // } if startRow != 0 { endRow := b.Row - 1 // 组件名字 startACell := fmt.Sprintf("%s%d", "B", startRow) endACell := fmt.Sprintf("%s%d", "B", endRow) b.Excel.MergeCell(b.SheetName, startACell, endACell) err := b.Excel.SetCellStyle(b.SheetName, startACell, endACell, b.AlignCenterStyle) if err != nil { return err } b.Excel.SetCellValue(b.SheetName, startACell, comp.Name) } } // 预算 totalBudgetPrice += perBudgetPrice // 预算 totalRealPrice += perRealPrice } } totalBudgetPrice += planBudgetPrice totalRealPrice += planRealPrice // plan // b.row +2 分割每个计划 planEndRow := b.Row planStartACell := fmt.Sprintf("%s%d", "A", planStartRow) planEndACell := fmt.Sprintf("%s%d", "A", planEndRow-1) b.Excel.MergeCell(b.SheetName, planStartACell, planEndACell) err := b.Excel.SetCellStyle(b.SheetName, planStartACell, planEndACell, b.AlignCenterStyle) if err != nil { return err } b.Excel.SetCellValue(b.SheetName, planStartACell, fmt.Sprintf("%s(%d)", plan.Name, plan.Total)) } // summaryEndRow := b.Row // startACell := fmt.Sprintf("%s%d", "A", summaryEndRow) // endNell := fmt.Sprintf("%s%d", "N", summaryEndRow) // OCell := fmt.Sprintf("%s%d", "O", summaryEndRow) // PCell := fmt.Sprintf("%s%d", "P", summaryEndRow) // b.Excel.MergeCell(b.SheetName, startACell, endNell) // b.Excel.SetCellStyle(b.SheetName, startACell, endNell, b.AlignCenterStyle) // b.Excel.SetCellValue(b.SheetName, startACell, fmt.Sprintf("【%s】生产计划汇总金额", supplier)) // // 生产预算汇总 // b.Excel.SetCellStyle(b.SheetName, OCell, OCell, b.AlignCenterStyle) // totalOrderRealPrice := fmt.Sprintf("%.3f", totalBudgetPrice) // b.FormatToEmpty(&totalOrderRealPrice) // b.Excel.SetCellValue(b.SheetName, OCell, totalOrderRealPrice) // // 生产实际汇总 // b.Excel.SetCellStyle(b.SheetName, PCell, PCell, b.AlignCenterStyle) // totalRealPricef := fmt.Sprintf("%.3f", totalRealPrice) // b.FormatToEmpty(&totalRealPricef) // b.Excel.SetCellValue(b.SheetName, PCell, totalRealPricef) // 供应商名字标题 style, err := b.Excel.NewStyle(&excelize.Style{ Alignment: &excelize.Alignment{Horizontal: "center", Vertical: "center", WrapText: true}, }) if err != nil { return err } err = b.Excel.SetCellStyle(b.SheetName, "A1", "G1", style) if err != nil { return err } b.Excel.SetRowHeight(b.SheetName, 1, 32) b.Excel.SetCellValue(b.SheetName, "A1", fmt.Sprintf("【%s】-汇总表", supplier)) return nil } func (b *PlanSummaryExcel) Draws() { b.drawTitle() b.drawTableTitle() if !b.Content.SupplierId.IsZero() { b.drawSupplierContent() } else { b.drawAllContent() } } func NewPlanSummaryExcel(f *excelize.File) *PlanSummaryExcel { 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 := &PlanSummaryExcel{ Title: "生产成本表", SheetName: "Sheet1", Excel: f, AlignCenterStyle: styleLeft, } f.SetColWidth(b.SheetName, "A", "D", 16) f.SetColWidth(b.SheetName, "E", "G", 12) f.SetColWidth(b.SheetName, "H", "H", 25) f.SetColWidth(b.SheetName, "I", "L", 16) f.SetColWidth(b.SheetName, "M", "M", 10) f.SetColWidth(b.SheetName, "N", "P", 13) f.SetColWidth(b.SheetName, "Q", "R", 16) f.SetColWidth(b.SheetName, "S", "S", 20) f.SetPageMargins(b.SheetName, excelize.PageMarginTop(0), excelize.PageMarginLeft(0), excelize.PageMarginRight(0)) return b } func (b *PlanSummaryExcel) FormatToEmpty(str *string) { if *str == "0" || *str == "0.000" { *str = "" } }