影刀RPA实操指南:PDF发票批量解析与信息提取自动化

财务月底收了一堆PDF发票,一张张打开、复制发票号、金额、开票日期,再粘贴到Excel。一百张发票,一下午就没了。用影刀RPA批量解析PDF,自动提取关键字段,写入表格,财务只负责核对。

PDF发票解析的核心是“文本提取”和“字段定位”。 电子发票是文本型PDF,可以直接提取文字;扫描件是图片型PDF,需要先转图片再OCR。

这篇把PDF文本提取、图片型PDF的OCR处理、发票字段正则匹配、批量写入Excel一次讲透,每个操作精确到按钮。

picture.image

PDF文本提取与pdfplumber的配置方法

影刀RPA没有内置PDF解析指令,用“执行Python代码”调pdfplumber库。Python图标要点亮。

操作步骤:

picture.image

  1. 右侧指令面板搜索“安装Python库”,拖入流程,库名填 pdfplumber。
  2. 再拖入“执行Python代码”指令。
  3. 在代码编辑区写解析逻辑。
import pdfplumber

![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/cf328ce40faa40bd9138e844f5a33b67~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1791901533&x-signature=sOmwZYNmpPj9L%2BDTt85XlKUSbC8%3D)

# 打开PDF文件
pdf_path = r'D:\发票\发票_001.pdf'

with pdfplumber.open(pdf_path) as pdf:
    # 遍历每一页
    for page in pdf.pages:
    
![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/76f17edaa49647e788444efd97cee09d~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1791901533&x-signature=cjBgiE%2Fkq6pGbac8OKCEm9RDKUk%3D)
        # 提取文本
        text = page.extract_text()
        print(text)

这里很容易踩坑,注意看:pdfplumber对文本型PDF效果好,对扫描件提取出来是空字符串。判断方法:if not text.strip(): 说明是图片型PDF,需要走OCR。

picture.image 版本差异提醒:影刀RPA社区版每天30分钟运行时长,调试PDF解析够用。创业版无限制,适合批量处理发票。魔法指令(3.0新特性)可对话式生成解析代码,但正则匹配还是手动写更稳。

图片型PDF转图片与OCR识别

扫描件发票需要先转成图片,再用OCR识别。用pdf2image库转换。


![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/d271f67b76fb4f029c1266a248a35d2d~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1791901533&x-signature=%2FJpyRsFVTFTKEVtQ9P7jlGquZuA%3D)
from pdf2image import convert_from_path

# PDF转图片
pdf_path = r'D:\发票\扫描件_001.pdf'
images = convert_from_path(pdf_path, dpi=300)

# 保存图片
for i, img in enumerate(images):
    img.save(rf'D:\发票\图片\page_{i+1}.png', 'PNG')

转成图片后,用影刀RPA的“百度OCR”或“腾讯云OCR”指令识别。操作路径:右侧指令面板搜索“OCR” → 拖入“百度OCR” → 图片路径填 D:\发票\图片\page_1.png → 输出变量 $识别结果$。

推荐一个方法,实测好用:dpi设300,识别率最高。dpi太低文字模糊,dpi太高文件太大处理慢。

发票字段正则提取与结构化

OCR或文本提取拿到的是整段文字,需要从中提取发票号、金额、日期等字段。

import re

# 假设 text 是提取出来的发票全文
text = """
发票代码:011002000311
发票号码:12345678
开票日期:2026年10月02日
金额:¥1,234.56

![picture.image](https://p6-volc-community-sign.byteimg.com/tos-cn-i-tlddhu82om/63c657be3b3144cfa2fc4a1ff885d050~tplv-tlddhu82om-image.image?=&rk3s=8031ce6d&x-expires=1791901533&x-signature=e9IrBjsvYTc%2Fd9g9yZq55OhPPKc%3D)
销售方:某某科技有限公司
"""

# 1. 提取发票代码(10-12位数字)
invoice_code = re.search(r'发票代码[::]\s*(\d{10,12})', text)
invoice_code = invoice_code.group(1) if invoice_code else ''

# 2. 提取发票号码(8位数字)
invoice_no = re.search(r'发票号码[::]\s*(\d{8})', text)
invoice_no = invoice_no.group(1) if invoice_no else ''

# 3. 提取开票日期
date = re.search(r'开票日期[::]\s*(\d{4})年(\d{2})月(\d{2})日', text)
if date:
    invoice_date = f'{date.group(1)}-{date.group(2)}-{date.group(3)}'
else:
    invoice_date = ''

