欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Python如何實(shí)現(xiàn)批量為PDF添加水印

 更新時(shí)間:2022年05月05日 11:21:45   作者:kingname  
我們有時(shí)候需要把一些機(jī)密文件發(fā)給多個(gè)客戶,為了避免客戶泄露文件,會(huì)在機(jī)密文件中添加水印。本文將利用Python實(shí)現(xiàn)批量為PDF添加水印,需要的可以參考一下

我們有時(shí)候需要把一些機(jī)密文件發(fā)給多個(gè)客戶,為了避免客戶泄露文件,會(huì)在機(jī)密文件中添加水印。每個(gè)客戶收到的文件內(nèi)容相同,但是水印都不相同。這樣一來(lái),如果資料泄露了,通過(guò)水印就知道是從誰(shuí)手上泄露的。

今天,一個(gè)做市場(chǎng)的朋友找我咨詢PDF加水印的問(wèn)題,如下圖所示:

圖片

他有一個(gè)Excel文件,文件里面有10000個(gè)經(jīng)銷商的名字,他要把價(jià)目表PDF發(fā)給這些經(jīng)銷商,每個(gè)經(jīng)銷商收到的PDF文件上面的水印都是這個(gè)經(jīng)銷商自己的名字。

這個(gè)需求手動(dòng)操作肯定要累死人。但是如果用Python來(lái)做,就非常簡(jiǎn)單。代碼不超過(guò)30行。

準(zhǔn)備環(huán)境

要完成這個(gè)需求,需要安裝兩個(gè)模塊,分別叫做reportlabpikepdf。使用Pip安裝就可以了:

python3?-m?pip?install?reportlab?pikepdf

然后,需要找到一個(gè).ttf或者.ttc格式的中文字體。你可以直接從網(wǎng)上下載中文字體文件。也可以使用系統(tǒng)自帶的中文字體。這里以尋找macOS系統(tǒng)默認(rèn)的宋體為例。

macOS系統(tǒng)字體在/System/Library/Fonts,宋體對(duì)應(yīng)的.ttc文件地址是/System/Library/Fonts/Supplemental/Songti.ttc。對(duì)于系統(tǒng)默認(rèn)的字體,我們只需要知道它的對(duì)應(yīng)的文件名叫做Songti.ttc就可以了。如果是從網(wǎng)上下載的第三方字體,需要使用絕對(duì)路徑或者相對(duì)于項(xiàng)目代碼的相對(duì)路徑。

獲得經(jīng)銷商名字對(duì)應(yīng)的列表

由于這位朋友不會(huì)使用pandas,那么我們就盡量使用Python原生的方法來(lái)獲得經(jīng)銷商名字列表。假設(shè)經(jīng)銷商信息對(duì)應(yīng)的Excel如下圖所示:

圖片

我們首先把這個(gè)Excel文件導(dǎo)出成csv文件:

圖片

然后,我們用Python讀取這個(gè)csv文件,獲得經(jīng)銷商名字列表:

import?csv
with?open('經(jīng)銷商信息.csv')?as?f:
????reader?=?csv.DictReader(f)
????name_list?=?[x['經(jīng)銷商名字']?for?x?in?reader]

print(name_list)

運(yùn)行效果如下圖所示:

生成水印PDF

一般來(lái)說(shuō),我們不能直接把一段文字作為水印添加到另一個(gè)PDF文件中。我們只有先把這段文字生成圖片或者生成水印PDF文件,然后把這個(gè)圖片或者水印PDF作為『圖層』覆蓋到目標(biāo)PDF上面。

因此,現(xiàn)在需要給每一個(gè)經(jīng)銷商生成對(duì)應(yīng)的水印PDF文件。這個(gè)PDF中只含有水印文字。效果如下圖所示:

圖片

對(duì)應(yīng)的代碼create_watermark.py如下:

import?csv
from?pathlib?import?Path
from?reportlab.lib?import?units
from?reportlab.pdfgen?import?canvas
from?reportlab.pdfbase?import?pdfmetrics
from?reportlab.pdfbase.ttfonts?import?TTFont


with?open('經(jīng)銷商信息.csv')?as?f:
????reader?=?csv.DictReader(f)
????name_list?=?[x['經(jīng)銷商名字']?for?x?in?reader]

pdfmetrics.registerFont(TTFont('Songti',?'Songti.ttc'))?#?加載中文字體

water_mark_folder?=?Path('water_pdf')?#?用一個(gè)文件夾存放所有的水印PDF
water_mark_folder.mkdir(exist_ok=True)

