package cmd import ( "fmt" "log" "path/filepath" "strings" "time" "github.com/mizuki1412/go-core-kit/class/exception" "github.com/mizuki1412/go-core-kit/init/initkit" "github.com/mizuki1412/go-core-kit/service/configkit" "github.com/spf13/cobra" "github.com/xuri/excelize/v2" ) func init() { rootCmd.AddCommand(gcoCmd) defFlagsGco(gcoCmd) } var gcoCmd = &cobra.Command{ Use: "gco", Short: "Generate construction order", Run: func(cmd *cobra.Command, args []string) { initkit.BindFlags(cmd) tp := configkit.GetString("gco.type", "kr") if tp == "kr" { handleGcoKr() } else if tp == "lx" { handleGcoLx() } }, } func defFlagsGco(cmd *cobra.Command) { cmd.Flags().String("gco.template", "", "*Specify the template used to generate construction order") cmd.Flags().String("gco.file", "", "*Specify the file used to generate construction order") cmd.Flags().String("gco.type", "", "*Specify the type used to generate construction order") } func handleGcoLx() { templatePath := configkit.GetString("gco.template", "/Users/leo/Desktop/归档/集客零星/模板.xlsx") filePath := configkit.GetString("gco.file", "/Users/leo/Desktop/归档/集客零星/集客零星资源归档.xlsx") src, err := excelize.OpenFile(filePath) if err != nil { panic(exception.New(err.Error())) } defer src.Close() rows, err := src.GetRows("施工单2026年") // todo 每年修改 if err != nil { panic(exception.New("缺少 Sheet:施工单2026年")) // todo 每年修改 } // 跳过表头 for i, row := range rows { if i == 0 { continue } // 防止越界 getVal := func(idx int) string { if idx >= len(row) { return "" } return strings.TrimSpace(row[idx]) } // Y列(索引24)标记为1 if getVal(24) != "1" { continue } // 打开模板 tpl, err := excelize.OpenFile(templatePath) if err != nil { log.Println("打开模板失败:", err) continue } sheet := "Sheet1" // 映射填充 _ = tpl.SetCellValue(sheet, "B2", getVal(2)) // C -> B2 _ = tpl.SetCellValue(sheet, "B3", getVal(0)) // A -> B3 _ = tpl.SetCellValue(sheet, "B4", getVal(12)) // M -> B4 _ = tpl.SetCellValue(sheet, "D4", getVal(13)) // N -> D4 _ = tpl.SetCellValue(sheet, "B5", getVal(3)) // D -> B5 _ = tpl.SetCellValue(sheet, "B6", getVal(14)) // O -> B6 _ = tpl.SetCellValue(sheet, "B7", getVal(10)) // K -> B7 _ = tpl.SetCellValue(sheet, "D7", getVal(11)) // L -> D7 _ = tpl.SetCellValue(sheet, "B8", getVal(8)) // I -> B8 _ = tpl.SetCellValue(sheet, "B9", getVal(9)) // J -> B9 // 文件名:B列-C列.xlsx fileName := fmt.Sprintf("%s-%s.xlsx", getVal(1), getVal(2)) // 清理非法文件名字符 fileName = strings.ReplaceAll(fileName, "/", "_") fileName = strings.ReplaceAll(fileName, "\\", "_") fileName = strings.ReplaceAll(fileName, ":", "_") fileName = strings.ReplaceAll(fileName, "*", "_") fileName = strings.ReplaceAll(fileName, "?", "_") fileName = strings.ReplaceAll(fileName, "\"", "_") fileName = strings.ReplaceAll(fileName, "<", "_") fileName = strings.ReplaceAll(fileName, ">", "_") fileName = strings.ReplaceAll(fileName, "|", "_") // 保存路径(默认保存在模板同目录) outPath := filepath.Join(filepath.Dir(templatePath), "施工单", fileName) if err := tpl.SaveAs(outPath); err != nil { log.Println("保存失败:", outPath, err) _ = tpl.Close() continue } _ = tpl.Close() fmt.Println("生成施工单:", outPath) } fmt.Println("全部生成完成") } func handleGcoKr() { templatePath := configkit.GetString("gco.template", "/Users/leo/Desktop/归档/公众扩容/施工单模板.xlsx") filePath := configkit.GetString("gco.file", "/Users/leo/Downloads/扩容需求表.xlsx") src, err := excelize.OpenFile(filePath) if err != nil { panic(exception.New(err.Error())) } defer src.Close() rows, err := src.GetRows("扩容需求表") if err != nil { panic(exception.New("缺少 Sheet:扩容需求表")) } // 今天日期 today := time.Now().Format("2006.01.02") today = strings.ReplaceAll(today, "-", ".") for i, row := range rows { if i == 0 { continue // 跳过表头 } // V 列 index = 21 if len(row) <= 22 || strings.TrimSpace(row[22]) != "1" { continue } // 必要字段 var bVal, dVal, eVal, fVal, gVal, lVal, dPrefix string if len(row) > 1 { bVal = strings.TrimSpace(row[1]) } if len(row) > 3 { dVal = strings.TrimSpace(row[3]) // D列 去掉“新增”及之后部分 if idx := strings.Index(dVal, "新增"); idx != -1 { dPrefix = dVal[:idx] } else { dPrefix = dVal } } if len(row) > 4 { eVal = strings.TrimSpace(row[4]) } if len(row) > 5 { fVal = strings.TrimSpace(row[5]) } if len(row) > 6 { gVal = strings.TrimSpace(row[6]) } if len(row) > 11 { lVal = strings.TrimSpace(row[11]) } // 打开模板(每次都打开一次,保证生成多份文件不会覆盖) tpl, err := excelize.OpenFile(templatePath) if err != nil { panic(exception.New("缺少 Sheet:扩容需求表")) } sheet := "Sheet1" // 写入日期 tpl.SetCellValue(sheet, "B5", today) tpl.SetCellValue(sheet, "B15", today) // 写入 D 列 tpl.SetCellValue(sheet, "B2", dVal) tpl.SetCellValue(sheet, "B12", dVal) // 写入 E 列 tpl.SetCellValue(sheet, "B9", eVal) tpl.SetCellValue(sheet, "B19", eVal) // 写入 D 去掉新增之前部分 tpl.SetCellValue(sheet, "B6", dPrefix) tpl.SetCellValue(sheet, "B16", dPrefix) // 输出文件名(F列 + D列) outName := "" if fVal == "" || fVal == "等无条件自动工单" || fVal == "需下" { outName = fmt.Sprintf("%s.xlsx", dVal) } else { outName = fmt.Sprintf("%s-%s.xlsx", dVal, fVal) } finishDate := time.Now() if gVal == "全覆盖" { finishDateStr := finishDate.AddDate(0, 0, 2).Format("1月2日") outName = finishDateStr + "需完成" + outName } else if gVal == "部分覆盖" { finishDateStr := finishDate.AddDate(0, 0, 5).Format("1月2日") outName = finishDateStr + "需完成" + outName } else if gVal == "未覆盖" { finishDateStr := finishDate.AddDate(0, 0, 15).Format("1月2日") outName = finishDateStr + "需完成" + outName } thisMonth := time.Now().Format("2006.01") bVal = strings.TrimSuffix(bVal, "网格") if lVal == "市公司整批扩容二级分光器清单" { outName = "(" + bVal + ")" + outName thisMonth = "批量二级" + time.Now().Format("2006.1.2") } outPath := filepath.Join(filepath.Dir(templatePath), "施工单", thisMonth, outName) err = tpl.SaveAs(outPath) if err != nil { panic(exception.New(err.Error())) } tpl.Close() fmt.Println("生成施工单:", outPath) } fmt.Println("全部生成完成") }