AI PLAY玩法更新持续收录
← 回到更新流

2026-09-22 · 原文发布日

本地发票PDF批量提取校验并转Excel

免费n8n模板(需自托管Community版):定时读取本地文件夹中的发票PDF,提取文本后交给GPT-4o-mini按严格JSON schema抽取发票头字段和行项目,再校验必填字段和小计金额一致性;每张发票输出一个Excel文件,源PDF按校验结果移入valid/invalid/error文件夹,最后覆盖生成一份含总数和耗时的执行报告。需开放文件系统权限并挂载/invoices目录。

原文要点

原模板页事实:免费 n8n 模板,需 Community 自托管以获得本地文件访问;按日调度,先判断是否本地部署,建执行报告 Excel,再读本地输入夹全部 PDF;逐个提取文本,不可读进错误处理;清洗后交 OpenAI gpt-4o-mini 按严格 JSON schema 抽发票头和行项目;规范化后校验必填字段与行项目/小计一致;每张发票写一个 Excel,源 PDF 移入 valid/invalid/error 并从输入删除;累计 total/valid/invalid/error 并覆盖写报告。需开放 fs/path 并限制到 /invoices,建 input/output/valid/invalid/error,配置 OpenAI 凭据。

这次做成什么

搭一条隔离测试用本地发票 PDF 流水线:定时触发→读 /invoices/input→提取/清洗文本→GPT-4o-mini 严格 JSON 抽取→Code 节点校验→按发票写 Excel→移动源文件到 valid/invalid/error→覆盖执行报告。本站给出字段映射、schema、测试数据和配置;不编造可导入 n8n JSON,节点名以原模板与当前 n8n 版本核对。

准备什么

  • Docker 可运行的自托管 n8n Community Edition,非云服务受限环境
  • 已挂载隔离目录 /invoices 且含 input output valid invalid error 五个子夹
  • n8n 中已新建 OpenAI API credential 并授权给 OpenAI 节点
  • 允许文件系统内置模块并限制访问范围的环境变量权限
  • 只用合成发票 PDF 与测试凭据,不放真实客户个人信息或密钥

