Python處理PDF文檔

PDF 表示 Portable Document Format,使用 .pdf 作爲文件擴展名。雖然 PDF 支持許多功能,但現在我們專注於最常做的兩件事:從 PDF 讀取文本內容和從已有的文檔生成新的 PDF。主要涉及到三個類:PdfFileReader、PdfFileWriter、PageObject。
Python中用於處理PDF文檔的模塊是PyPDF2。可以直接通過 pip 指令去安裝:pip install PyPDF2 。 這個地方要注意,模塊名是區分大小寫的,除了 y 是小寫其他字母都是大寫。

1. PdfFileReader

PdfFileReader是 PyPDF2 提供的一個類,主要是通過方法和屬性來提供獲取pdf文件內容的相關功能。
使用PdfFileReader讀取pdf文件前需要先創建一個PdfFileReader的對象:

PdfFileReader(stream, strict = True,warndest = None,overwriteWarnings = True)
  • stream: **File 對象或支持與 File 對象類似的標準讀取和查找方法的對象,**也可以是表示 PDF 文件路徑的字符串。
  • strict(bool): 確定是否應該警告用戶所用的問題,也導致一些可糾正的問題是致命的,默認是 True
  • warndest : 記錄警告的目標(默認是 sys.stderr)
  • overwriteWarnings(bool):確定是否 warnings.py 用自定義實現覆蓋 Python 模塊(默認爲 True)

下表是部分 PdfFileReader 對象的方法和屬性:

屬性和方法 描述
getDestinationPageNumber(destination) 檢索給定目標對象的頁碼
getDocumentInfo() 檢索 PDF 文件的文檔信息字典
getFields(tree = None,retval = None,fileObj= None) 如果此 PDF 包含交互式表單字段,則提取字段數據,
getFormTextFields() 從文檔中檢索帶有文本數據(輸入,下拉列表)的表單域
getNameDestinations(tree = None,retval= None) 檢索文檔中的指定目標
getNumPages() 計算此 PDF 文件中的頁數
getOutlines(node = None,outline = None,) 檢索文檔中出現的文檔大綱
getPage(pageNumber) 從這個 PDF 文件中檢索指定編號的頁面
getPageLayout() 獲取頁面佈局
getPageMode() 獲取頁面模式
getPageNumber(pageObject) 檢索給定 pageObject 處於的頁碼
getXmpMetadata() 從 PDF 文檔根目錄中檢索 XMP 數據
isEncrypted 顯示 PDF 文件是否加密的只讀布爾屬性
decrypt(密碼) 通過指定密碼對pdf文件進行解密

實例一:從PDF文件中提取文本

# 從PyPDF2模塊中導入PdfFileReader類
from PyPDF2 import PdfFileReader

# 打開需要操作的pdf文件,獲取文件對象。因爲pdf文件是二進制文件,所以打開的時候是 'rb'
pdf_file = open('files/new.pdf', 'rb')

# 創建pdf文件對應的PdfFileReader對象
pdf_reader = PdfFileReader(pdf_file)

# 獲取當前pdf文件總頁數(這兒其實不需要,只是給大家看看)
total_page = pdf_reader.getNumPages()       # 結果是: 17

# 獲取pdf文件的第一頁
page0 = pdf_reader.getPage(0)

# 獲取第一頁中的文本內容
text_content = page0.extractText()
print(text_content)

實例二:解密

# 從PyPDF2模塊中導入PdfFileReader類
from PyPDF2 import PdfFileReader

# 創建PdfFileReader對象,並且讓它和指定的pdf文件進行關聯
# pdf_reader = PdfFileReader('files/MySQL.pdf')   # 打開文件的時候可以直接給pdf文件路徑
pdf_reader = PdfFileReader(open('files/MySQL.pdf', 'rb'))     # 打開文件的時候可以直接給文件對象

# 是否加密 - 如果結果是True,表示已經加密,如果獲取頁面的時候程序會報錯
is_encrypted = pdf_reader.isEncrypted

# 通過密碼解密, 這兒的 1234 是密碼
pdf_reader.decrypt('1234')

# 獲取當前pdf文件的第一頁
page0 = pdf_reader.getPage(0)

2. PdfFileWriter

在 PyPDF2 中,與 PdfFileReader 對象相對的是 PdfFileWriter 對象,它可以創建一個新的 PDF 文件。但 PyPDF2 不能將任意文本寫入 PDF,就像 Python 可以寫入純文本文件那樣。PyPDF2 寫入 PDF 的能力,僅限於從其他 PDF 中拷貝頁面、旋轉頁面、重疊頁面和加密文件。模塊不允許直接編輯 PDF。必須創建一個新的 PDF,然後從已有的文檔拷貝內容。PdfFileWriter 的使用一般遵守以下方式:

  1. 打開一個或多個已有的 PDF(源 PDF),得到 PdfFileReader 對象。
  2. 創建一個新的 PdfFileWriter 對象。
  3. 將頁面從 PdfFileReader 對象拷貝到 PdfFileWriter 對象中。
  4. 最後,利用 PdfFileWriter 對象寫入輸出的 PDF。

創建一個PdfFileWriter 對象,只是在Python 中創建了一個代表PDF 文檔的值,這並沒有創建實際的PDF 文件,要實際生成文件,必須調用PdfFileWriter 對象的write()方法。

下表是部分 PdfFileWriter 對象的方法和屬性:

