在RPA流程設計中,會有各種文件的處理,其中就包括對pdf文件的處理,這時候就須要調用PyPDF2進行相關的代碼編寫了。
PyPDF2 是一個純 Python 包,可經過使用 PyPDF2 包在 Python 中處理已先存在的 PDF。python
使用 PyPDF2 從 PDF 中提取元數據和一些文本,尤爲是當在預先存在的 PDF 文件上執行某些類型的自動化時是很是有用的。
如下是當前能夠提取的數據:函數
能夠在本身的電腦上隨便找一個 PDF 文件進行嘗試操做。下面是使用該 PDF 編寫一些代碼,並瞭解如何訪問這些屬性:加密
from PyPDF2 import PdfFileReader def extract_information(pdf_path): with open(pdf_path, 'rb') as f: pdf = PdfFileReader(f) information = pdf.getDocumentInfo() number_of_pages = pdf.getNumPages() txt = f""" Information about {pdf_path}: Author: {information.author} Creator: {information.creator} Producer: {information.producer} Subject: {information.subject} Title: {information.title} Number of pages: {number_of_pages} """ print(txt) return information if __name__ == '__main__': path = 'xxxx.pdf' extract_information(path)
首先從 PyPDF2 包導入 PdfFileReader。PdfFileReader 是一個具備多種與 PDF 文件交互的方法的類。在此示例中,咱們調用了.getDocumentInfo(),它將返回 DocumentInformation 的實例, 包含了咱們感興趣的大部分信息。咱們還能夠在 reader 對象上調用.getNumPages(),讓它返回文檔中的頁數。命令行
information 這個變量具備多個實例屬性,可使用這些屬性從文檔中獲取所需的其他元數據。咱們能夠打印出該信息並將其返回以備未來使用。設計
雖然 PyPDF2 具備.extractText(),能夠在其頁面對象上使用提取文本(本例中未顯示),但它的效果不是很好。有些 PDF 會返回文本,有些會返回空字符串。若是要從 PDF 中提取文本,建議應該看一下 PDFMiner 項目。PDFMiner 更增強大,專門用於從 PDF 中提取文本。code
有時候 PDF 是橫向模式而不是縱向模式,甚至是顛倒的。當有人掃描文檔爲 PDF 或電子郵件時,極可能會發生這種狀況。咱們能夠打印出文檔並閱讀紙質版本,也可使用 Python 的強大功能來旋轉有問題的頁面。orm
下面看一下如何使用 PyPDF2 旋轉文章的一些頁面:對象
from PyPDF2 import PdfFileReader, PdfFileWriter def rotate_pages(pdf_path): pdf_writer = PdfFileWriter() pdf_reader = PdfFileReader(path) # 順時針旋轉90度 page_1 = pdf_reader.getPage(0).rotateClockwise(90) pdf_writer.addPage(page_1) # 逆時針旋轉90度 page_2 = pdf_reader.getPage(1).rotateCounterClockwise(90) pdf_writer.addPage(page_2) # 在正常方向上添加一頁 pdf_writer.addPage(pdf_reader.getPage(2)) with open('rotate_pages.pdf', 'wb') as fh: pdf_writer.write(fh) if __name__ == '__main__': path = '新路徑.pdf' rotate_pages(path)
在許多狀況下,咱們但願將兩個或多個 PDF 合併到一個 PDF 中。例如,如今可能有一個標準的封面,須要轉到許多類型的報告中。這時候就可使用 python 來幫助完成這類工做。接口
下面是實現的代碼,完成 PDF 合併的操做:文檔
from PyPDF2 import PdfFileReader, PdfFileWriter def merge_pdfs(paths, output): pdf_writer = PdfFileWriter() for path in paths: pdf_reader = PdfFileReader(path) for page in range(pdf_reader.getNumPages()): # 將每頁添加到writer對象 pdf_writer.addPage(pdf_reader.getPage(page)) # 寫入合併的pdf with open(output, 'wb') as out: pdf_writer.write(out) if __name__ == '__main__': paths = ['document1.pdf', 'document2.pdf'] merge_pdfs(paths, output='merged.pdf')
假若有一個要合併到一塊兒的 pdf 列表時,能夠直接使用 merge_pdf 函數完成。此函數採用了輸入路徑和輸出路徑做爲參數。
首先遍歷輸入的 paths,併爲每一個輸入建立一個 PDF 閱讀對象。而後遍歷 PDF 文件中的全部頁面,並使用.addpage() 將這些頁面寫入 writer 對象。當完成對列表中全部 PDF 的全部頁面的寫入後,將在末尾寫入新的結果中。
若是不想合併每一個 PDF 的全部頁面,能夠經過添加一系列要添加的頁面來稍微加強這個腳本。挑戰一點的話,也可使用 Python 的 argparse 模塊爲這個函數建立一個命令行接口。
有時可能須要將 PDF 拆分爲多個 PDF,對於包含大量掃描內容的 PDF 來講尤爲重要。如下是如何使用 PyPDF2 將 PDF 拆分爲多個文件:
from PyPDF2 import PdfFileReader, PdfFileWriter def split(path, name_of_split): pdf = PdfFileReader(path) for page in range(pdf.getNumPages()): pdf_writer = PdfFileWriter() pdf_writer.addPage(pdf.getPage(page)) output = f'{name_of_split}{page}.pdf' with open(output, 'wb') as output_pdf: pdf_writer.write(output_pdf) if __name__ == '__main__': path = 'xxx.pdf' split(path, 'jupyter_page')
這個函數中再次建立了 PDF 的 reaer 對象,並對其所讀取的頁面進行遍歷。對於 PDF 中的每一個頁面,建立一個新的 PDF 的 writer 實例並向其添加單個頁面。而後,將該頁面寫入一個惟一命名的文件。腳本運行完畢後,就能夠將原始 PDF 的每一個頁面拆分爲單獨的 PDF。
水印是紙質或者電子文檔上的圖像或圖案,一些水印只能在特殊照明條件下才能看到。水印的重要性在於它能夠保護你的知識產權,例如圖像或 PDF。
咱們可使用 Python 和 PyPDF2 爲文檔添加水印,並且是擁有僅包含水印圖像或文本的 PDF。下面是向 PDF 添加水印方法:
from PyPDF2 import PdfFileWriter, PdfFileReader def create_watermark(input_pdf, output, watermark): watermark_obj = PdfFileReader(watermark) watermark_page = watermark_obj.getPage(0) pdf_reader = PdfFileReader(input_pdf) pdf_writer = PdfFileWriter() # 給全部頁面添加水印 for page in range(pdf_reader.getNumPages()): page = pdf_reader.getPage(page) page.mergePage(watermark_page) pdf_writer.addPage(page) with open(output, 'wb') as out: pdf_writer.write(out) if __name__ == '__main__': create_watermark( input_pdf='Jupyter_Notebook_An_Introduction.pdf', output='watermarked_notebook.pdf', watermark='watermark.pdf')
上面 create_watermark 有三個參數:
在代碼中,打開水印 PDF 並從文檔中抓取第一頁,由於這是水印應該駐留的位置。而後使用 input_pdf 和通用 pdf_writer 對象建立 PDF 的 writer 對象,以寫出帶水印的 PDF。
下一步是遍歷 input_pdf 中的頁面,而後調用.mergePage() 並以用上面讀取的水印對象 watermark_page 爲參數,這樣會將 watermark_page 覆蓋在當前頁面的頂部,而後再將新合併的頁面添加到 pdf_writer 對象中。遍歷完成後,最後將新加水印的 PDF 寫入磁盤。
PyPDF2 目前僅支持將用戶密碼和全部者密碼添加到預先存在的 PDF。在 PDF 版本中,全部者密碼會提供 PDF 的管理員權限,並容許設置文檔的權限,而用戶密碼只容許打開文檔。
實際上,PyPDF2 是不容許設置文檔的任何權限的,即便它容許設置全部者密碼的狀況下。但不管如何,這是能夠加密的方式,也將固有地加密 PDF:
from PyPDF2 import PdfFileWriter, PdfFileReader def add_encryption(input_pdf, output_pdf, password): pdf_writer = PdfFileWriter() pdf_reader = PdfFileReader(input_pdf) for page in range(pdf_reader.getNumPages()): pdf_writer.addPage(pdf_reader.getPage(page)) pdf_writer.encrypt(user_pwd=password, owner_pwd=None, use_128bit=True) with open(output_pdf, 'wb') as fh: pdf_writer.write(fh) if __name__ == '__main__': add_encryption(input_pdf='reportlab-sample.pdf', output_pdf='reportlab-encrypted.pdf', password='twofish')
dd_encryption 以輸入輸出 PDF 路徑和要添加到 PDF 的密碼爲參數。因爲須要加密整個輸入 PDF,所以須要遍歷其全部頁面並將其添加到 writer 編寫器。最後一步是調用.encrypt(),以用戶密碼,全部者密碼以及是否應該添加 128 位加密爲參數。默認狀況下,要啓用 128 位加密。若是將其設置爲 False,則將應用 40 位加密。