Python自動化辦公之PDF拆分

今天我們繼續(xù)分享真實的自動化辦公案例,希望各位 Python 愛好者能夠從中得到些許啟發(fā),在自己的工作生活中更多的應用 Python,使得工作事半功倍! ### 需求 需要從 PDF 中取出幾頁并將其保存為新的 PDF,為了后期使用方便,這個工具需要做成傻瓜式的帶有 GUI 頁面的形式 ![](https://upload-images.jianshu.io/upload_images/5803165-8d9a6dd8f9d1abc0.png) 選擇源 pdf 文件,再指定下生成的新的 pdf 文件名稱及保存位置,和需要拆分的 page 信息,就可以得到新的 pdf 文件了 ### 需求解析 對于 Python GUI,我們有太多種選擇了,下面我們先來橫向的簡單對比下 從高層次上看,大的 GUI 工具有: - Qt - WxWindows - Tkinter - Customer libraries(Kivy,Toga等) - Web相關(HTML,F(xiàn)lask等) 不過今天,我們選擇的工具是 appJar,這是一個由一位從事教育工作的大神發(fā)明的,所以它可以提供一個更加簡單的 GUI 創(chuàng)建過程,而且是完全基于 Tkinter 的,Python 默認支持 ### 代碼實現(xiàn) 首先為了實現(xiàn) PDF 操作,我這里選擇了 pypdf2 庫 我們先硬編碼一個輸入輸出的示例 ```Python from PyPDF2 import PdfFileWriter, PdfFileReader infile = "Input.pdf" outfile = "Output.pdf" page_range = "1-2,6" ``` 接下來我們實例化 PdfFileWriter 和 PdfFIleReader 對象,并創(chuàng)建實際的 Output.pdf 文件 ```Python output = PdfFileWriter() input_pdf = PdfFileReader(open(infile, "rb")) output_file = open(outfile, "wb") ``` 下面一個比較復雜的點就是需要拆分 pdf,提取頁面并保存在列表中 ```Python page_ranges = (x.split("-") for x in page_range.split(",")) range_list = [i for r in page_ranges for i in range(int(r[0]), int(r[-1]) + 1)] ``` 最后就是從原始文件中拷貝內容到新的文件 ```Python for p in range_list: output.addPage(input_pdf.getPage(p - 1)) output.write(output_file) ``` 下面來構建 GUI 界面 對于這個拆分 PDF 的小工具,需要具有如下功能: - 可以通過標準文件瀏覽器選擇 pdf 文件 - 可以選擇輸出文件的位置及文件名稱 - 可以自定義提取哪些頁面 - 有一些錯誤檢查 通過 PIP 安裝好 appJar 后,我們就可以編碼了 ```Python from appJar import gui from PyPDF2 import PdfFileWriter, PdfFileReader from pathlib import Path ``` 創(chuàng)建 GUI 窗口 ```Python app = gui("PDF Splitter", useTtk=True) app.setTtkTheme("default") app.setSize(500, 200) ``` 這里我使用了默認主題,當然也可以切換各種各樣的主題模式 ![](https://upload-images.jianshu.io/upload_images/5803165-30f842a911232783.png) 下面是添加標簽和數據輸入組件 ```Python app.addLabel("Choose Source PDF File") app.addFileEntry("Input_File") app.addLabel("Select Output Directory") app.addDirectoryEntry("Output_Directory") app.addLabel("Output file name") app.addEntry("Output_name") app.addLabel("Page Ranges: 1,3,4-10") app.addEntry("Page_Ranges") ``` 接下來添加按鈕,“處理”和“退出”,按下按鈕,調用如下函數 ```Python app.addButtons(["Process", "Quit"], press) ``` 最后就是運行這個 app 啦 ```Python # start the GUI app.go() ``` 這要我們就完成了 GUI 的搭建,下面編寫內部處理邏輯。程序讀取任何輸入,判斷是否為 PDF,并拆分 ```Python def press(button): if button == "Process": src_file = app.getEntry("Input_File") dest_dir = app.getEntry("Output_Directory") page_range = app.getEntry("Page_Ranges") out_file = app.getEntry("Output_name") errors, error_msg = validate_inputs(src_file, dest_dir, page_range, out_file) if errors: app.errorBox("Error", "\n".join(error_msg), parent=None) else: split_pages(src_file, page_range, Path(dest_dir, out_file)) else: app.stop() ``` 如果單擊 “處理(Process)”按鈕,則調用 app.getEntry() 檢索輸入值,每個值都會被存儲,然后通過調用 validate_inputs() 進行驗證 來看看 validate_inputs 函數 ```Python def validate_inputs(input_file, output_dir, range, file_name): errors = False error_msgs = [] # Make sure a PDF is selected if Path(input_file).suffix.upper() != ".PDF": errors = True error_msgs.append("Please select a PDF input file") # Make sure a range is selected if len(range) < 1: errors = True error_msgs.append("Please enter a valid page range") # Check for a valid directory if not(Path(output_dir)).exists(): errors = True error_msgs.append("Please Select a valid output directory") # Check for a file name if len(file_name) < 1: errors = True error_msgs.append("Please enter a file name") return(errors, error_msgs) ``` 這個函數就是執(zhí)行一些檢查來確保輸入有數據并且有效 在收集驗證了所以數據后,就可以調用 split 函數來處理文件了 ```Python def split_pages(input_file, page_range, out_file): output = PdfFileWriter() input_pdf = PdfFileReader(open(input_file, "rb")) output_file = open(out_file, "wb") page_ranges = (x.split("-") for x in page_range.split(",")) range_list = [i for r in page_ranges for i in range(int(r[0]), int(r[-1]) + 1)] for p in range_list: # Need to subtract 1 because pages are 0 indexed try: output.addPage(input_pdf.getPage(p - 1)) except IndexError: # Alert the user and stop adding pages app.infoBox("Info", "Range exceeded number of pages in input.\nFile will still be saved.") break output.write(output_file) if(app.questionBox("File Save", "Output PDF saved. Do you want to quit?")): app.stop() ``` 好了,這樣我們就完成了一個簡易的 GUI 拆分 PDF 文件的工具嘍 喜歡就在看、點贊,轉發(fā),三連支持一下噻! 本文由[mdnice](https://mdnice.com/?platform=6)多平臺發(fā)布
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容