Install
openclaw skills install @seairteng/pdf-invoice-statopenclaw skills install @seairteng/pdf-invoice-stat基于 pdfplumber + PaddleOCR + PP-StructureV3 的本地提取方案,支持增值税电子发票(普通发票)、火车票、通行费等场景,输出格式化 Excel。
相比 v1.0.1 增量升级了 7 个本地版本(v2~v8)的改进:
合 计 正则贪婪匹配到 价税合计 跨行内容,导致通行费(金额和 合 计 分两行)税额=0** → 生/海/消:处理 PDF 渲染时的 *生产生活服务* 双星编码python3 invoice_extractor.py <PDF> [输出.xlsx],不硬编码路径| 特性 | 说明 |
|---|---|
| 票据类型 | 增值税电子发票(普通发票)+ 铁路电子客票(火车票)+ 通行费 |
| 提取字段 | 发票号码、日期、购买方、销售方、税号、项目名称、金额、税率、税额、价税合计 |
| 输出格式 | Excel(15 列,冻结首行,会计格式) |
| 本地运行 | 纯 Python + pdfplumber,无外部 API |
| 多税率处理 | 多税率发票税率留空 |
| 免税/不征税 | 税额=0,税率列显示对应文字 |
| 水印页兜底 | 支持水印遮挡场景的发票号/日期/税号兜底提取 |
| 火车票 | 自动识别票价/退票费,按 9%/6% 税率计算,含购方/税号/起终点车次 |
| 通行费 | 自动处理「合 计」跨行 bug |
clawhub install pdf-invoice-stat
python3 invoice_extractor.py <PDF路径> [输出Excel路径]
<PDF路径>:必填,合并 PDF 文件路径[输出Excel路径]:选填,默认在同目录下生成 <原文件名>_发票统计.xlsx# 示例1:指定输出路径
python3 invoice_extractor.py /path/to/invoices.pdf /path/to/output.xlsx
# 示例2:使用默认输出路径(PDF 同目录)
python3 invoice_extractor.py /path/to/invoices.pdf
| 情形 | 填写内容 |
|---|---|
| 单税率(如 3%、6%、13%) | 对应百分比 |
| 仅含"不征税"文字 | 不征税 |
| 仅含"免税"文字 | 免税 |
| 含多个不同税率 | 留空 |
| 情形 | 填写内容 |
|---|---|
| 免税/不征税 | 0 |
| 含税额 | 实际税额 |
识别特征: 含 电子客票 / 中国铁路 / 国铁 / 12306 字样时自动判定为火车票。
火车票与增值税发票处理逻辑不同,按"票价"和"退票费"两种场景区分:
| 字段 | 票价场景 | 退票费场景 |
|---|---|---|
| 购买方信息-名称 | 火车票"购买方名称"后公司名 | 同 |
| 购买方信息-统一社会信用代码 | 火车票"统一社会信用代码"后 18 位 | 同 |
| 销售方信息-名称 | 留空(铁路运输非销售方) | 留空 |
| 销售方信息-统一社会信用代码 | 留空 | 留空 |
| 项目名称 | "火车票" | "火车票-退票费" |
| 价税合计 | 火车票"票价:¥XX.XX"金额 | 火车票"退票费:¥XX.XX"金额 |
| 税率/征收率 | 9% | 6% |
| 税额 | =价税合计/(1+9%)×9% | =价税合计/(1+6%)×6% |
| 金额 | =价税合计-税额 | =价税合计-税额 |
| 备注 | "起点站-终点站,车次GXXXX" | 同 |
计算示例(保留 2 位小数):
新增字段填充:
单价 0 异常处理: PDF 上"退票费:"标签后无金额时,自动 fallback 到 ¥XX.XX 总价正则。
识别失败时 fallback: 购方/税号未识别到时,自动 fallback 到 PaddleOCR 二次抽取。
# 必需依赖
pip3 install pdfplumber openpyxl
# v2.2.0 新增:纯图片发票 OCR(可选,但建议装)
pip3 install paddlepaddle>=3.0 paddleocr>=3.0
# 首次运行会自动下载模型到 ~/.paddlex/official_models/ (~180MB)
# v2.3.0 新增:纯图片发票 + 复杂版面(可选,按需装)
pip3 install "paddlex[ocr]"
# 首次运行会自动下载模型到 ~/.paddlex/official_models/ (~290MB)
# PP-StructureV3 含 Layout + Table Recognition
不装 PaddleOCR 也能用: skill 默认用 pdfplumber 处理电子发票,只有遇到纯图片 PDF(扫描件、拍照)才需要 PaddleOCR fallback。
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 日期为空 | 水印页日期格式特殊 | 检查 PDF 水印样式,更新 normalize_date 兜底正则 |
| 税号为空 | 水印遮挡标签 | 检查 zone 扫描逻辑是否有新变体 |
| 项目名称为空 | ** 误输入 | 检查 parse_star_word 双星处理逻辑 |
| 金额为 0 但非火车票 | 合汁行提取失败 | 检查金额正则匹配逻辑(v2.0.0 已修复通行费跨行 bug) |
| 通行费税额=0 | v1 版本的跨行 bug | 升级到 v2.0.0 |
价税合计/(1+税率)×税率(保留 2 位小数)价税合计-税额extract_train_ticket_info() 函数:火车票字段抽取独立函数pp_structure.py 适配器(~315 行)~/.paddlex/official_models/(额外 ~290MB)paddlex[ocr]>=3.7parse_html_table 通用 HTML 表格解析器paddle_ocr.py 适配器(单例引擎)电子客票 / 中国铁路 / 国铁 / 12306 字样invoice_extractor.py 第 184-200 行 (get_page_info 火车票分支)** → 生/海/消 修复pdf-vat-invoice-extractor → 正确的 pdf-invoice-statMIT-0 License. 作者 seairteng.