Python自動化辦公之編寫PDF拆分工具
今天我們繼續(xù)分享真實的自動化辦公案例,希望各位 Python 愛好者能夠從中得到些許啟發(fā),在自己的工作生活中更多的應(yīng)用 Python,使得工作事半功倍!
需求
需要從 PDF 中取出幾頁并將其保存為新的 PDF,為了后期使用方便,這個工具需要做成傻瓜式的帶有 GUI 頁面的形式
選擇源 pdf 文件,再指定下生成的新的 pdf 文件名稱及保存位置,和需要拆分的 page 信息,就可以得到新的 pdf 文件了
需求解析
對于 Python GUI,我們有太多種選擇了,下面我們先來橫向的簡單對比下
從高層次上看,大的 GUI 工具有:
- Qt
- WxWindows
- Tkinter
- Customer libraries(Kivy,Toga等)
- Web相關(guān)(HTML,F(xiàn)lask等)
不過今天,我們選擇的工具是 appJar,這是一個由一位從事教育工作的大神發(fā)明的,所以它可以提供一個更加簡單的 GUI 創(chuàng)建過程,而且是完全基于 Tkinter 的,Python 默認(rèn)支持
代碼實現(xiàn)
首先為了實現(xiàn) PDF 操作,我這里選擇了 pypdf2 庫
我們先硬編碼一個輸入輸出的示例
from?PyPDF2?import?PdfFileWriter,?PdfFileReader infile?=?"Input.pdf" outfile?=?"Output.pdf" page_range?=?"1-2,6"
接下來我們實例化 PdfFileWriter 和 PdfFIleReader 對象,并創(chuàng)建實際的 Output.pdf 文件
output?=?PdfFileWriter() input_pdf?=?PdfFileReader(open(infile,?"rb")) output_file?=?open(outfile,?"wb")
下面一個比較復(fù)雜的點就是需要拆分 pdf,提取頁面并保存在列表中
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)]
最后就是從原始文件中拷貝內(nèi)容到新的文件
for?p?in?range_list: ????output.addPage(input_pdf.getPage(p?-?1)) output.write(output_file)
下面來構(gòu)建 GUI 界面
對于這個拆分 PDF 的小工具,需要具有如下功能:
- 可以通過標(biāo)準(zhǔn)文件瀏覽器選擇 pdf 文件
- 可以選擇輸出文件的位置及文件名稱
- 可以自定義提取哪些頁面
- 有一些錯誤檢查
通過 PIP 安裝好 appJar 后,我們就可以編碼了
from?appJar?import?gui from?PyPDF2?import?PdfFileWriter,?PdfFileReader from?pathlib?import?Path
創(chuàng)建 GUI 窗口
app?=?gui("PDF?Splitter",?useTtk=True) app.setTtkTheme("default") app.setSize(500,?200)
這里我使用了默認(rèn)主題,當(dāng)然也可以切換各種各樣的主題模式
下面是添加標(biāo)簽和數(shù)據(jù)輸入組件
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")
接下來添加按鈕,“處理”和“退出”,按下按鈕,調(diào)用如下函數(shù)
app.addButtons(["Process",?"Quit"],?press)
最后就是運行這個 app 啦
#?start?the?GUI app.go()
這樣我們就完成了 GUI 的搭建,下面編寫內(nèi)部處理邏輯。程序讀取任何輸入,判斷是否為 PDF,并拆分
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)”按鈕,則調(diào)用 app.getEntry() 檢索輸入值,每個值都會被存儲,然后通過調(diào)用 validate_inputs() 進(jìn)行驗證
來看看 validate_inputs 函數(shù)
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)
這個函數(shù)就是執(zhí)行一些檢查來確保輸入有數(shù)據(jù)并且有效
在收集驗證了所有數(shù)據(jù)后,就可以調(diào)用 split 函數(shù)來處理文件了
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 文件的工具嘍
到此這篇關(guān)于Python自動化辦公之編寫PDF拆分工具的文章就介紹到這了,更多相關(guān)Python PDF拆分內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python調(diào)用http-post接口的實現(xiàn)方式
這篇文章主要介紹了Python調(diào)用http-post接口的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-08-08Python簡單連接MongoDB數(shù)據(jù)庫的方法
這篇文章主要介紹了Python簡單連接MongoDB數(shù)據(jù)庫的方法,結(jié)合實例形式分析了Python使用pymongo模塊操作MongoDB數(shù)據(jù)庫的相關(guān)技巧,需要的朋友可以參考下2016-03-03Python內(nèi)存管理精準(zhǔn)釋放與延遲拷貝技術(shù)探究
這篇文章主要為大家介紹了Python內(nèi)存管理精準(zhǔn)釋放與延遲拷貝技術(shù)探究,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01python?Seaborn繪制統(tǒng)計圖全面指南(直方圖散點圖小提琴圖熱力圖相關(guān)系數(shù)圖多張合并)
這篇文章主要介紹了python?Seaborn繪制統(tǒng)計圖全面指南,包括直方圖,散點圖,小提琴圖,熱力圖,相關(guān)系數(shù)圖及多張圖合并的實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助2024-01-01