「Python實用秘技04」pdf文件批量添加文字水印

添加微信號"CNFeffery"加入技術交流群
?本文完整示例代碼及文件已上傳至我的
?Github倉庫https://github.com/CNFeffery/PythonPracticalSkills
這是我的系列文章「Python實用秘技」的第4期,本系列立足于筆者日常工作中使用Python積累的心得體會,每一期為大家?guī)硪粋€3分鐘即可學會的簡單小技巧。
作為系列第4期,我們即將學習的是:為pdf文件批量添加文字水印。

有些情況下我們需要為單個或多個pdf文件添加文字水印,尤其是那種需要在每一頁按照一定間距鋪滿的文字水印。而借助reportlab和pikepdf這兩個實用的pdf文件操作庫,我們就可以很方便地實現(xiàn)批量文字水印添加工作。
利用pip install reportlab pikepdf完成安裝后,我們就可以按照步驟來實現(xiàn)需要的功能:
生成指定的文本水印pdf文件
為了向目標pdf文件添加水印,我們首先需要有單獨的pdf格式的文本水印文件,我用reportlab編寫了一個方便易用的函數(shù)來生成水印文件,你可以通過注釋來仔細學習其中的步驟,也可以直接調用即可:
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:?文字透明度
????'''
????#?創(chuàng)建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()
下面我們就利用這個函數(shù)來生成水印文件:
#?制造示例文字水印pdf文件
create_watermark(content='公眾號【Python大數(shù)據(jù)分析】作者:費弗里',?
?????????????????filename='水印示例',?
?????????????????width=200,
?????????????????height=200,?
?????????????????font='msyh',?
?????????????????fontsize=35,
?????????????????text_fill_alpha=0.3)
看看效果,非常的不錯,具體使用時,你可以自己動手調參以找到大小以及畫幅都令你滿意的水印導出結果:

將水印文件批量覆蓋到目標pdf文件中
搞定了文本水印文件的生成之后,接下來我們就可以把現(xiàn)成的水印文件插入到目標pdf文件中,這里我們使用pikepdf中的相關功能就可以輕松實現(xiàn),我寫了一個簡單的函數(shù),大家在調用時只需要傳入幾個必要參數(shù)即可:
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:?水印平鋪的行數(shù)
??? ncol:水印平鋪的列數(shù)
????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')
下面我們直接調用這個函數(shù),對示例文件【吳恩達】機器學習訓練秘籍-中文版.pdf中除了封面以外的每一頁,按照3行2列的平鋪密度,添加上我們的示例水印:
add_watermark(target_pdf_path='./【吳恩達】機器學習訓練秘籍-中文版.pdf',
??????????????watermark_pdf_path='./水印示例.pdf',
??????????????nrow=3,
??????????????ncol=2,
??????????????skip_pages=[0])
效果杠杠的,讀者朋友們可以自己多試試,得到更多心得體會~

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

加入知識星球【我們談論數(shù)據(jù)科學】
400+小伙伴一起學習!
· 推薦閱讀?·
聊聊我常用的5款動態(tài)數(shù)據(jù)可視化工具
