Python實(shí)現(xiàn)自動(dòng)化處理PDF文件的方法詳解
自動(dòng)化處理PDF文件
使用Python完成簡(jiǎn)單的PDF文件處理操作,如PDF文件的批量合并、拆分、加密以及添加水印等。
1. 批量合并PDF文件
from pathlib import Path # PdfFileReader用于讀取PDF文件,PdfFileMerger用于合并PDF文件 from PyPDF2 import PdfFileReader, PdfFileMerger src_folder = Path('PDF1') # 設(shè)置要合并的多個(gè)PDF文件所在的文件路徑 des_file = Path(r'PDF2\combine.pdf') # 設(shè)置合并后的PDF文件的保存文件夾和文件名 # 調(diào)用路徑對(duì)象的parent屬性返回父文件夾(即保存文件夾)的路徑 if not des_file.parent.exists(): # 如果該文件夾不存在,則創(chuàng)建該文件夾 des_file.parent.mkdir(parents=True) # 獲取所有要合并的PDF文件的路徑 file_list = list(src_folder.glob('*.pdf')) # 讀取PDF并進(jìn)行合并 merger = PdfFileMerger() # 創(chuàng)建PdfFileMerger對(duì)象 outputPages = 0 # 統(tǒng)計(jì)合并到PDF文件的總頁(yè)數(shù) # 遍歷文件列表 for pdf in file_list: input_file = PdfFileReader(str(pdf)) # 讀取待合并的PDF文件 merger.append(input_file) # 將PDF文件合并到PdfFileMerger對(duì)象中 pageCount = input_file.getNumPages() # 獲取PDF文件的頁(yè)數(shù) print(f'{pdf.name}--頁(yè)數(shù):{pageCount}') outputPages += pageCount # 進(jìn)行累加,統(tǒng)計(jì)總頁(yè)數(shù) merger.write(str(des_file)) # 將合并好的PDF文件寫(xiě)入指定的路徑 merger.close() # 關(guān)閉PdfFileMerger對(duì)象,釋放資源 print(f'\n合并后的總頁(yè)數(shù):{outputPages}')
測(cè)試文件:
效果:
2. 批量拆分PDF文件
from math import ceil from pathlib import Path from PyPDF2 import PdfFileReader, PdfFileWriter src_folder = Path('PDF2') # 設(shè)置要拆分的多個(gè)PDF文件所在的文件路徑 output_folder = Path('PDF2') # 設(shè)置拆分后的PDF文件的保存文件夾和文件名 # 獲取所有要拆分的PDF文件的路徑 file_list = list(src_folder.glob('*.pdf')) # 采用按固定頁(yè)數(shù)進(jìn)行拆分 step = 5 # 每份為5頁(yè) for pdf in file_list: inputFile = PdfFileReader(str(pdf)) pages = inputFile.getNumPages() # 獲取PDF文件的頁(yè)數(shù) # 判斷PDF文件頁(yè)數(shù)是否小于等于step if pages <= step: # 若是則不進(jìn)行拆分 continue else: parts = ceil(pages / step) # 拆分的份數(shù),向上取整 # 根據(jù)份數(shù)進(jìn)行循環(huán) for pt in range(parts): # 計(jì)算每一份的開(kāi)始頁(yè)碼和結(jié)束頁(yè)碼 # PyPDF2模塊中,PDF文件頁(yè)碼從0開(kāi)始 start = step * pt # 判斷是否是最后一份 if pt != (parts - 1): # 如果不是最后一份,那么結(jié)束頁(yè)碼為開(kāi)始頁(yè)碼加每份頁(yè)數(shù)減1 end = start + step - 1 else: # 若是最后一份,則結(jié)束頁(yè)碼等于文件頁(yè)數(shù)減1 end = pages - 1 # 拆分文件 outputfile = PdfFileWriter() # 創(chuàng)建PdfFileWriter對(duì)象 for pageNum in range(start, end + 1): outputfile.addPage(inputFile.getPage(pageNum)) # 調(diào)用路徑對(duì)象的stem屬性獲取文件的主名,與后面的字符串拼接成PDF文件名 pt_name = f'{pdf.stem}_第{pt + 1}份.pdf' pt_file = output_folder / pt_name # 生成當(dāng)前份的PDF文件的保存路徑 with open(pt_file, 'wb') as f: outputfile.write(f) print(f'【{pdf.name}】共{pages}頁(yè),拆分為{parts}份-->完成')
效果:
3. 批量加密PDF文件
from pathlib import Path from PyPDF2 import PdfFileReader, PdfFileWriter src_folder = Path('PDF2') # 設(shè)置要加密的多個(gè)PDF文件所在的文件路徑 output_folder = Path('PDF2') # 設(shè)置加密后的PDF文件的保存文件夾和文件名 # 獲取所有要加密的PDF文件的路徑 file_list = list(src_folder.glob('*.pdf')) # 遍歷文件列表 for pdf in file_list: inputFile = PdfFileReader(str(pdf)) # 讀取文件 outputFile = PdfFileWriter() # 創(chuàng)建PdfFileWriter對(duì)象 pageCount = len(inputFile.pages) # 獲得PDF文件頁(yè)數(shù) for pageNum in range(pageCount): # 將PDF內(nèi)容逐頁(yè)添加到輸出文件 outputFile.add_page(inputFile.pages[pageNum]) # 進(jìn)行加密 outputFile.encrypt('123456') # 輸出文件名 output_name = f'{pdf.stem}_encrypted.pdf' # 輸出文件的路徑 output_path = output_folder / output_name with open(output_path, 'wb') as pf: outputFile.write(pf) print(f'{output_name}加密文件-->保存完成')
效果:
4. 批量PDF添加水印
4.1 創(chuàng)建水印文件
安裝reportlab模塊
pip install reportlab
def createWatermark(content): """ 創(chuàng)建水印 :param content: 水印內(nèi)容 :return: """ filename = 'watermark.pdf' # 水印文件的文件名 can = canvas.Canvas(filename=filename, pagesize=(30 * cm, 30 * cm)) # 設(shè)置水印文件的頁(yè)面大小 can.translate(5 * cm, 0 * cm) # 設(shè)置頁(yè)面的坐標(biāo)原點(diǎn) # 注冊(cè)水印文件需要使用的字體 reportlab.pdfbase.ttfonts.pdfmetrics.registerFont( reportlab.pdfbase.ttfonts.TTFont(name='華文行楷', filename=r'C:\Windows\Fonts\STXINGKA.TTF')) can.setFont(psfontname='華文行楷', size=25) # 設(shè)置水印字體即字號(hào) can.rotate(28) # 設(shè)置水印旋轉(zhuǎn)角度 can.setFillColorRGB(r=0.3, g=0.6, b=0.9) # 設(shè)置填充顏色 can.setFillAlpha(a=0.2) # 設(shè)置透明度 for i in range(0, 30, 5): for j in range(0, 30, 5): can.drawString(x=i * cm, y=j * cm, text=content) # 繪制6行x6列的水印文字 can.save() # 保存水印 return filename
4.2 添加水印
def addWatermark(pdf_file_input, pdf_file_mark, pdf_file_output): """ 添加水印 :param pdf_file_input: 需要添加水印的文件 :param pdf_file_mark: 水印文件 :param pdf_file_output: 輸出文件 :return: """ input_file = PdfFileReader(pdf_file_input) output_file = PdfFileWriter() # 創(chuàng)建PdfFileWriter對(duì)象 page_count = len(input_file.pages) # 獲得PDF文件頁(yè)數(shù) water_mark = PdfFileReader(pdf_file_mark) # 讀取水印PDF文件 for pageNum in range(page_count): page = input_file.pages[pageNum] page.merge_page(water_mark.pages[0]) # 將兩張PDF合并成1張 output_file.add_page(page) # 將頁(yè)面添加到PDF文件 with open(pdf_file_output, 'wb') as pf: output_file.write(pf) print(f'{pdf_file_input}添加水印-->處理完成')
完整代碼
# author:mlnt # createdate:2022/8/25 from pathlib import Path from PyPDF2 import PdfFileReader, PdfFileWriter from reportlab.lib.units import cm from reportlab.pdfgen import canvas import reportlab.pdfbase.ttfonts def createWatermark(content): """ 創(chuàng)建水印 :param content: 水印內(nèi)容 :return: """ filename = 'watermark.pdf' # 水印文件的文件名 can = canvas.Canvas(filename=filename, pagesize=(30 * cm, 30 * cm)) # 設(shè)置水印文件的頁(yè)面大小 can.translate(5 * cm, 0 * cm) # 設(shè)置頁(yè)面的坐標(biāo)原點(diǎn) # 注冊(cè)水印文件需要使用的字體 reportlab.pdfbase.ttfonts.pdfmetrics.registerFont( reportlab.pdfbase.ttfonts.TTFont(name='華文行楷', filename=r'C:\Windows\Fonts\STXINGKA.TTF')) can.setFont(psfontname='華文行楷', size=25) # 設(shè)置水印字體即字號(hào) can.rotate(28) # 設(shè)置水印旋轉(zhuǎn)角度 can.setFillColorRGB(r=0.3, g=0.6, b=0.9) # 設(shè)置填充顏色 can.setFillAlpha(a=0.2) # 設(shè)置透明度 for i in range(0, 30, 5): for j in range(0, 30, 5): can.drawString(x=i * cm, y=j * cm, text=content) # 繪制6行x6列的水印文字 can.save() # 保存水印 return filename def addWatermark(pdf_file_input, pdf_file_mark, pdf_file_output): """ 添加水印 :param pdf_file_input: 需要添加水印的文件 :param pdf_file_mark: 水印文件 :param pdf_file_output: 輸出文件 :return: """ input_file = PdfFileReader(pdf_file_input) output_file = PdfFileWriter() # 創(chuàng)建PdfFileWriter對(duì)象 page_count = len(input_file.pages) # 獲得PDF文件頁(yè)數(shù) water_mark = PdfFileReader(pdf_file_mark) # 讀取水印PDF文件 for pageNum in range(page_count): page = input_file.pages[pageNum] page.merge_page(water_mark.pages[0]) # 將兩張PDF合并成1張 output_file.add_page(page) # 將頁(yè)面添加到PDF文件 with open(pdf_file_output, 'wb') as pf: output_file.write(pf) print(f'{pdf_file_input}添加水印-->處理完成') if __name__ == '__main__': # 創(chuàng)建Path對(duì)象 src_folder = Path('PDF1') output_folder = Path('PDF_mark') # 判斷輸出目錄是否存在 if not output_folder.exists(): # 不存在則創(chuàng)建 output_folder.mkdir(parents=True) file_list = list(src_folder.glob('*.pdf')) # 獲得給定目錄下的所有pdf文件的路徑 for file in file_list: pdf_file_in = str(file) # 輸入文件路徑 # 創(chuàng)建水印 pdf_file_mark = createWatermark('絕密文件') # 輸出文件名 output_name = f'{file.stem}_mark.pdf' pdf_file_out = str(output_folder / output_name) # 輸出文件的路徑 addWatermark(pdf_file_in, pdf_file_mark, pdf_file_out) # 添加水印
效果:
以上就是Python實(shí)現(xiàn)自動(dòng)化處理PDF文件的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Python自動(dòng)化處理PDF的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Pygame實(shí)戰(zhàn)練習(xí)之保護(hù)單身狗游戲
下面這篇文章主要給大家介紹了關(guān)于如何利用python寫(xiě)一個(gè)簡(jiǎn)單的由經(jīng)典躲避類(lèi)益智小游戲修改的保護(hù)單身狗游戲的相關(guān)資料,需要的朋友可以參考下2021-09-09Python語(yǔ)法學(xué)習(xí)之進(jìn)程間的通信方式
進(jìn)程在創(chuàng)建之后是沒(méi)有辦法獲取返回值的,但有的時(shí)候兩個(gè)進(jìn)程之間需要進(jìn)行相互之間的配合才能完成工作,這就需要通信的幫助。本文主要介紹了Python中進(jìn)程間的通信方式,需要的可以了解一下2022-04-04通過(guò) Django Pagination 實(shí)現(xiàn)簡(jiǎn)單分頁(yè)功能
這篇文章主要介紹了通過(guò) Django Pagination 實(shí)現(xiàn)簡(jiǎn)單分頁(yè)功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11Python 動(dòng)態(tài)變量名定義與調(diào)用方法
這篇文章主要介紹了Python 動(dòng)態(tài)變量名定義與調(diào)用方法,需要的朋友可以參考下2020-02-02Python pyinotify日志監(jiān)控系統(tǒng)處理日志的方法
這篇文章主要介紹了Python pyinotify日志監(jiān)控系統(tǒng)處理日志的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03pycharm中選中一個(gè)單詞替換所有重復(fù)單詞的實(shí)現(xiàn)方法
這篇文章主要介紹了pycharm中選中一個(gè)單詞替換所有重復(fù)單詞的實(shí)現(xiàn)方法,類(lèi)似于sublime 里的ctrl+D功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2020-11-11Python中類(lèi)型關(guān)系和繼承關(guān)系實(shí)例詳解
這篇文章主要介紹了Python中類(lèi)型關(guān)系和繼承關(guān)系,較為詳細(xì)的分析了Python中類(lèi)型關(guān)系和繼承關(guān)系的原理與使用技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-05-05Python實(shí)現(xiàn)按學(xué)生年齡排序的實(shí)際問(wèn)題詳解
這篇文章主要給大家介紹了關(guān)于Python實(shí)現(xiàn)按學(xué)生年齡排序?qū)嶋H問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08用60行代碼實(shí)現(xiàn)Python自動(dòng)搶微信紅包
這篇文章主要介紹了用60行代碼實(shí)現(xiàn)Python自動(dòng)搶微信紅包,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-02-02