for?name?in?name_list:
????path?=?str(water_mark_folder?/?Path(f'{name}.pdf'))
????c?=?canvas.Canvas(path,?pagesize=(200?*?units.mm,?200?*?units.mm))?#?生成畫布,長(zhǎng)寬都是200毫米
????c.translate(0.1?*?200?*?units.mm,?0.1?*?200?*?units.mm)??
????c.rotate(45)??#?把水印文字旋轉(zhuǎn)45°
????c.setFont('Songti',?35)??#?字體大小
????c.setStrokeColorRGB(0,?0,?0)??#?設(shè)置字體顏色
????c.setFillColorRGB(0,?0,?0)??#?設(shè)置填充顏色
????c.setFillAlpha(0.3)??#?設(shè)置透明度,越小越透明
????c.drawString(0,?0,?f'{name}專用價(jià)目表,嚴(yán)禁泄露!')
????c.save()

代碼的具體作用,已經(jīng)寫到注釋中了。運(yùn)行以后會(huì)在當(dāng)前項(xiàng)目根目錄生成water_pdf文件夾,里面就是生成的水印PDF。

合并水印與目標(biāo)PDF

最后一步,把每一個(gè)經(jīng)銷商的水印PDF與目標(biāo)PDF進(jìn)行合并。水印PDF作為一個(gè)圖層覆蓋到目標(biāo)PDF上面。

使用pikepdf完成這個(gè)工作非常簡(jiǎn)單,編寫一個(gè)combine.py文件,代碼如下:

import?glob
from?pathlib?import?Path
from?pikepdf?import?Pdf,?Page,?Rectangle


water_pdf_list?=?glob.glob('water_pdf/*.pdf')
result?=?Path('result')
result.mkdir(exist_ok=True)

col?=?2??#?每頁(yè)多少列水印
row?=?3??#?每頁(yè)多少行水印

for?path?in?water_pdf_list:
????target?=?Pdf.open('./PythonisinstanceGolang.pdf')??#?必須每次重新打開PDF,因?yàn)樘砑铀∈莍nplace的操作
????file?=?Path(path)
????name?=?file.stem
????water_mark_pdf?=?Pdf.open(path)
????water_mark?=?water_mark_pdf.pages[0]

????for?page?in?target.pages:
????????for?x?in?range(col):??#?每一行顯示多少列水印
????????????for?y?in?range(row):?#?每一頁(yè)顯示多少行PDF
????????????????page.add_overlay(water_mark,
?????????????????????????????????Rectangle(page.trimbox[2]?*?x?/?col,
???????????????????????????????????????????page.trimbox[3]?*?y?/?row,
???????????????????????????????????????????page.trimbox[2]?*?(x?+?1)?/?col,
???????????????????????????????????????????page.trimbox[3]?*?(y?+?1)?/?row))

????result_name?=?Path('result',?f'{name}_添加水印.pdf')
????target.save(str(result_name))

運(yùn)行以后,會(huì)在項(xiàng)目根目錄生成一個(gè)result文件夾,里面就是添加了水印的PDF文件了,如下圖所示:

圖片

這里有必要對(duì)代碼中的一些地方進(jìn)行解釋。帶上行號(hào)的代碼如下圖所示:

圖片

代碼第21行和22行,有兩個(gè)for循環(huán),他們的作用是給一個(gè)頁(yè)面上添加多個(gè)水印。請(qǐng)大家注意下圖我畫圈的地方:

圖片

每一頁(yè)都有6個(gè)水印,分成3行2列。其中的3行對(duì)應(yīng)了變量row的值。2列對(duì)應(yīng)了變量col的值。大家也可以根據(jù)自己的需要修改這兩個(gè)數(shù)字。甚至每一頁(yè)的水印隨機(jī)變換位置,防止被去水印的程序移除。

page.trimbox[2]是PDF頁(yè)面的寬度,page.trimbox[3]是PDF頁(yè)面的高度。

總結(jié)

大家注意在這篇文章中,我把任務(wù)分成了3個(gè)部分,分別是:

  • Excel轉(zhuǎn)CSV,讓Python方便讀取
  • Python讀取CSV生成水印PDF
  • 水印PDF與目標(biāo)PDF文件合并

這三個(gè)部分的代碼是可以合并在一個(gè).py文件里面的,但是我沒有這樣做,是考慮到問(wèn)這個(gè)問(wèn)題的同學(xué)不是程序員,Python水平只是入門,如果合并在一起,代碼量多了以后,出問(wèn)題都不知道錯(cuò)在哪里。

在計(jì)算機(jī)領(lǐng)域,所有問(wèn)題都可以通過(guò)把問(wèn)題拆分成多個(gè)部分分別單獨(dú)運(yùn)行或者增加若干個(gè)中間層來(lái)解決。今天用的方法就是把問(wèn)題拆分的方法。對(duì)于初學(xué)者來(lái)說(shuō),每一步都是相對(duì)獨(dú)立的,都能立刻看到效果。第二步只需要依賴第一步的結(jié)果,第三步只需要依賴第二步的結(jié)果,這樣每一步的輸入輸出非常清楚,可以顯著降低問(wèn)題的復(fù)雜度。如果報(bào)錯(cuò)了,也更容易知道是哪個(gè)地方有問(wèn)題。