屬性和方法 描述
addAttachment(fname,fdata) 在 PDF 中嵌入文件
addBlankPage(width= None,height=None) 追加一個空白頁面到這個 PDF 文件並返回它
addJS(javascript) 添加將在打開此 PDF 是啓動的 javascript
addLink(pagenum,pagedest,rect,border=None,fit=’/fit’,*args) 從一個矩形區域添加一個內部鏈接到指定的頁面
addPage(page) 添加一個頁面到這個PDF 文件,該頁面通常從 PdfFileReader 實例獲取
getNumpages() 頁數
getPage(pageNumber) 從這個 PDF 文件中檢索一個編號的頁面
insertBlankPage(width=None,height=None,index=0) 插入一個空白頁面到這個 PDF 文件並返回它,如果沒有指定頁面大小,就使用最後一頁的大小
insertPage(page,index=0) 在這個 PDF 文件中插入一個頁面,該頁面通常從 PdfFileReader 實例獲取
removeLinks() 從次數出中刪除連接盒註釋
removeText(ignoreByteStringObject = False) 從這個輸出中刪除圖像
write(stream) 將添加到此對象的頁面集合寫入 PDF 文件

實例三:拷貝頁面

from PyPDF2 import PdfFileReader, PdfFileWriter

# 創建兩個pdf文件對應的PdfFileReader對象
pdf_reader1 = PdfFileReader('files/file1.pdf')
pdf_reader2 = PdfFileReader('files/file2.pdf')

# 創建PdfFileWriter對象
writer = PdfFileWriter()

# 遍歷將第一個pdf文件中的每一頁取出來
for page_num in range(pdf_reader1.getNumPages()):
    # 取出每一頁對應的PageObject對象
    page = pdf_reader1.getPage(page_num)
    # 將當前取出來的頁面添加到writer中
    writer.addPage(page)

# 遍歷將第二個pdf文件中的每一頁取出來
for page_num in range(pdf_reader2.getNumPages()):
    # 取出每一頁對應的PageObject對象
    page = pdf_reader2.getPage(page_num)
    # 將當前取出來的頁面添加到writer中
    writer.addPage(page)

# write(stream)  - 將添加到此對象的頁面集合寫入 PDF 文件 ,這兒的stream必須是以寫的方式打開的文件對象
out_file = open('files/out.pdf', 'wb')
writer.write(out_file)
out_file.close()

# 程序結束後,會在files下創建一個 out.pdf 文件,文件中的內容是 file1.pdf 和 file2.pdf 兩個文件中的所有內容

3. PageObject

從 PdfFileReader 對象中通過 getPage 方法得到頁面都是 PageObject 的對象。

下表是部分 PageObject 對象的屬性和方法:

屬性或方法 描述
createBlankPage(pdf=None,width=None,height=None) 返回一個新的空白頁面(靜態方法)
extractText() 找到所有文本繪圖命令,按照他們在內容流中提供的順序,並提取文本
getContents() 訪問頁面內容,返回 Contents 對象或 None
rotateClockwise(angle) 順時針旋轉指定度數
scale(sx,sy) 通過向其內容應用轉換矩陣並更新頁面大小
mergePage(page) 頁面的合併
compressContentStreams() 頁面壓縮
mediaBox.upperRight 將頁面裁剪成指定大小
mediaBox.getUpperRight_x()/mediaBox.getUpperRight_y() 獲取頁面的大小

實例四:旋轉頁面

# **實例三:拷貝頁面**
from PyPDF2 import PdfFileReader, PdfFileWriter

# 打開文件
# file_reader = PdfFileReader(open('files/MySQL.pdf', 'rb'))
file_reader = PdfFileReader('files/MySQL.pdf')

# 取第一頁
page0 = file_reader.getPage(0)

# 旋轉90度
page0.rotateClockwise(90)

# 創建 PdfFileWriter 對象
file_writer = PdfFileWriter()

# 將第一頁添加到新文件中
file_writer.addPage(page0)

# 保存新文件
file_writer.write(open('files/MySQL2.pdf', 'wb'))

在這裏插入圖片描述

PyPDF2 也可以將一頁的內容疊加到另一頁上,這可以用來在頁面上添加公司標誌、時間戳或水印。利用 Python,很容易爲多個文件添加水印,並且只針對程序指定的頁面添加。

實例五: 添加水印

from PyPDF2 import PdfFileReader, PdfFileWriter

# 打開需要添加水印的文件
pdf_reader = PdfFileReader('files/MySQL.pdf')

# 打開水印文件
water_reader = PdfFileReader('files/water.pdf')

# 獲取需要添加水印的頁面(如果所有也都要添加水印就遍歷)
page0 = pdf_reader.getPage(0)

# 獲取水印頁
water_page = water_reader.getPage(0)

# 合併
page0.mergePage(water_page)

# 創建PdfFileWriter對象並且將已經添加水印的也添加到PdfFileWriter對象中
writer = PdfFileWriter()
writer.addPage(page0)

# 保存
writer.write(open('out/newMySQL.pdf', 'wb'))

在這裏插入圖片描述

實例六:加密PDF
PdfFileWriter 對象也可以爲 PDF 文檔進行加密:

from PyPDF2 import PdfFileWriter, PdfFileReader

# 打開需要加密的文件
file_reader = PdfFileReader('files/MySQL.pdf')

# 創建PdfFileWriter對象
file_writer = PdfFileWriter()

# 將原文件的內容全部添加到PdfFileWriter對象中
for page_num in range(file_reader.getNumPages()):
    file_writer.addPage(file_reader.getPage(page_num))

# 加密,並且設置密碼爲: 123456
file_writer.encrypt('123456')

# 保存文件
file_writer.write(open('out/newMySQL.pdf', 'wb'))

參考書籍:《Python編程快速上手-讓繁瑣工作自動化》

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章