From fb686e3058e5b0eab96b0826e8bd905b669bd467 Mon Sep 17 00:00:00 2001 From: YANG JIANKUAN Date: Wed, 9 Sep 2026 10:52:45 +0800 Subject: [PATCH] feat: new module --- README.md | 1 + output/生产系统/生产系统增补报价单.xlsx | Bin 0 -> 12363 bytes scripts/gen_production_addon_quote.py | 180 ++++++++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 output/生产系统/生产系统增补报价单.xlsx create mode 100644 scripts/gen_production_addon_quote.py diff --git a/README.md b/README.md index 14cc189..3747268 100644 --- a/README.md +++ b/README.md @@ -32,3 +32,4 @@ CLAUDE.md 报价规则:单价、计费口径、人天基准、格式规范 | 项目 | 人天 | 单价 | 金额 | 时间 | |---|---|---|---|---| | 生产系统(化工 AI 优化) | 194 | 1200 | 232,800 元 | 2026-08 | +| 生产系统增补(扩到净化、水处理、二洗三工段) | 99 | 1200 | 118,800 元 | 2026-09 | diff --git a/output/生产系统/生产系统增补报价单.xlsx b/output/生产系统/生产系统增补报价单.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..012fdbf4d176abd4a37b7d822202ff180df9960a GIT binary patch literal 12363 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

Z~O{SUOnZ%Ju0s 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 (起始行, 结束行) +row = 4 +for idx, (cat, name, days) in enumerate(items, 1): + ws.cell(row=row, column=1, value=idx) + ws.cell(row=row, column=2, value=cat) + ws.cell(row=row, column=3, value=name) + ws.cell(row=row, column=4, value=days) + ws.cell(row=row, column=5, value=f"=D{row}*{RATE}") + for col in range(1, 6): + c = ws.cell(row=row, column=col) + c.font = Font(name=FONT, size=11) + c.border = border + if col == 3: + c.alignment = Alignment(horizontal="left", vertical="center", wrap_text=True) + elif col in (4, 5): + c.alignment = Alignment(horizontal="right", vertical="center", wrap_text=True) + else: + c.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True) + if cat not in cat_ranges: + cat_ranges[cat] = [row, row] + cat_ranges[cat][1] = row + row += 1 + +total_row = row +# 类别列合并 + 填色 +for cat, (r1, r2) in cat_ranges.items(): + if r2 > r1: + ws.merge_cells(start_row=r1, start_column=2, end_row=r2, end_column=2) + a = ws.cell(row=r1, column=2) + a.fill = PatternFill("solid", fgColor=LIGHT) + for r in range(r1, r2 + 1): + ws.cell(row=r, column=2).fill = PatternFill("solid", fgColor=LIGHT) + +ws.merge_cells(start_row=total_row, start_column=1, end_row=total_row, end_column=3) +ws.cell(row=total_row, column=1, value="合计") +ws.cell(row=total_row, column=4, value=f"=SUM(D4:D{total_row-1})") +ws.cell(row=total_row, column=5, value=f"=SUM(E4:E{total_row-1})") +for col in range(1, 6): + c = ws.cell(row=total_row, column=col) + c.font = Font(name=FONT, size=11, bold=True) + c.fill = PatternFill("solid", fgColor=GREEN) + c.border = border + c.alignment = Alignment( + horizontal="right" if col in (4, 5) else "center", vertical="center" + ) + +for col, w in zip("ABCDE", [6, 16, 56, 9, 15]): + ws.column_dimensions[col].width = w + +# ---------- 报价汇总 ---------- +ws2 = wb.create_sheet("报价汇总", 0) +ws2.merge_cells("A1:E1") +c = ws2["A1"] +c.value = "生产系统增补报价汇总" +c.font = Font(name=FONT, size=15, bold=True, color="FFFFFF") +c.fill = PatternFill("solid", fgColor=DARK) +c.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True) +ws2.row_dimensions[1].height = 34 + +headers2 = ["序号", "功能 / 模块", "范围说明", "人天", "金额(元)"] +for i, h in enumerate(headers2, 1): + c = ws2.cell(row=3, column=i, value=h) + c.font = Font(name=FONT, size=11, bold=True, color="FFFFFF") + c.fill = PatternFill("solid", fgColor=DARK) + c.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True) + c.border = border +ws2.row_dimensions[3].height = 24 + +r = 4 +for i, (name, scope) in enumerate(summary_rows, 1): + r1, r2 = cat_ranges[name] + ws2.cell(row=r, column=1, value=i) + ws2.cell(row=r, column=2, value=name) + ws2.cell(row=r, column=3, value=scope) + ws2.cell(row=r, column=4, value=f"=SUM(报价明细!D{r1}:D{r2})") + ws2.cell(row=r, column=5, value=f"=SUM(报价明细!E{r1}:E{r2})") + for col in range(1, 6): + c = ws2.cell(row=r, column=col) + c.font = Font(name=FONT, size=11) + c.border = border + if col == 3: + c.alignment = Alignment(horizontal="left", vertical="center", wrap_text=True) + elif col in (4, 5): + c.alignment = Alignment(horizontal="right", vertical="center", wrap_text=True) + else: + c.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True) + r += 1 + +sum_total = r +ws2.merge_cells(start_row=sum_total, start_column=1, end_row=sum_total, end_column=3) +ws2.cell(row=sum_total, column=1, value="合计") +ws2.cell(row=sum_total, column=4, value=f"=SUM(D4:D{sum_total-1})") +ws2.cell(row=sum_total, column=5, value=f"=SUM(E4:E{sum_total-1})") +for col in range(1, 6): + c = ws2.cell(row=sum_total, column=col) + c.font = Font(name=FONT, size=11, bold=True) + c.fill = PatternFill("solid", fgColor=GREEN) + c.border = border + c.alignment = Alignment( + horizontal="right" if col in (4, 5) else "center", vertical="center" + ) + +for col, w in zip("ABCDE", [6, 18, 50, 10, 16]): + ws2.column_dimensions[col].width = w + +wb.save(OUT) +print("saved:", OUT, "| 明细行数:", len(items), "| 合计人天:", sum(d for _, _, d in items))