Python提取PDF发票内容保存到Excel
---
摘要:这篇文章介绍如何把发票内容提取出来保存到Excel中。文章分为两个部分,第一部分程序用法,第二部分介绍代码。
---
作者:yooongchun
CSDN博客:https://blog.csdn.net/zyc121561
微信公众号:yooongchun小屋
---
![](images/yooongchun小屋.jpg)
---
- 程序功能及使用:
程序会把发票中的内容提取出来然后写入Excel中,一个示例的发票内容如下:
![](images/demo.png)
而多份PDF的提取结果示意如下:
![](images/Capture.png)
这里提取的关键词可自定义,只需要把需要的关键字写在Excel中即可。
程序的运行使用很简单,只要在可视化界面中输入相应的文件路径然后运行即可,程序界面示意如下:
![](images/gui.png)
- 程序开发思路:开发主要涉及三个点:其一就是PDF解析,其二是提取规则,其三就是Excel保存。
- PDF解析:PDF解析使用pdfminer3K模块,Python3环境下使用如下方式安装:
```python
pip3 install PdfMiner3K
```
接下来使用该模块进行PDF解析,主要函数如下:
```python
# 解析文件
def parse_pdf(path, output_path):
with open(path, 'rb') as fp:
parser = PDFParser(fp)
doc = PDFDocument()
parser.set_document(doc)
doc.set_parser(parser)
doc.initialize('')
rsrcmgr = PDFResourceManager()
laparams = LAParams()
laparams.char_margin = 1.0
laparams.word_margin = 1.0
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
interpreter = PDFPageInterpreter(rsrcmgr, device)
extracted_text = ''
for page in doc.get_pages():
interpreter.process_page(page)
layout = device.get_result()
for lt_obj in layout:
if isinstance(lt_obj, LTTextBox) or isinstance(lt_obj, LTTextLine):
extracted_text += lt_obj.get_text()
with open(output_path, "w", encoding="utf-8") as f:
f.write(extracted_text)
```
解析后PDF文字内容会被转换为TXT,当然,PDF必须遵守标准的Adobe规范才行,另外,不同的参数设置会导致不同的解析结果(主要是文字的相对位置),因而实际使用中必须对此参数进行调整。
- 提取规则:提取规则根据文字的相对位置和文字规律来确定,比如关键词后面接着内容,比如银行账号一定是数字,比如开户行关键字的内容一定会有银行,支行等词汇,这里提取规则稍微复杂一些,根据实际情况进行设定,我设定的规则如下:
```python
# 格式化发票内容
# 内容分区
def split_block(text):
text_line = text.split("\n")
# 第一步:分区:[公共头,购买方,销售方,公共域]
header = []
buyer = []
saler = []
body = []
index = 0
while index < len(text_line):
if not text_line[index] == "购":
header.append(re.sub(r"\s+", "", text_line[index]))
index += 1
continue
else:
break
while index < len(text_line):
if not text_line[index] == "项目名称":
if text_line[index] == "购" or text_line[index] == "买" or text_line[index] == "方":
index += 1
continue
if re.sub(r"\s+", "", text_line[index]) == "地址、" and re.sub(
r"\s+", "", text_line[index + 1]) == "电话:":
buyer.append(
re.sub(r"\s+", "",
text_line[index] + text_line[index + 1]))
index +=