如何用Python/JavaScript提取PDF表格、键值对文本并存为指定格式Excel
PDF结构化提取问题解决方案
问题描述
- 需求:从同时包含表格、键值对两类数据的PDF中提取内容,按结构化格式存入Excel
- 原有PyPDF2实现仅能将整页提取的文本全部写入Excel单个单元格,无法实现分字段、分表格行列的结构化存储
- 原有代码如下:
import PyPDF2 import openpyxl from openpyxl import Workbook pdfFileObj = open('sample.pdf', 'rb') pdfReader = PyPDF2.PdfFileReader(pdfFileObj) pdfReader.numPages pageObj = pdfReader.getPage(0) mytext = pageObj.extractText() wb = Workbook() sheet = wb.active sheet.title = 'MyPDF' sheet['A1'] = mytext wb.save('sample.xlsx') print('Save')
问题根因
PyPDF2自带的extractText()方法仅按PDF内部文本流的顺序拼接字符,不会识别版面布局、表格行列结构、键值对的位置对应关系,输出的是无结构的整段文本,无法直接按单元格拆分写入Excel。
实现方法
用pdfplumber替换PyPDF2做内容提取,该库支持获取每个文本块的坐标信息、自动识别表格的行列结构,可以分别处理键值对和表格内容,再按规则写入Excel对应位置。
- 安装所需依赖:
pip install pdfplumber openpyxl
- 参考实现代码:
import pdfplumber from openpyxl import Workbook # 初始化Excel工作簿 wb = Workbook() sheet = wb.active sheet.title = 'PDF提取结果' with pdfplumber.open("sample.pdf") as pdf: # 单页处理示例,多页PDF可循环遍历pdf.pages page = pdf.pages[0] # 提取全页文本按行拆分 full_text = page.extract_text() text_lines = [line.strip() for line in full_text.split('\n') if line.strip()] # 自动提取页面内所有表格,返回按行列拆分的二维数组 page_tables = page.extract_tables() write_row = 1 # 先写入键值对类内容 for line in text_lines: # 过滤掉属于表格内容的行,避免重复写入 is_table_line = False for table in page_tables: for row in table: row_content = ''.join([cell.strip() for cell in row if cell]) if line in row_content: is_table_line = True break if is_table_line: break if is_table_line: continue # 按中英文冒号拆分键和值,写入相邻两列 if ':' in line: key, val = line.split(':', 1) sheet.cell(row=write_row, column=1, value=key.strip()) sheet.cell(row=write_row, column=2, value=val.strip()) write_row += 1 elif ':' in line: key, val = line.split(':', 1) sheet.cell(row=write_row, column=1, value=key.strip()) sheet.cell(row=write_row, column=2, value=val.strip()) write_row += 1 # 空一行后写入表格内容 write_row += 1 for table in page_tables: for row in table: for col_idx, cell_content in enumerate(row, start=1): if cell_content: sheet.cell(row=write_row, column=col_idx, value=cell_content.strip()) write_row += 1 # 多个表格之间空一行分隔 write_row += 1 wb.save('结构化提取结果.xlsx')
如果PDF版式固定,可以通过指定坐标范围单独提取键值对区域、表格区域,进一步提升提取准确率,避免内容错漏。
内容的提问来源于stack exchange,提问作者kkk
相关产品推荐
相关产品推荐