# 4. 提取金额(去掉¥和逗号)
amount = re.search(r'金额[::]\s*¥?([\d,]+\.?\d*)', text)
if amount:
    amount = float(amount.group(1).replace(',', ''))
else:
    amount = 0.0

# 5. 提取销售方
seller = re.search(r'销售方[::]\s*(.+)', text)
seller = seller.group(1).strip() if seller else ''

print(f'发票代码:{invoice_code}')
print(f'发票号码:{invoice_no}')
print(f'开票日期:{invoice_date}')
print(f'金额:{amount}')
print(f'销售方:{seller}')

容易踩的坑:不同发票的字段名可能不同。有的写“发票代码”,有的写“发票代码:”。正则用 [::] 兼容中英文冒号。

批量解析文件夹内所有PDF

一张张处理不现实,用循环遍历文件夹。

import os
import pdfplumber
import re
import pandas as pd

folder = r'D:\发票'
results = []

for filename in os.listdir(folder):
    if not filename.endswith('.pdf'):
        continue

    pdf_path = os.path.join(folder, filename)

    with pdfplumber.open(pdf_path) as pdf:
        text = ''
        for page in pdf.pages:
            page_text = page.extract_text()
            if page_text:
                text += page_text

    # 如果是扫描件,text为空,走OCR
    if not text.strip():
        # 这里调用OCR逻辑,省略
        continue

    # 提取字段
    record = {
        '文件名': filename,
        '发票代码': re.search(r'发票代码[::]\s*(\d{10,12})', text),
        '发票号码': re.search(r'发票号码[::]\s*(\d{8})', text),
        '开票日期': re.search(r'开票日期[::]\s*(\d{4})年(\d{2})月(\d{2})日', text),
        '金额': re.search(r'金额[::]\s*¥?([\d,]+\.?\d*)', text),
        '销售方': re.search(r'销售方[::]\s*(.+)', text),
    }

    # 处理匹配结果
    for key, match in record.items():
        if key == '文件名':
            continue
        if match:
            record[key] = match.group(1) if match.lastindex == 1 else '-'.join(match.groups())
        else:
            record[key] = ''

    results.append(record)

# 写入Excel
df = pd.DataFrame(results)
df.to_excel(r'D:\发票\发票汇总.xlsx', index=False)
print(f'共处理 {len(results)} 张发票')

在影刀RPA中,把 results 赋值给数据表格变量,用“写入Excel内容”指令导出。

推荐一个方法,实测好用:先用10张发票测试正则匹配率。匹配率低于90%,调整正则再跑全量。

发票数据校验与异常处理

解析完必须校验,否则错误数据会流进财务系统。

# 校验逻辑
def validate_invoice(record):
    errors = []
    if not record['发票号码']:
        errors.append('发票号码为空')
    if len(record['发票号码']) != 8:
        errors.append('发票号码长度不对')
    if not record['金额'] or float(record['金额']) <= 0:
        errors.append('金额异常')
    if not record['开票日期']:
        errors.append('日期为空')
    return errors

# 逐条校验
for record in results:
    errors = validate_invoice(record)
    if errors:
        print(f'{record["文件名"]} 校验失败:{errors}')

在影刀RPA的Catch块中加“输出日志”记录解析失败的文件名和错误信息。

这里很容易踩坑,注意看:金额可能是负数(红冲发票)。校验时不要简单判断 > 0,要允许负数。

版本差异提醒:影刀RPA社区版每天30分钟运行时长,批量解析大量PDF时注意时间。创业版无限制,适合财务批量处理。收费模块中有些高级OCR功能需要创业版。

常见问题与易错速查

问题原因解决方法
提取文本为空扫描件PDF转图片后走OCR
发票号匹配不到字段名不同正则兼容多种写法
金额带逗号未清洗replace(',', '')
日期格式不对年月日分隔正则分组拼接
社区版超时30分钟限制分批次或升级创业版

特别提醒:发票数据涉及财务信息,解析结果不要公开传播。处理完的PDF和Excel设置访问权限。

推荐资源

  • 影刀RPA官方文档:搜索“执行Python代码”和“安装Python库”
  • pdfplumber文档:github.com/jsvine/pdfplumber
  • 影刀学院B站账号:有PDF解析实战视频

一个实测好用的习惯:先用一张文本型PDF和一张扫描件PDF分别测试,确认两条路径都能跑通,再批量处理。


#影刀RPA #RPA自动化 #PDF解析 #发票识别 #OCR #财务自动化

作者:林焱

本文为《影刀RPA学习手册》系列文章之一,内容源于实操经验的整理与分享。

0
0
0
0
评论
未登录
暂无评论