Python使用PyMuPDF實現(xiàn)PDF文件的智能注釋
引言
在數(shù)字化辦公的浪潮中,處理和分析大量文檔成為了我們?nèi)粘9ぷ鞯囊徊糠?。尤其是面對PDF文件,手動檢索和標注信息不僅耗時耗力,還難免疏漏。為了提升效率并減少人為失誤,我精心打造了這款Python腳本,它能夠智能化地在PDF文檔中定位并標注Excel表格所指定的關(guān)鍵文本。本文將深入探討這一腳本的內(nèi)在邏輯,并指導(dǎo)你如何輕松駕馭這一自動化工具。
程序的核心功能在于,它能夠識別Excel文件中B列的特定文本,一旦這些文本在PDF文檔中被找到,腳本便會自動在這些文本周圍繪制矩形框,并在相鄰位置以注釋的形式展示同一行A列的內(nèi)容。這一過程不僅提高了PDF文檔處理的速度,同時也確保了信息標注的準確性和一致性。接下來,我將逐步展開,詳細解釋這一自動化流程的每個關(guān)鍵步驟。
值得注意的是,隨著PyMuPDF庫的不斷更新迭代,PyMuPDF庫的語法已經(jīng)產(chǎn)生不小的變化和以及新功能的加入,使得現(xiàn)有網(wǎng)絡(luò)上的許多教程和文檔的語法已經(jīng)在某些情況下不再適用于最新版本使用需求?;谶@一現(xiàn)狀,筆者投入了不少時間和精力進行研究和實踐,以確保本腳本使用的是最新的、正確的語法和方法。
在這篇文章中,你將看到:
- 最新版本的PyMuPDF的正確使用方式。
- 如何利用PyMuPDF的強大功能來實現(xiàn)復(fù)雜的PDF處理任務(wù)。
- 實用技巧和最佳實踐,幫助你避免常見的陷阱和錯誤。
我希望通過分享這些經(jīng)過驗證的知識和經(jīng)驗,能夠幫助你在自動化PDF和Excel文件處理的道路上少走彎路,直接掌握最前沿的技術(shù)。無論你是編程新手還是資深開發(fā)者,這篇文章都將為你提供寶貴的信息和指導(dǎo)。讓我們一起探索自動化魔法的奧秘,釋放你的工作效率吧!
環(huán)境準備
在開始之前,請確保你的Python環(huán)境中安裝了以下庫:
- PyMuPDF:用于讀取、修改PDF文件。
- openpyxl:用于讀取Excel文件。
- Tkinter:用于創(chuàng)建圖形用戶界面(GUI)。
要安裝這三個庫,你可以使用Python的包管理器pip。以下是安裝命令:
對于PyMuPDF:
pip install PyMuPDF
對于openpyxl:
pip install openpyxl
對于Tkinter(通常Python的安裝已經(jīng)包含了Tkinter,但如果沒有,你可以使用以下命令安裝):
pip install tk
請注意,如果你使用的是Python 3.x版本,通常pip命令已經(jīng)內(nèi)置在Python中,你可以直接使用它來安裝這些庫。如果你使用的是Python 2.x版本,可能需要使用pip2或pip3來指定正確的Python版本。
腳本功能概述
本腳本具有以下核心功能:
- 通過GUI讓用戶選擇PDF和Excel文件。
- 讀取Excel文件中B列數(shù)據(jù)以獲取指定的文本,并在PDF中搜索這些文本。
- 在PDF中找到的文本位置添加矩形框和文本注釋。
- 保存修改后的PDF文件,并提供選項讓用戶選擇保存路徑。
- 腳本運行結(jié)束后,提示用戶按特定鍵退出程序。
腳本詳解
1. 圖形用戶界面(GUI)
使用Tkinter庫創(chuàng)建一個簡潔的GUI,讓用戶能夠方便地選擇需要處理的文件。
# 創(chuàng)建Tk窗口對象并立即銷毀,用于文件對話框 root = Tk() root.withdraw() # 使用tkinter.filedialog獲取PDF文件路徑 input_file_pdf = filedialog.askopenfilename( title="請選擇PDF文件", # 對話框標題 filetypes=(("PDF files", "*.pdf"), ("All files", "*.*")) # 文件類型過濾 ) # 如果用戶取消了文件選擇,就退出程序 if not input_file_pdf: print("未選擇文件,程序?qū)⑼顺觥?) exit()
2. 打開和讀取文件
使用PyMuPDF打開用戶選擇的PDF文件,使用openpyxl讀取Excel文件,并獲取活動工作表。
# 打開PDF文件 print("正在打開PDF文件,請稍候...") doc = fitz.open(input_file_pdf) # 使用PyMuPDF打開PDF文件 print("已打開PDF文件,請稍候...") # 使用tkinter.filedialog獲取Excel文件路徑 input_file_excel = filedialog.askopenfilename( title="請選擇Excel文件", # 對話框標題 filetypes=(("Excel files", "*.xlsx"), ("All files", "*.*")) # 文件類型過濾 ) # 如果用戶取消了文件選擇,就退出程序 if not input_file_excel: print("未選擇文件,程序?qū)⑼顺觥?) exit()
3. 搜索和注釋
遍歷Excel工作表的每一行,使用PyMuPDF的搜索功能在PDF中查找指定文本,并在找到的位置添加矩形框和文本注釋。
# 遍歷Excel的每一行,從第二行開始讀取 for row in ws.iter_rows(min_row=1, values_only=True): text = str(row[0]) # 獲取A列的值 text_to_search = row[1] # 獲取B列的值 print(f"正在處理Excel中的文本:'{text}' 和 '{text_to_search}'") # 用于跟蹤是否在當前循環(huán)中找到文本的變量 page_text_found = False # 遍歷PDF的每一頁 for page_number in range(len(doc)): page = doc[page_number] # 訪問當前頁 areas = page.search_for(text_to_search) # 在當前頁搜索文本 # 如果在頁面上找到文本,添加擴大的矩形框和文本注釋 if areas: page_text_found = True for area in areas: x0, y0, x1, y1 = area print(f"在第 {page_number + 1} 頁找到文本 '{text_to_search}'") # 擴大矩形框 new_x0 = 27.7 # 根據(jù)需要調(diào)整 new_y0 = y0 - down_size new_x1 = 524.6 # 根據(jù)需要調(diào)整 new_y1 = y1 + up_size # 創(chuàng)建擴大后的矩形區(qū)域 rect = fitz.Rect(new_x0, new_y0, new_x1, new_y1) # 添加矩形注釋 annot = page.add_rect_annot(rect) annot.set_border(width=2) annot.update(opacity=1) # 添加文本注釋 new_rect = fitz.Rect(5, new_y0 + 3, 10 + 50, new_y0 + 15) annot = page.add_freetext_annot(new_rect, text, fontsize=12, text_color=(1, 0, 0)) # 由于找到文本后已添加注釋,可以跳出內(nèi)層循環(huán) break # 如果在當前Excel行的搜索中沒有找到文本,則告知用戶 if not page_text_found: print(f"在整個PDF中沒有找到文本 '{text_to_search}'。")
4. 保存和退出
用戶選擇保存路徑后,腳本將保存修改后的PDF文件,并在所有操作完成后提示用戶按特定鍵退出程序。
# 使用tkinter.filedialog獲取保存PDF的文件路徑 output_file_pdf = filedialog.asksaveasfilename( title="請輸入要保存的PDF文件路徑", filetypes=(("PDF files", "*.pdf"), ("All files", "*.*")), defaultextension=".pdf" # 設(shè)置默認擴展名為PDF ) # 如果用戶取消了保存文件選擇,就退出程序 if not output_file_pdf: print("未選擇保存路徑,程序?qū)⑼顺觥?) exit() print("正在保存修改后的PDF文件,請稍候...") doc.save(output_file_pdf) # 保存修改后的PDF文件 print("修改后的PDF文件已保存。") # 關(guān)閉文檔 doc.close() # 關(guān)閉PyMuPDF文檔 print("搜索完成,PDF文件已關(guān)閉。")
代碼示例文件與截圖
Excel文件原內(nèi)容
PDF文件原內(nèi)容
程序運行后PDF文件內(nèi)容
代碼運行截圖
完整代碼
# 導(dǎo)入PyMuPDF庫,用于處理PDF文件 import fitz # 導(dǎo)入openpyxl庫中的load_workbook函數(shù),用于處理Excel文件 from openpyxl import load_workbook # 導(dǎo)入Tk和filedialog,用于創(chuàng)建圖形用戶界面對話框 from tkinter import Tk, filedialog # 創(chuàng)建Tk窗口對象并立即銷毀,用于文件對話框 root = Tk() root.withdraw() # 使用tkinter.filedialog獲取PDF文件路徑 input_file_pdf = filedialog.askopenfilename( title="請選擇PDF文件", # 對話框標題 filetypes=(("PDF files", "*.pdf"), ("All files", "*.*")) # 文件類型過濾 ) # 如果用戶取消了文件選擇,就退出程序 if not input_file_pdf: print("未選擇文件,程序?qū)⑼顺觥?) exit() # 打開PDF文件 print("正在打開PDF文件,請稍候...") doc = fitz.open(input_file_pdf) # 使用PyMuPDF打開PDF文件 print("已打開PDF文件,請稍候...") # 使用tkinter.filedialog獲取Excel文件路徑 input_file_excel = filedialog.askopenfilename( title="請選擇Excel文件", # 對話框標題 filetypes=(("Excel files", "*.xlsx"), ("All files", "*.*")) # 文件類型過濾 ) # 如果用戶取消了文件選擇,就退出程序 if not input_file_excel: print("未選擇文件,程序?qū)⑼顺觥?) exit() # 打開Excel文件 print("正在打開Excel文件,請稍候...") wb = load_workbook(filename=input_file_excel) # 加載Excel文件 ws = wb.active # 獲取活動工作表 # 矩形擴大的尺寸 up_size = 5 # 上邊擴大的尺寸 down_size = 3 # 下邊擴大的尺寸 left_size = 77.5 # 左邊擴大的尺寸 right_size = 389.5 # 右邊擴大的尺寸 # 遍歷Excel的每一行,從第二行開始讀取 for row in ws.iter_rows(min_row=1, values_only=True): text = str(row[0]) # 獲取A列的值 text_to_search = row[1] # 獲取B列的值 print(f"正在處理Excel中的文本:'{text}' 和 '{text_to_search}'") # 用于跟蹤是否在當前循環(huán)中找到文本的變量 page_text_found = False # 遍歷PDF的每一頁 for page_number in range(len(doc)): page = doc[page_number] # 訪問當前頁 areas = page.search_for(text_to_search) # 在當前頁搜索文本 # 如果在頁面上找到文本,添加擴大的矩形框和文本注釋 if areas: page_text_found = True for area in areas: x0, y0, x1, y1 = area print(f"在第 {page_number + 1} 頁找到文本 '{text_to_search}'") # 擴大矩形框 new_x0 = 27.7 # 根據(jù)需要調(diào)整 new_y0 = y0 - down_size new_x1 = 524.6 # 根據(jù)需要調(diào)整 new_y1 = y1 + up_size # 創(chuàng)建擴大后的矩形區(qū)域 rect = fitz.Rect(new_x0, new_y0, new_x1, new_y1) # 添加矩形注釋 annot = page.add_rect_annot(rect) annot.set_border(width=2) annot.update(opacity=1) # 添加文本注釋 new_rect = fitz.Rect(5, new_y0 + 3, 10 + 50, new_y0 + 15) annot = page.add_freetext_annot(new_rect, text, fontsize=12, text_color=(1, 0, 0)) # 由于找到文本后已添加注釋,可以跳出內(nèi)層循環(huán) break # 如果在當前Excel行的搜索中沒有找到文本,則告知用戶 if not page_text_found: print(f"在整個PDF中沒有找到文本 '{text_to_search}'。") # 使用tkinter.filedialog獲取保存PDF的文件路徑 output_file_pdf = filedialog.asksaveasfilename( title="請輸入要保存的PDF文件路徑", filetypes=(("PDF files", "*.pdf"), ("All files", "*.*")), defaultextension=".pdf" # 設(shè)置默認擴展名為PDF ) # 如果用戶取消了保存文件選擇,就退出程序 if not output_file_pdf: print("未選擇保存路徑,程序?qū)⑼顺觥?) exit() print("正在保存修改后的PDF文件,請稍候...") doc.save(output_file_pdf) # 保存修改后的PDF文件 print("修改后的PDF文件已保存。") # 關(guān)閉文檔 doc.close() # 關(guān)閉PyMuPDF文檔 print("搜索完成,PDF文件已關(guān)閉。") # 提示用戶按下q鍵退出程序,并檢查輸入 print("程序運行結(jié)束,按 'q' 鍵退出程序(不區(qū)分大小寫)。") while True: # 創(chuàng)建一個無限循環(huán) key = input().strip().lower() # 獲取用戶輸入并轉(zhuǎn)換為小寫 if key == 'q': # 檢查輸入是否是 'q' break # 如果是 'q',退出循環(huán) else: print("請輸入 'q' 以退出程序。")
結(jié)語
這個Python腳本提供了一種高效、自動化的方式來處理PDF和Excel文件,尤其適用于需要在大量文檔中搜索和標記特定信息的場景。通過使用這個腳本,你可以節(jié)省寶貴的時間,減少人為錯誤,提高工作效率。
到此這篇關(guān)于Python使用PyMuPDF實現(xiàn)PDF文件的智能注釋的文章就介紹到這了,更多相關(guān)Python PDF智能注釋內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python獲取當前頁面內(nèi)所有鏈接的四種方法對比分析
這篇文章主要介紹了Python獲取當前頁面內(nèi)所有鏈接的方法,結(jié)合實例形式對比分析了Python常用的四種獲取頁面鏈接的方法,并附帶了iframe框架內(nèi)鏈接的獲取方法,需要的朋友可以參考下2017-08-08解析numpy中的iscomplex方法及實際應(yīng)用
NumPy 的 iscomplex 方法為檢查數(shù)組中的元素是否為復(fù)數(shù)提供了一種高效且易于使用的接口,本文介紹了 iscomplex 方法的基本概念、使用方法以及它在解決實際問題中的應(yīng)用,需要的朋友可以參考下2024-06-06Windows下創(chuàng)建定時任務(wù)執(zhí)行Python腳本的方法實現(xiàn)
Python定時任務(wù)執(zhí)行,本文主要介紹了Windows下創(chuàng)建定時任務(wù)執(zhí)行Python腳本的方法實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-11-11Python實戰(zhàn)使用Selenium爬取網(wǎng)頁數(shù)據(jù)
這篇文章主要為大家介紹了Python實戰(zhàn)使用Selenium爬取網(wǎng)頁數(shù)據(jù)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2023-05-05