Python 批量自动提取、整理 PDF 发票

Python 批量自动提取、整理 PDF 发票

随着数字化的普及,越来越多的发票以 PDF 格式进行存储,这给企业的账务管理和数据统计带来了方便,但也带来了一定的问题:如何快速、准确地从大量的 PDF 发票中提取所需的数据?本文将介绍使用 Python 对 PDF 发票进行批量自动提取和整理的方法。

1. 环境准备

为了方便操作 PDF 文件,我们需要安装 Python 的 PDF 处理库 PyPDF2 和数据处理库 Pandas。可以通过以下命令进行安装:

pip install PyPDF2 pandas

2. 提取 PDF 发票数据

使用 PyPDF2 库可以非常方便地从 PDF 文件中提取文本数据。我们可以将 PDF 中需要提取的数据抽象为一张表格,每行代表一张发票,每列代表发票的一种信息,例如:发票号码、开票日期、销售方名称、购买方名称、商品名称、商品数量、商品单价等。

我们可以定义一个函数,将 PDF 文件的每一页转成文本,并通过正则表达式进行匹配,提取所需的数据。具体代码如下:

import re

from io import BytesIO

from typing import List

import pandas as pd

from PyPDF2 import PdfFileReader

def extract_invoice_data(pdf_bytes: bytes, start_page: int,

end_page: int) -> pd.DataFrame:

pages = []

with BytesIO(pdf_bytes) as f:

pdf = PdfFileReader(f)

for i in range(start_page - 1, end_page):

page = pdf.getPage(i)

text = page.extractText()

pages.append(text)

data = []

for page in pages:

regex = r'发票号码[::]\s*(\S+).*?'

regex += r'开票日期[::]\s*(\S+).*?'

regex += r'销售方名称[::]\s*((.*\n)+)?.*?'

regex += r'购买方名称[::]\s*((.*\n)+)?.*?'

regex += r'商品名称[::]\s*((.*\n)+)?.*?'

regex += r'商品数量[::]\s*(\S+).*?'

regex += r'商品单价[::]\s*(\S+)'

matches = re.findall(regex, page, re.S)

for match in matches:

invoice_no, invoice_date, seller, buyer, item_name, item_qty, item_price = match

data.append({

'发票号码': invoice_no.strip().replace('\n', ''),

'开票日期': invoice_date.strip(),

'销售方名称': seller.strip().replace('\n', '') if seller else '',

'购买方名称': buyer.strip().replace('\n', '') if buyer else '',

'商品名称': item_name.strip().replace('\n', '') if item_name else '',

'商品数量': item_qty.strip(),

'商品单价': item_price.strip()})

df = pd.DataFrame(data)

return df

以上代码使用正则表达式对 PDF 中的文本进行匹配,提取发票号码、开票日期、销售方名称、购买方名称、商品名称、商品数量、商品单价等信息,并将其保存到 DataFrame 中。这里需要注意的是,PDF 文件中的文本可能是以多行呈现的,因此我们需要对多行文本进行处理。为了方便数据的后续处理和存储,我们将发票信息保存到 DataFrame 中。

3. 批量处理 PDF 发票

对于大规模的 PDF 发票数据,我们需要批量处理。为了方便起见,我们可以将每个 PDF 文件看成一个批次,将多个 PDF 文件作为多个批次进行处理。

具体而言,我们可以将每个 PDF 文件读入内存,调用 extract_invoice_data 函数提取发票信息,并将结果保存到磁盘文件中。以下是实现代码:

import os

def batch_process_pdfs(pdf_dir: str, start_page: int, end_page: int,

out_dir: str) -> None:

if not os.path.exists(out_dir):

os.makedirs(out_dir)

for pdf_file in os.listdir(pdf_dir):

file_path = os.path.join(pdf_dir, pdf_file)

if os.path.isfile(file_path) and file_path.endswith('.pdf'):

with open(file_path, 'rb') as f:

pdf_bytes = f.read()

df = extract_invoice_data(pdf_bytes, start_page, end_page)

out_file_name = pdf_file.replace('.pdf', '.csv')

out_file_path = os.path.join(out_dir, out_file_name)

df.to_csv(out_file_path, index=None)

以上代码将 PDF 文件的后缀名替换成 CSV,将每个文件的发票信息保存到同名的 CSV 文件中。

4. 数据整理和清洗

对于提取出来的数据,很可能存在一些缺失值和噪声,这些需要进行清洗和整理。我们可以通过 Pandas 库的一些函数对数据进行操作,例如:fillna 函数填充缺失值,drop_duplicates 函数去掉重复的记录,dropna 函数去掉缺失值等。以下是一个简单的数据清洗和整理代码示例:

import pandas as pd

def clean_dataframe(df: pd.DataFrame) -> pd.DataFrame:

# 去掉空白行

df = df.dropna(how='all')

# 去掉重复行

df = df.drop_duplicates(subset=['发票号码'], keep='last')

# 填充缺失值

df = df.fillna('')

# 按照发票号码排序

df = df.sort_values(by='发票号码')

return df

以上代码对 DataFrame 进行了去重、填充和排序等操作,并将处理后的 DataFrame 返回。

5. 结语

以上就是使用 Python 对 PDF 发票进行批量自动提取和整理的方法。这种方法可以为企业的数据统计和管理带来很大的方便,但也需要注意 PDF 文件本身的格式,确保文本内容可以被正确抽取。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。

后端开发标签