有很多的库都可以用于处理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 编辑过