# 差旅报销自动化流程 ## 给大模型的自动执行入口 当用户把本 `README.md` 提供给大模型,或让大模型在本目录处理差旅报销时,大模型应直接按下面流程开始执行,不需要用户再复制额外提示词: 1. 先阅读本说明,确认当前目录是报销目录。 2. 检查当前目录是否存在基础文件:`差旅报销.py`、`差旅费明细表.xlsx`、本次报销 PDF。 3. 如果 `报销输出/pdf_raw_text.txt` 不存在,自动运行: ```bash python3 差旅报销.py extract ``` Windows 环境可改用: ```powershell py 差旅报销.py extract ``` 4. 读取 `报销输出/pdf_raw_text.txt`,按本文的 JSON Schema 分析出差人、日期、事由、费用分类、金额和证据。 5. 如果出差人、出差事由、出发地、目的地、日期、金额等关键信息无法从原文可靠判断,必须先问用户;不要编造。 6. 将最终 JSON 保存为 `报销输出/analyzed_result.json`。 7. 确认 `questions` 为空、金额合计一致、附件张数一致后,自动运行: ```bash python3 差旅报销.py fill 报销输出/analyzed_result.json ``` Windows 环境可改用: ```powershell py 差旅报销.py fill 报销输出/analyzed_result.json ``` 8. 最后告诉用户生成的 Excel 文件路径,以及是否有任何需要人工复核的证据或假设。 > 简单说:看到本 README 后,大模型应自动完成“提取 PDF 原文 → 分析生成 JSON → 填写 Excel”,只有在信息不确定时才暂停询问用户。 --- ## 核心思想 这个流程分成三段: 1. **Python 提取原文**:只把 PDF 内容提取成 TXT,不理解、不计算、不猜测。 2. **大模型分析**:读取 TXT,判断出差人、日期、事由、费用分类和金额,输出标准 JSON。 3. **Python 填表**:只读取 JSON,把数据填入 Excel 模板,生成最终 XLSX。 也就是说:**Python 只做机械衔接,大模型负责理解发票内容。** --- ## 基础三件套 每次复用这个流程,只需要保留下面三个基础文件: | 文件 | 作用 | |------|------| | `差旅费明细表.xlsx` | 原始 Excel 模板,脚本会复制它,不直接修改 | | `差旅报销.py` | 唯一 Python 脚本,提供 `extract` / `schema` / `fill` 三个命令 | | `README.md` | 本说明,给人和大模型看 | PDF 发票、`pdf_raw_text.txt`、`analyzed_result.json`、最终 XLSX 都是每次报销产生的过程文件或结果文件。 --- ## 为什么使用 XLSX 为了跨平台,模板统一使用 `.xlsx`。 这样脚本只依赖 Python 包: ```text pdfplumber # 提取 PDF 文本 openpyxl # 复制和填写 xlsx 模板 ``` 不再依赖 LibreOffice,也不需要系统命令做 `.xls` / `.xlsx` 转换。 如果你手里只有 `.xls` 模板,请先用 Excel、WPS 或 LibreOffice 手动另存为: ```text 差旅费明细表.xlsx ``` --- ## 依赖安装 ### Windows ```powershell py -m pip install pdfplumber openpyxl ``` 运行时使用: ```powershell py 差旅报销.py extract py 差旅报销.py fill 报销输出/analyzed_result.json ``` ### Linux / macOS ```bash python3 -m pip install pdfplumber openpyxl ``` 运行时使用: ```bash python3 差旅报销.py extract python3 差旅报销.py fill 报销输出/analyzed_result.json ``` --- ## 标准目录结构 ```text 报销目录/ ├── 差旅费明细表.xlsx # 必需:模板 ├── 差旅报销.py # 必需:脚本 ├── README.md # 必需:说明 ├── 住宿.pdf # 本次报销 PDF ├── 机票*.pdf # 本次报销 PDF ├── 滴滴出行行程报销单*.pdf # 本次报销 PDF └── 滴滴电子发票*.pdf # 本次报销 PDF ``` 脚本输出统一放到: ```text 报销输出/ ``` 运行后会形成: ```text 报销目录/ └── 报销输出/ ├── pdf_raw_text.txt ├── analyzed_result.json ├── schema_example.json # 可选 └── 差旅费明细表_xxxx_20260520_广州_售后维修.xlsx ``` --- ## 使用流程 ### Step 1:提取 PDF 原文 ```bash python3 差旅报销.py extract ``` Windows 可用: ```powershell py 差旅报销.py extract ``` 输出: ```text 报销输出/pdf_raw_text.txt ``` 这个文件按 PDF 文件分块保存原始文本,例如: ```text ============================================================ 文件: 住宿.pdf ============================================================ 电子发票(增值税专用发票) ... ============================================================ 文件: 滴滴出行行程报销单A.pdf ============================================================ 滴滴出行-行程单 ... ``` 注意:这一步**不会**提取金额、不会判断类型、不会计算总额。 --- ### Step 2:让大模型分析 TXT 并输出 JSON 把 `报销输出/pdf_raw_text.txt` 交给大模型,让大模型生成: ```text 报销输出/analyzed_result.json ``` 可以先查看 JSON 模板: ```bash python3 差旅报销.py schema ``` 也可以直接输出模板文件: ```bash python3 差旅报销.py schema --output ``` 输出: ```text 报销输出/schema_example.json ``` #### 给大模型的推荐提示词 ```text 请根据本 README 自动处理当前目录的差旅报销。 你的任务: 1. 如果 `报销输出/pdf_raw_text.txt` 不存在,先运行 `python3 差旅报销.py extract` 提取 PDF 原文。 2. 读取 `报销输出/pdf_raw_text.txt`,从 PDF 原文中识别出差人、出差事由、出发日期、结束日期、出发地、目的地、出行方式、出差天数。 3. 将费用分为:住宿、交通、饮食、其他。 4. 每个费用类别都要给出金额、单据张数、说明。 5. 计算附件总张数、报销总额、预借差旅费、补领金额、退还金额。 6. 每个金额必须写入 evidence,说明来自哪个文件、依据是哪段文本。 7. 如果某个字段无法可靠判断,必须先问用户,不要编造;在未确认前不要填表。 8. 将最终 JSON 保存为 `报销输出/analyzed_result.json`,JSON 必须符合 README 中的 schema。 9. 确认 `questions` 为空、金额合计一致、附件张数一致后,运行 `python3 差旅报销.py fill 报销输出/analyzed_result.json` 生成最终 Excel。 10. 最后告诉用户生成的 Excel 文件路径,并列出需要人工复核的证据或假设。 ``` --- ## JSON Schema 大模型必须输出如下结构: ```json { "meta": { "出差人": "xxxx", "出差事由": "前往广州进行售后维修工作", "出发日期": "2026/5/20", "结束日期": "2026/5/22", "出发地": "北京", "目的地": "广州", "出行方式": "飞机", "出差天数": 3, "事由简写": "售后维修" }, "expenses": { "住宿": { "金额": 510.0, "单据张数": 1, "说明": "广州市番禺明乐宾馆住宿费" }, "交通": { "金额": 2013.77, "单据张数": 5, "说明": "机票1690.00 + 滴滴323.77" }, "饮食": { "金额": 0.0, "单据张数": 0, "说明": "未发现餐饮发票" }, "其他": { "金额": 0.0, "单据张数": 0, "说明": "无其他费用" } }, "summary": { "附件总张数": 6, "报销总额": 2523.77, "预借差旅费": 0.0, "补领金额": 2523.77, "退还金额": 0.0 }, "evidence": [ { "文件": "住宿.pdf", "类别": "住宿", "金额": 510.0, "依据": "价税合计(小写)¥510.00" }, { "文件": "机票预订出行订单尾号87377629-电子普通发票.pdf", "类别": "交通", "金额": 1690.0, "依据": "价税合计(小写)¥1690.00" } ], "questions": [] } ``` ### 字段说明 | 字段 | 说明 | |------|------| | `meta.出差人` | 出差人姓名,不确定就问用户 | | `meta.出差事由` | 出差目的,不确定就问用户 | | `meta.出发日期` / `meta.结束日期` | 格式建议为 `YYYY/M/D` | | `meta.出差天数` | 含首尾日期,例如 5/20 至 5/22 为 3 天 | | `expenses.住宿` | 酒店住宿类费用 | | `expenses.交通` | 机票、火车、打车等交通类费用 | | `expenses.饮食` | 餐饮费用,没有就 0 | | `expenses.其他` | 不属于前三类的费用,没有就 0 | | `summary.附件总张数` | 四类费用单据张数之和 | | `summary.报销总额` | 四类费用金额之和 | | `evidence` | 每笔金额的来源证据,便于人工核对 | | `questions` | 如果大模型无法判断,可以列出问题;最终填表前应为空 | --- ## Step 3:读取 JSON 并填表 ```bash python3 差旅报销.py fill 报销输出/analyzed_result.json ``` Windows 可用: ```powershell py 差旅报销.py fill 报销输出/analyzed_result.json ``` 脚本会: 1. 校验 JSON 字段是否完整 2. 校验金额合计是否一致 3. 校验附件张数是否一致 4. 复制 `差旅费明细表.xlsx` 5. 用 openpyxl 填入固定单元格 6. 输出最终 XLSX 到 `报销输出/` 输出文件命名规则: ```text 差旅费明细表_[出差人]_[出发日期YYYYMMDD]_[目的地]_[事由简写].xlsx ``` 示例: ```text 报销输出/差旅费明细表_xxxx_20260520_广州_售后维修.xlsx ``` --- ## Excel 填写位置 脚本只填写这些单元格: | 单元格 | 内容 | |--------|------| | `E3` | 出差事由 | | `A6` | 出发日期-结束日期 | | `B6` | 出发地-目的地 | | `C6` | 出差天数 | | `D6` | 出行方式 | | `H6` / `I6` | 住宿单据张数 / 住宿金额 | | `H7` / `I7` | 饮食单据张数 / 饮食金额 | | `H8` / `I8` | 交通单据张数 / 交通金额 | | `H9` / `I9` | 其他单据张数 / 其他金额 | 脚本**不会覆盖公式单元格**,例如: | 单元格 | 公式 | |--------|------| | `H2` | 附件张数合计 | | `F9` | 天数合计 | | `C10` | 报销总额 | | `H10` | 补领金额 | | `H11` | 退还金额 | --- ## 校验规则 `fill` 命令会检查: ```text summary.报销总额 = 住宿金额 + 交通金额 + 饮食金额 + 其他金额 summary.附件总张数 = 住宿单据张数 + 交通单据张数 + 饮食单据张数 + 其他单据张数 ``` 如果不一致,脚本会停止,不会写 Excel。 --- ## 本次数据示例 ```json { "meta": { "出差人": "xxxx", "出差事由": "前往广州进行售后维修工作", "出发日期": "2026/5/20", "结束日期": "2026/5/22", "出发地": "北京", "目的地": "广州", "出行方式": "飞机", "出差天数": 3, "事由简写": "售后维修" }, "expenses": { "住宿": {"金额": 510.0, "单据张数": 1, "说明": "住宿费"}, "交通": {"金额": 2013.77, "单据张数": 5, "说明": "机票1690.00 + 滴滴323.77"}, "饮食": {"金额": 0.0, "单据张数": 0, "说明": "无餐饮发票"}, "其他": {"金额": 0.0, "单据张数": 0, "说明": "无其他费用"} }, "summary": { "附件总张数": 6, "报销总额": 2523.77, "预借差旅费": 0.0, "补领金额": 2523.77, "退还金额": 0.0 }, "evidence": [], "questions": [] } ``` --- ## 常见错误 ### 1. `找不到模板文件:差旅费明细表.xlsx` 确认当前目录存在: ```text 差旅费明细表.xlsx ``` 如果只有 `.xls`,请先用 Excel / WPS / LibreOffice 另存为 `.xlsx`。 ### 2. `报销总额不一致` 说明 JSON 里的总额和分类费用合计不一致,检查: ```text 住宿 + 交通 + 饮食 + 其他 ``` ### 3. `附件总张数不一致` 说明 JSON 里的附件总数和分类单据张数合计不一致。 ### 4. 缺少 Python 库 Windows: ```powershell py -m pip install pdfplumber openpyxl ``` Linux / macOS: ```bash python3 -m pip install pdfplumber openpyxl ```