# WareShipManifest · 装箱单报表系统 基于 **ReportBro**(`reportbro-lib`,纯 Python)生成装箱单 PDF。报表定义(SQL / 模板 / 数据装配)均为纯文本,可被 Git 管理;后期对接真实打印机时,PDF 方案可直接复用。 > 业务背景:把 CargoTrace 成品库分拣系统的装箱数据,打印成装箱单随货流转。 > 一个箱子一份 PDF,展示该箱装了哪些内容物(总排号)及其产品信息。 ## 快速开始 ```bash # 1. 建虚拟环境并装依赖 python -m venv .venv .venv/Scripts/python.exe -m pip install -r requirements.txt # Windows / Git Bash # 2. 配置数据库(复制模板并填凭据,或直接复用 services/fastapi 的 settings.yaml) cp config/settings.example.yaml config/settings.yaml # 编辑 config/settings.yaml 填入真实 host/数据库/账号密码 # 3. 生成装箱单 .venv/Scripts/python.exe run.py --report packing_list \ --param paichan_no=R04398 --param box_no=1 \ --output out/R04398_box1.pdf # → out/R04398_box1.pdf ``` ## 用法 ```bash python run.py --report packing_list \ --param paichan_no=<排产号> \ --param box_no=<箱号> \ --output <输出路径.pdf> # 可选,默认 out/<排产号>_box<箱号>.pdf ``` - 缺少参数 → 提示缺少哪个参数。 - 排产号 + 箱号无装箱明细 → 提示「找不到该箱」。 - 均以非零退出码退出,便于脚本集成。 ## 报表内容 | 区域 | 内容 | |---|---| | 标题 | 装箱单 / PACKING LIST + 分隔线 | | 信息条 | 排产号、箱号、装箱日期、订单号(2×2 网格,标签灰 + 值黑) | | 列头 | 序号 · 总排号 · 产品型号 · 量程 · 位号 · 数量 · 工令号(小号灰) | | 明细 | 逐行文本,行间细灰线;无网格边框 | | 合计 | 合计 N 件(右对齐于数量列下) | | 页脚 | 生成时间 | - **无边框、单色、字体驱动**:靠字号 / 字重 / 留白 / 细灰分隔线建立层次,不用表格网格。 - **位号**:合同表字段,多数订单为空,有则显示、无则留白。 - **产品型号**为超长编码串,按列宽换行,行高自适应。 ## 数据来源 | 表 | 作用 | |---|---| | `CargoTrace.finished_goods_box` | 箱头(排产号 + 箱号 + 装箱时间) | | `CargoTrace.finished_goods_box_item` | 箱内明细(总排号 + 装入数量) | | `productionContractData.26年压力表合同数据` / `26年温度计合同数据` | 产品信息(型号/量程/位号/工令号/订单号) | 同一总排号只命中压力表或温度计其中一张表,用双 `LEFT JOIN + COALESCE` 取产品字段, 避免前缀误匹配(`26BW` 不会被 `26B%` 命中)。 ## 目录结构 ``` WareShipManifest/ ├── config/ │ ├── settings.example.yaml # 配置模板(提交) │ └── settings.yaml # 真实凭据(gitignore) ├── core/ │ ├── settings.py # 读 yaml → mssql+pyodbc 连接 URL │ ├── db.py # run_query(sql, params) 参数化绑定 │ └── fonts.py # 中文字体注册(simhei via additional_fonts) ├── reports/packing_list/ │ ├── query.sql # 参数化查询(:paichan_no / :box_no) │ ├── transform.py # build_context(rows) → 预展开标量参数 + 行高估算(纯逻辑) │ ├── _build_template.py # 样式 + 运行时按数据动态布局的文档元素(无边框列表式) │ └── config.yaml # 报表元信息(参数/字段说明) ├── tests/test_transform.py # 纯逻辑单测 ├── run.py # CLI 入口 ├── requirements.txt └── README.md ``` ## 开发 ### 改报表版式(列宽 / 字号 / 边距 / 配色 / 行距) 版式全部在 `reports/packing_list/_build_template.py` 中以代码定义(常量 + 样式工厂)。 文档元素在运行时按数据动态生成(明细行高度自适应),无需预生成模板文件—— 直接改代码后重跑 `run.py` 即生效。 > 不使用 ReportBro 可视化设计器,也不用其表格元素(行高不自适应、行不自动堆叠); > 改用纯文本元素 + 细横线手工排版,坐标完全可控,靠字号/字重/留白建立层次。 ### 改查询 / 数据装配 - SQL:`reports/packing_list/query.sql`(参数化,禁字符串拼接)。 - 数据装配:`reports/packing_list/transform.py` 的 `build_context`(纯逻辑,含单测)。 ### 跑测试 ```bash .venv/Scripts/python.exe -m pytest -q ``` ### 中文字体 核心字体(helvetica 等)无法编码中文,故通过 `core/fonts.py` 注册 `C:/Windows/Fonts/simhei.ttf`(黑体),模板样式 `font="simhei"`。 跨机器部署若缺该字体,可用环境变量 `REPORT_CJK_FONT` 指定其它支持中文的 ttf。 ## 技术说明 - **reportbro-lib**:纯 Python(`pip install reportbro-lib`),无需 Docker / 浏览器 / 设计器常驻服务。 - 数据处理与展示分离:排序在 SQL、合计与日期在 transform、模板只渲染。 - 生成的 PDF 可用 `pymupdf`(`fitz`)渲染 PNG 做肉眼核对(验证用,非运行时依赖)。 ## 路线图 - [ ] 后期对接真实打印机(PDF 方案可直接复用)。 - [ ] 发货信息单(地址 / 收件人 / 总件数 / 物料编码)—— 与装箱单拆分,另出报表。