有很多的庫(kù)都可以用于處理PDF文檔,例如PyMuPDF、PyPDF2、pdfplumber、pikepdf等等,它們各自有著特定的優(yōu)勢(shì)和用途,為了實(shí)現(xiàn)對(duì)文本、圖片和表格的簡(jiǎn)單提取功能,這里我選用的是pdfplumber,大家可以訪問下面鏈接來對(duì)這個(gè)庫(kù)有個(gè)大致了解:
https://pypi.org/project/pdfplumber/
?
在開始寫代碼前,我們需要用以下命令對(duì)這個(gè)庫(kù)進(jìn)行安裝:
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文件。它確保無論代碼執(zhí)行成功還是失敗,PDF文件都會(huì)被正確關(guān)閉。pdfplumber.open(file_path)
打開指定路徑的PDF文件,并將其賦值給變量pdf
。
for page in pdf.pages:
這個(gè)for
循環(huán)用于遍歷PDF文檔中的每一頁。pdf.pages
是一個(gè)包含PDF所有頁面對(duì)象的列表,循環(huán)會(huì)依次將每個(gè)頁面對(duì)象賦值給變量page
。
tables = page.extract_tables()
這里的extract_tables()
可不是我們自定義的方法名,它是pdfplumber
的extract_tables()
方法,它會(huì)自動(dòng)識(shí)別并提取當(dāng)前頁面page
中的所有表格。提取的結(jié)果是一個(gè)列表,其中的每個(gè)元素代表一個(gè)表格。這個(gè)列表被賦值給變量tables
。
if tables is not None and len(tables)>0:
這個(gè)條件判斷檢查tables
是否為None
(表示沒有提取到表格),并且檢查tables
列表的長(zhǎng)度是否大于0。如果這兩個(gè)條件都成立,即成功提取到至少一個(gè)表格,才會(huì)執(zhí)行下面的代碼塊。
for table in tables:
這個(gè)for
循環(huán)用于遍歷上一步提取到的tables
列表中的每一個(gè)表格。每次循環(huán)中,table
代表當(dāng)前正在處理的表格。
if table is not None and len(table)>0:
這個(gè)條件判斷再次確保當(dāng)前table
對(duì)象不為空,并且包含至少一行數(shù)據(jù)。
for row in table:
table
本身是一個(gè)列表,這個(gè)最內(nèi)層的for循環(huán)遍歷表格中的每一行,并將每一行數(shù)據(jù)賦值給row
變量。
print(' '.join(map(str,row)))
這里我用join()
和map()
方法將表格中的數(shù)據(jù)。
map(str, row)
:將 row
列表中的每個(gè)元素都轉(zhuǎn)換成字符串類型。
' '.join(…)
:這是一個(gè)字符串方法,它使用一個(gè)空格作為分隔符,將 map()
返回的所有字符串連接成一個(gè)完整的字符串,也就是說,這里我將每一行的數(shù)據(jù),用空格連接成了一個(gè)字符串,然后進(jìn)行了打印。
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):
這個(gè) for
循環(huán)用于遍歷PDF文檔中的每一頁。enumerate()
會(huì)返回頁面的索引i
(從0開始) 和頁面對(duì)象page
。
for j,table in enumerate(tables):
這個(gè)嵌套的for
循環(huán),用于遍歷page.extract_tables()
得到的tables
列表中的每一個(gè)表格。enumerate()
會(huì)返回表格的索引 j
(從 0 開始) 和表格對(duì)象table
。
csv_filename = f'table_{i+1}_{j}.csv'
利用前面的到的i
和j
組合出將保存的CSV文件的文件名。例如,第一個(gè)頁面上的第一個(gè)表格會(huì)被命名為 table_1_0.csv
。
with open(csv_filename, 'w', newline='') as csvfile:
這個(gè)with
語句,用于打開一個(gè)文件進(jìn)行寫入。open(csv_filename, 'w', newline='')
以寫入模式'w'
打開之前定義的文件名。newline=''
參數(shù)用于防止在寫入CSV文件時(shí)產(chǎn)生額外的空行。打開的文件對(duì)象被賦值給變量csvfile
。
writer = csv.writer(csvfile)
這行代碼創(chuàng)建了一個(gè)csv.writer
對(duì)象,它用于將表格數(shù)據(jù)寫入csvfile
對(duì)象。
writer.writerows(table)
這行代碼調(diào)用writer
對(duì)象的writerows()
方法。這個(gè)方法接受一個(gè)列表(在這里是table
),并將列表中的每個(gè)子列表(也就是每一行)作為 CSV 的一行寫入文件。
for row in table:
print(row)
這個(gè)for
循環(huán)遍歷當(dāng)前表格的每一行,并將每一行賦值給row
,這個(gè)變量的類型也是列表,會(huì)以列表形式打印到終端。
該文章在 2025/8/4 18:35:38 編輯過