具体怎么做

  1. 建目录与限制文件权限

    在宿主机建 ./invoices/{input,output,valid,invalid,error},挂载到容器 /invoices;用下方 configuration 设置 NODE_FUNCTION_ALLOW_BUILTIN=fs,path 与 N8N_RESTRICT_FILE_ACCESS_TO=/invoices,重启 n8n 后在测试执行里确认只能读写 /invoices。

  2. 打开模板并核对链路

    在 n8n 打开模板 19810 或按原文描述重建:Schedule Trigger→本地部署/文件系统判断→初始化报告 Excel→Read Binary Files 读 /invoices/input/*.pdf→Extract from File 取文本→IF 不可读分支→Code 清洗→OpenAI→Code 校验/规范化→写 Excel→Move File→更新计数与报告。原页未给下载 JSON 时,不要导入来路不明文件。

  3. 配置凭据与 schema

    在 OpenAI 节点选已建 credential,模型保持模板所写的 gpt-4o-mini 除非你在账号另有预算;把 artifact 的抽取提示词与 JSON schema 放入系统/用户提示或输出解析处,要求仅返回 JSON。字段映射以 artifact 为准,缺字段先置 null 再交校验。

  4. 跑一张合成发票

    把 example 的合成发票文本做成 invoice_demo.pdf 放入 input,手动执行一次;期待 output 出现 INV-2026-0001.xlsx,input 清空,PDF 进入 valid;把金额改成不相等再跑一次,期待进入 invalid,并在执行报告看到 total/valid/invalid/error 计数变化。

可直接复制的材料

发票抽取提示词与严格 schema

本站独立编写,按原页“严格 JSON schema、校验必填和小计”描述实现;接入位置与输出解析器需在模板内核对。

你是发票结构化抽取器。只根据给定文本抽取,禁止猜测、禁止补银行账号或真实个人信息。返回且仅返回符合 schema 的 JSON;金额用数字不用千分位;日期统一 YYYY-MM-DD;无法确定用 null。schema={"type":"object","additionalProperties":false,"required":["invoice_number","invoice_date","seller_name","buyer_name","currency","subtotal","tax","total","line_items"],"properties":{"invoice_number":{"type":["string","null"]},"invoice_date":{"type":["string","null"]},"seller_name":{"type":["string","null"]},"buyer_name":{"type":["string","null"]},"currency":{"type":["string","null"]},"subtotal":{"type":["number","null"]},"tax":{"type":["number","null"]},"total":{"type":["number","null"]},"line_items":{"type":"array","items":{"type":"object","additionalProperties":false,"required":["description","quantity","unit_price","amount"],"properties":{"description":{"type":"string"},"quantity":{"type":"number"},"unit_price":{"type":"number"},"amount":{"type":"number"}}}}}}。校验规则:必填字段非空;每个 amount≈quantity*unit_price;subtotal≈行项目 amount 之和;total≈subtotal+tax;容差 0.01;币种为 CNY/USD/EUR 之一或 null。

字段映射与测试数据

INV-2026-0002 故意让行项目 100 与 subtotal 90 不一致,应进 invalid;全是虚构演示数据。

{
  "excel_invoice_row": {"invoice_number":"header.invoice_number","invoice_date":"header.invoice_date","seller_name":"header.seller_name","buyer_name":"header.buyer_name","currency":"header.currency","subtotal":"header.subtotal","tax":"header.tax","total":"header.total","validation_status":"valid|invalid|error","source_pdf":"file.name"},
  "excel_line_row": {"invoice_number":"header.invoice_number","line_no":"index+1","description":"item.description","quantity":"item.quantity","unit_price":"item.unit_price","amount":"item.amount"},
  "report_columns": ["run_id","start_time","end_time","total","valid","invalid","error","duration_seconds"],
  "test_invoice_csv": "invoice_number,invoice_date,seller_name,buyer_name,currency,description,quantity,unit_price,amount,subtotal,tax,total\nINV-2026-0001,2026-09-01,示例供应商有限公司,演示采购部,CNY,云存储 100GB 月费,2,49.5,99,99,5.94,104.94\nINV-2026-0002,2026-09-02,示例供应商有限公司,演示采购部,CNY,备份服务 月费,1,100,100,90,5.4,104.94"
}

隔离 Docker 环境示例

仅本地隔离测试示例;密码必须替换,OpenAI key 放 n8n credentials 而非写进 compose;版本未核实前不保证命令可运行。

services:
  n8n:
    image: n8nio/n8n:latest
    environment:
      - NODE_FUNCTION_ALLOW_BUILTIN=fs,path
      - N8N_RESTRICT_FILE_ACCESS_TO=/invoices
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=demo_admin
      - N8N_BASIC_AUTH_PASSWORD=replace_with_local_only_password
    volumes:
      - ./invoices:/invoices
      - ./n8n-data:/home/node/.n8n
    ports:
      - "127.0.0.1:5678:5678"

输入与输出示例

本站虚构演示输入输出,字段与数字相互对应;未真实调用 OpenAI 或原模板。

输入

合成 PDF 文本含:发票号 INV-2026-0001,日期 2026-09-01,卖方示例供应商有限公司,买方演示采购部;两行云存储各 2×49.5,subtotal 99,tax 5.94,total 104.94 CNY。

对应输出

期望 JSON 关键行:{"invoice_number":"INV-2026-0001","subtotal":99,"tax":5.94,"total":104.94,"line_items":[{"description":"云存储 100GB 月费","quantity":2,"unit_price":49.5,"amount":99}]};校验 status=valid;报告关键行 total=1,valid=1,invalid=0,error=0。

做完检查这些

  • 容器内 n8n 只能访问 /invoices,访问其它路径应被拒绝
  • 可读合成 PDF 在 output 生成同名 Excel,且源文件从 input 消失并进入 valid
  • 行项目金额与小计不一致时必须进入 invalid,且必填缺失进 invalid 或 error
  • 执行报告被覆盖且包含 start/end、total/valid/invalid/error 与耗时
  • OpenAI 节点使用 n8n credential,测试数据和日志不含真实密钥或个人信息

容易卡住的地方

  • 扫描件或图片型 PDF 无可提取文本,会走 unreadable/error 而非抽取成功
  • Hosted/云 n8n 通常不能随意读本地文件,需自托管 Community 并开放 fs/path
  • 挂载路径、权限或 N8N_RESTRICT_FILE_ACCESS_TO 错配会导致读写失败
  • 金额浮点需用约 0.01 容差,不能用字符串比较判断小计一致
  • OpenAI 调用与 Comfy/其它服务可能另计费,模板免费不等于模型免费
  • 不要把含真实税号、银行、地址的发票放入测试目录

原文与作者资料 ↗

本站借助AI整理来源事实,独立编写中文操作指南与示例。示例不代表实际运行结果;来源效果尚未由本站独立复现。付费模板与模型、服务费用分别计算。

原文标题
Extract and validate invoice PDFs into Excel with OpenAI GPT-4o-mini
原作者
Tirumalesh Bodavula
原始发布日期
2026-09-22T07:05:08.595Z
来源
https://n8n.io/workflows/19810