到此這篇關(guān)于詳解Python如何實(shí)現(xiàn)批量為PDF添加水印的文章就介紹到這了,更多相關(guān)Python PDF添加水印內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • python如何實(shí)現(xiàn)遞歸轉(zhuǎn)非遞歸

    python如何實(shí)現(xiàn)遞歸轉(zhuǎn)非遞歸

    這篇文章主要介紹了python如何實(shí)現(xiàn)遞歸轉(zhuǎn)非遞歸,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-02-02
  • python機(jī)器學(xué)習(xí)基礎(chǔ)線性回歸與嶺回歸算法詳解

    python機(jī)器學(xué)習(xí)基礎(chǔ)線性回歸與嶺回歸算法詳解

    這篇文章主要為大家介紹了python機(jī)器學(xué)習(xí)基礎(chǔ)線性回歸與嶺回歸算法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • Pygame游戲開發(fā)之太空射擊實(shí)戰(zhàn)盾牌篇

    Pygame游戲開發(fā)之太空射擊實(shí)戰(zhàn)盾牌篇

    相信大多數(shù)8090后都玩過(guò)太空射擊游戲,在過(guò)去游戲不多的年代太空射擊自然屬于經(jīng)典好玩的一款了,今天我們來(lái)自己動(dòng)手實(shí)現(xiàn)它,在編寫學(xué)習(xí)中回顧過(guò)往展望未來(lái),在本課中,我們將為玩家添加一個(gè)盾牌以及一個(gè)用于顯示盾牌等級(jí)的欄
    2022-08-08
  • python圖像和辦公文檔處理總結(jié)

    python圖像和辦公文檔處理總結(jié)

    在本文里我們給大家整理了關(guān)于python圖像和辦公文檔處理的相關(guān)知識(shí)點(diǎn)內(nèi)容以及重點(diǎn)內(nèi)容總結(jié),有需要的朋友們跟著學(xué)習(xí)下。
    2019-05-05
  • Python基于socket實(shí)現(xiàn)TCP/IP客戶和服務(wù)器通信

    Python基于socket實(shí)現(xiàn)TCP/IP客戶和服務(wù)器通信

    本主要介紹了Python socket網(wǎng)絡(luò)編程TCP/IP服務(wù)器與客戶端通信的相關(guān)資料,這里對(duì)Scoket 進(jìn)行詳解并創(chuàng)建TCP服務(wù)器及TCP 客戶端實(shí)例代碼,需要的朋友可以參考下
    2021-06-06
  • python通過(guò)BF算法實(shí)現(xiàn)關(guān)鍵詞匹配的方法

    python通過(guò)BF算法實(shí)現(xiàn)關(guān)鍵詞匹配的方法

    這篇文章主要介紹了python通過(guò)BF算法實(shí)現(xiàn)關(guān)鍵詞匹配的方法,實(shí)例分析了BF算法的原理與Python實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • 總結(jié)python多進(jìn)程multiprocessing的相關(guān)知識(shí)

    總結(jié)python多進(jìn)程multiprocessing的相關(guān)知識(shí)

    今天給大家?guī)?lái)的是關(guān)于Python的相關(guān)知識(shí),文章圍繞著python multiprocessing多進(jìn)程的相關(guān)知識(shí)展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Python基于pyjnius庫(kù)實(shí)現(xiàn)訪問(wèn)java類

    Python基于pyjnius庫(kù)實(shí)現(xiàn)訪問(wèn)java類

    這篇文章主要介紹了Python基于pyjnius庫(kù)實(shí)現(xiàn)訪問(wèn)java類,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Python?matplotlib?seaborn繪圖教程詳解

    Python?matplotlib?seaborn繪圖教程詳解

    Seaborn是在matplotlib的基礎(chǔ)上進(jìn)行了更高級(jí)的API封裝,從而使得作圖更加容易,在大多數(shù)情況下使用seaborn就能做出很具有吸引力的圖。本文將詳細(xì)講解如何利用Seaborn繪制圖表,需要的可以參考一下
    2022-03-03
  • 基于PyQt5制作一個(gè)數(shù)據(jù)圖表生成器

    基于PyQt5制作一個(gè)數(shù)據(jù)圖表生成器

    這篇文章主要介紹了如何利用PyQT5制作一個(gè)數(shù)據(jù)圖表生成器,可以通過(guò)Pyecharts模塊生成可視化的html數(shù)據(jù)圖表,感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下
    2022-02-02

最新評(píng)論