「Python實用秘技04」為pdf文件批量添加文字水印
- 2022 年 1 月 20 日
- 筆記
- Python, Python實用秘技
本文完整示例程式碼及文件已上傳至我的
Github
倉庫//github.com/CNFeffery/PythonPracticalSkills
這是我的系列文章「Python實用秘技」的第4期,本系列立足於筆者日常工作中使用Python
積累的心得體會,每一期為大家帶來一個3分鐘即可學會的簡單小技巧。
作為系列第4期,我們即將學習的是:為pdf文件批量添加文字水印
。

有些情況下我們需要為單個或多個pdf
文件添加文字水印,尤其是那種需要在每一頁按照一定間距鋪滿的文字水印。而藉助reportlab
和pikepdf
這兩個實用的pdf
文件操作庫,我們就可以很方便地實現批量文字水印添加工作。
利用pip install reportlab pikepdf
完成安裝後,我們就可以按照步驟來實現需要的功能:
- 生成指定的文本水印pdf文件
為了向目標pdf
文件添加水印,我們首先需要有單獨的pdf
格式的文本水印文件,我用reportlab
編寫了一個方便易用的函數來生成水印文件,你可以通過注釋來仔細學習其中的步驟,也可以直接調用即可:
from typing import Union, Tuple
from reportlab.lib import units
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
# 註冊字體,這裡的字體是我從windows的字體目錄下複製過來的
pdfmetrics.registerFont(TTFont('msyh', r'./msyh.ttc'))
def create_watermark(content: str,
filename: str,
width: Union[int, float],
height: Union[int, float],
font: str,
fontsize: int,
angle: Union[int, float] = 45,
text_stroke_color_rgb: Tuple[int, int, int] = (0, 0, 0),
text_fill_color_rgb: Tuple[int, int, int] = (0, 0, 0),
text_fill_alpha: Union[int, float] = 1) -> None:
'''
用於生成包含content文字內容的水印pdf文件
content: 水印文本內容
filename: 導出的水印文件名
width: 畫布寬度,單位:mm
height: 畫布高度,單位:mm
font: 對應註冊的字體代號
fontsize: 字型大小大小
angle: 旋轉角度
text_stroke_color_rgb: 文字輪廓rgb色
text_fill_color_rgb: 文字填充rgb色
text_fill_alpha: 文字透明度
'''
# 創建pdf文件,指定文件名及尺寸,這裡以像素單位為例
c = canvas.Canvas(f"{filename}.pdf", pagesize = (width*units.mm, height*units.mm))
# 進行輕微的畫布平移保證文字的完整
c.translate(0.1*width*units.mm, 0.1*height*units.mm)
# 設置旋轉角度
c.rotate(angle)
# 設置字體及字型大小大小
c.setFont(font, fontsize)
# 設置文字輪廓色彩
c.setStrokeColorRGB(*text_stroke_color_rgb)
# 設置文字填充色
c.setFillColorRGB(*text_fill_color_rgb)
# 設置文字填充色透明度
c.setFillAlpha(text_fill_alpha)
# 繪製文字內容
c.drawString(0, 0, content)
# 保存水印pdf文件
c.save()
下面我們就利用這個函數來生成水印文件:
# 製造示例文字水印pdf文件
create_watermark(content='公眾號【Python大數據分析】作者:費弗里',
filename='水印示例',
width=200,
height=200,
font='msyh',
fontsize=35,
text_fill_alpha=0.3)
看看效果,非常的不錯,具體使用時,你可以自己動手調參以找到大小以及片幅都令你滿意的水印導出結果:

- 將水印文件批量覆蓋到目標pdf文件中
搞定了文本水印文件的生成之後,接下來我們就可以把現成的水印文件插入到目標pdf
文件中,這裡我們使用pikepdf
中的相關功能就可以輕鬆實現,我寫了一個簡單的函數,大家在調用時只需要傳入幾個必要參數即可:
from typing import List
from pikepdf import Pdf, Page, Rectangle
def add_watermark(target_pdf_path: str,
watermark_pdf_path: str,
nrow: int,
ncol: int,
skip_pages: List[int] = []) -> None:
'''
向目標pdf文件中添加平鋪水印
target_pdf_path: 目標pdf文件的路徑+文件名
watermark_pdf_path: 水印pdf文件的路徑+文件名
nrow: 水印平鋪的行數
ncol:水印平鋪的列數
skip_pages: 需要跳過不添加水印的頁面序號(從0開始)
'''
# 讀入需要添加水印的pdf文件
target_pdf = Pdf.open(target_pdf_path)
# 讀入水印pdf文件並提取水印頁
watermark_pdf = Pdf.open(watermark_pdf_path)
watermark_page = watermark_pdf.pages[0]
# 遍歷目標pdf文件中的所有頁(排除skip_pages指定的若干頁)
for idx, target_page in enumerate(target_pdf.pages):
if idx not in skip_pages:
for x in range(ncol):
for y in range(nrow):
# 向目標頁指定範圍添加水印
target_page.add_overlay(watermark_page, Rectangle(target_page.trimbox[2] * x / ncol,
target_page.trimbox[3] * y / nrow,
target_page.trimbox[2] * (x + 1) / ncol,
target_page.trimbox[3] * (y + 1) / nrow))
# 將添加完水印後的結果保存為新的pdf
target_pdf.save(target_pdf_path[:-4]+'_已添加水印.pdf')
下面我們直接調用這個函數,對示例文件【吳恩達】機器學習訓練秘籍-中文版.pdf
中除了封面以外的每一頁,按照3行2列的平鋪密度,添加上我們的示例水印:
add_watermark(target_pdf_path='./【吳恩達】機器學習訓練秘籍-中文版.pdf',
watermark_pdf_path='./水印示例.pdf',
nrow=3,
ncol=2,
skip_pages=[0])
效果杠杠的,讀者朋友們可以自己多試試,得到更多心得體會~

本期分享結束,咱們下回見~