有很多的库都可以用于处理PDF文档,例如PyMuPDF、PyPDF2、pdfplumber、pikepdf等等,它们各自有着特定的优势和用途,为了实现对文本、图片和表格的简单提取功能,这里我选用的是pdfplumber,大家可以访问下面链接来对这个库有个大致了解:
https://pypi.org/project/pdfplumber/
在开始写代码前,我们需要用以下命令对这个库进行安装:
pip install pdfplumber
def extract_tables(file_path):
try:
with pdfplumber.open(file_path) as pdf:
for page in pdf.pages:
tables = page.extract_tables()
if tables isnotNoneand len(tables)>0:
for table in tables:
if table isnotNoneand len(table)>0:
for row in table:
# print(row)
print(' '.join(map(str,row)))
except FileNotFoundError:
print(f"Error: The file '{file_path}' does not exist.")
except Exception as e:
print(f"Error: An error occurred while processing the file: {e}")
with pdfplumber.open(file_path) as pdf:
with语句用于管理资源,在这里是打开的PDF文件。它确保无论代码执行成功还是失败,PDF文件都会被正确关闭。pdfplumber.open(file_path)打开指定路径的PDF文件,并将其赋值给变量pdf。
for page in pdf.pages:
这个for循环用于遍历PDF文档中的每一页。pdf.pages是一个包含PDF所有页面对象的列表,循环会依次将每个页面对象赋值给变量page。
tables = page.extract_tables()
这里的extract_tables()可不是我们自定义的方法名,它是pdfplumber的extract_tables()方法,它会自动识别并提取当前页面page中的所有表格。提取的结果是一个列表,其中的每个元素代表一个表格。这个列表被赋值给变量tables。
if tables is not None and len(tables)>0:
这个条件判断检查tables是否为None(表示没有提取到表格),并且检查tables列表的长度是否大于0。如果这两个条件都成立,即成功提取到至少一个表格,才会执行下面的代码块。
for table in tables:
这个for循环用于遍历上一步提取到的tables列表中的每一个表格。每次循环中,table代表当前正在处理的表格。
if table is not None and len(table)>0:
这个条件判断再次确保当前table对象不为空,并且包含至少一行数据。
for row in table:
table本身是一个列表,这个最内层的for循环遍历表格中的每一行,并将每一行数据赋值给row变量。
print(' '.join(map(str,row)))
这里我用join()和map()方法将表格中的数据。
map(str, row):将 row列表中的每个元素都转换成字符串类型。
' '.join(…):这是一个字符串方法,它使用一个空格作为分隔符,将 map()返回的所有字符串连接成一个完整的字符串,也就是说,这里我将每一行的数据,用空格连接成了一个字符串,然后进行了打印。
def extract_tables2csv(file_path):
try:
with pdfplumber.open(file_path) as pdf:
for i,page in enumerate(pdf.pages):
tables = page.extract_tables()
if tables isnotNoneand len(tables)>0:
for j,table in enumerate(tables):
if table isnotNoneand len(table)>0:
csv_filename = f'table_{i+1}_{j}.csv'
with open(csv_filename, 'w', newline='') as csvfile:
writer = csv.writer(csvfile)
writer.writerows(table)
print(f'Page {i+1}:\n')
for row in table:
print(row)
except FileNotFoundError:
print(f"Error: The file '{file_path}' does not exist.")
except Exception as e:
print(f"Error: An error occurred while processing the file: {e}")
for i,page in enumerate(pdf.pages):
这个 for循环用于遍历PDF文档中的每一页。enumerate()会返回页面的索引i(从0开始) 和页面对象page。
for j,table in enumerate(tables):
这个嵌套的for循环,用于遍历page.extract_tables()得到的tables列表中的每一个表格。enumerate()会返回表格的索引 j(从 0 开始) 和表格对象table。
csv_filename = f'table_{i+1}_{j}.csv'
利用前面的到的i和j组合出将保存的CSV文件的文件名。例如,第一个页面上的第一个表格会被命名为 table_1_0.csv。
with open(csv_filename, 'w', newline='') as csvfile:
这个with语句,用于打开一个文件进行写入。open(csv_filename, 'w', newline='')以写入模式'w'打开之前定义的文件名。newline=''参数用于防止在写入CSV文件时产生额外的空行。打开的文件对象被赋值给变量csvfile。
writer = csv.writer(csvfile)
这行代码创建了一个csv.writer对象,它用于将表格数据写入csvfile对象。
writer.writerows(table)
这行代码调用writer对象的writerows()方法。这个方法接受一个列表(在这里是table),并将列表中的每个子列表(也就是每一行)作为 CSV 的一行写入文件。
for row in table:
print(row)
这个for循环遍历当前表格的每一行,并将每一行赋值给row,这个变量的类型也是列表,会以列表形式打印到终端。
该文章在 2025/8/4 18:35:38 编辑过