PyPDF2 進階 PDF 自動化教學:批量生成報表、加浮水印與加密保護的 Python 實戰
上次寫了 PyPDF2 基礎的合併與分割教學 之後,收到不少讀者問:「合併分割我會了,但公司要我每個月自動生成幾十份報表加浮水印怎麼辦?」今天就來解決這個問題。
老實說,我自己也是因為前公司每月要處理超過 200 份 PDF 報表,才被逼著把 PyPDF2 摸透的。手動處理一份大概要 3 分鐘,200 份就是 10 小時——寫個腳本跑一次不到 5 分鐘搞定,省下來的時間拿去喝咖啡不好嗎?
為什麼需要 PDF 自動化?
PDF 自動化不只是「把手動操作寫成程式」這麼簡單。它帶來的好處包括:
- 一致性:每份文件的浮水印位置、加密方式完全相同
- 可追溯:搭配 Python logging 模組,每次處理都有完整紀錄
- 可擴展:從處理 10 份到 10,000 份,程式碼幾乎不用改
環境設定與 PyPDF2 安裝
先確認你的 Python 版本在 3.8 以上,然後安裝最新版 PyPDF2:
pip install PyPDF2>=3.0.0
# 如果需要加密功能,額外安裝
pip install pycryptodome
這邊要特別注意,PyPDF2 從 3.0 版開始,原本的 PdfFileReader 和 PdfFileWriter 已經改名為 PdfReader 和 PdfWriter。如果你看到網路上的舊教學還在用舊名稱,記得自己轉換一下。
批量合併 PDF:多檔案整合
最基本的需求:把一個資料夾裡所有 PDF 合併成一份。但實務上你可能還需要「按照特定順序」合併,或者只合併符合條件的檔案:
from PyPDF2 import PdfMerger
from pathlib import Path
def batch_merge(input_dir, output_path, pattern="*.pdf", sort_key=None):
"""批量合併 PDF,支援自訂排序"""
merger = PdfMerger()
pdf_files = sorted(Path(input_dir).glob(pattern), key=sort_key or (lambda x: x.name))
for pdf_path in pdf_files:
print(f"合併中: {pdf_path.name}")
merger.append(str(pdf_path))
merger.write(str(output_path))
merger.close()
print(f"完成!共合併 {len(pdf_files)} 個檔案 → {output_path}")
# 使用範例:依檔名排序合併
batch_merge("./monthly_reports/", "merged_2026_q1.pdf")
智慧分割:按頁碼與書籤拆分
有時候你拿到一份 100 頁的大 PDF,需要按章節拆分。比較聰明的做法是讀取 PDF 的書籤來自動判斷分割點:
from PyPDF2 import PdfReader, PdfWriter
def split_by_ranges(input_path, ranges):
"""按頁碼範圍分割 PDF
ranges: [(start, end, filename), ...]
"""
reader = PdfReader(input_path)
for start, end, filename in ranges:
writer = PdfWriter()
for page_num in range(start - 1, min(end, len(reader.pages))):
writer.add_page(reader.pages[page_num])
with open(filename, 'wb') as f:
writer.write(f)
print(f"已輸出: {filename} ({end - start + 1} 頁)")
# 使用範例
split_by_ranges("big_report.pdf", [
(1, 10, "chapter1.pdf"),
(11, 25, "chapter2.pdf"),
(26, 50, "chapter3.pdf"),
])
自動加浮水印:保護文件版權
加浮水印是我最常被問到的需求。原理很簡單:先準備一份只有浮水印的 PDF(可以用 reportlab 產生),然後疊加到目標 PDF 的每一頁上:
from PyPDF2 import PdfReader, PdfWriter
def add_watermark(input_path, watermark_path, output_path):
"""為 PDF 每一頁加上浮水印"""
reader = PdfReader(input_path)
watermark = PdfReader(watermark_path)
watermark_page = watermark.pages[0]
writer = PdfWriter()
for page in reader.pages:
page.merge_page(watermark_page)
writer.add_page(page)
with open(output_path, 'wb') as f:
writer.write(f)
print(f"浮水印已加入: {output_path}")
# 批量處理整個資料夾
from pathlib import Path
for pdf in Path("./contracts/").glob("*.pdf"):
add_watermark(str(pdf), "watermark.pdf", f"./output/{pdf.name}")
小技巧:如果浮水印文字需要動態變化(比如每份合約加上客戶名稱),可以搭配 reportlab 先動態生成浮水印 PDF,再用上面的方法疊加。
PDF 加密與密碼保護
有些文件在寄出前需要加密碼保護。PyPDF2 支援兩種密碼:使用者密碼(打開文件時需要)和擁有者密碼(控制列印、複製等權限):
from PyPDF2 import PdfReader, PdfWriter
def encrypt_pdf(input_path, output_path, user_password, owner_password=None):
"""加密 PDF 文件"""
reader = PdfReader(input_path)
writer = PdfWriter()
for page in reader.pages:
writer.add_page(page)
writer.encrypt(
user_password=user_password,
owner_password=owner_password or user_password,
use_128bit=True
)
with open(output_path, 'wb') as f:
writer.write(f)
print(f"已加密: {output_path}")
實戰:批量生成月報表
把前面學到的技巧整合起來,這是我實際在用的月報表生成流程:
- 從資料庫撈取每位客戶的數據
- 用 reportlab 生成個別報表 PDF
- 加上該客戶專屬浮水印
- 加密碼保護
- 自動寄信(搭配 smtplib)
from pathlib import Path
def generate_monthly_reports(clients_data):
"""完整的月報表生成流程"""
output_dir = Path("./reports/")
output_dir.mkdir(exist_ok=True)
for client in clients_data:
name = client["name"]
report = output_dir / f"{name}_report.pdf"
watermarked = output_dir / f"{name}_wm.pdf"
final = output_dir / f"{name}_final.pdf"
add_watermark(str(report), "watermark.pdf", str(watermarked))
encrypt_pdf(str(watermarked), str(final), client["password"])
watermarked.unlink()
print(f"✓ {name} 的報表已生成")
從舊 API 遷移到新版 PdfReader
如果你的專案還在用舊版 API,這裡整理了對照表:
| 舊版(< 3.0) | 新版(≥ 3.0) |
|---|---|
| PdfFileReader | PdfReader |
| PdfFileWriter | PdfWriter |
| PdfFileMerger | PdfMerger |
| getPage(n) | pages[n] |
| getNumPages() | len(reader.pages) |
| addPage() | add_page() |
結語與下一步
掌握了這些技巧,大部分的 PDF 自動化需求你都能搞定了。如果你想把這些功能包裝成 API 服務,推薦看看 FastAPI 的教學,用 FastAPI 把 PDF 處理功能封裝成微服務,團隊裡其他人就能直接呼叫 API 來處理 PDF 了。
下一篇我會寫怎麼用 Python 自動化處理 Excel 報表,搭配今天的 PDF 技巧,整套報表流程就完全自動化了。有問題歡迎留言討論!
繼續閱讀
Python Requests 網頁爬蟲入門:從 HTTP 請求到資料擷取完整教學
想用 Python 自動抓取網頁資料?這篇手把手教你用 Requests + BeautifulSoup 建立你的第一支爬蟲程式。
相關文章
你可能也喜歡
探索其他領域的精選好文