如何给pdf文件批量添加水印,python批量打印pdf文件
有时我们需要向多个客户发送一些机密文档。为了防止客户泄露文档,我们会在机密文档中添加水印。本文将使用Python对PDF进行批量水印,有需要的可以参考。
00-1010准备环境获取经销商名称对应的列表,生成水印PDF,将水印与目标PDF摘要合并。有时,我们需要将一些机密文件发送给多个客户。为了防止客户泄露文件,我们将在机密文件中添加水印。每个客户都收到相同的文件内容,但水印是不同的。这样,如果信息泄露,通过水印你就知道是从谁手里泄露的。
今天市场上有个朋友问我关于给PDF加水印的问题,如下图:
他有一个Excel文件,里面有一万个经销商的名字。他想将价格表PDF发送给这些经销商。每个经销商收到的PDF文件上的水印都是经销商自己的名字。
这种手工操作一定很累人。但是如果用Python来做,就很简单了。不超过30行代码。
目录
为了满足这个需求,您需要安装两个模块,即reportlab和pikepdf。用Pip安装即可:
python 3-mpipinstallreportlabpikedf
然后,你需要在。ttf或者。ttc格式。你可以直接从网上下载中文字体文件。也可以使用系统自带的中文字体。以寻找macOS系统默认的歌曲风格为例。
MacOS系统字体在/System/Library/Fonts中,对应的。ttc文件地址为/system/library/fonts/supplemental/songti.ttc,对于系统默认字体,我们只需要知道其对应的文件名为song ti . TTC如果是从网上下载的第三方字体,则需要使用绝对路径或者相对于项目代码的相对路径。
准备环境
既然这位朋友不会用熊猫,那么我们就尝试用Python的原生方法来获取经销商名称列表。假设经销商信息对应的Excel如下图所示:
首先,我们将这个Excel文件导出为csv文件:
然后,我们读取Python中的这个csv文件,以获得经销商名称列表:
importcsv
带有open(经销商信息. csv) ASF :
读者=csv。字典阅读器
Name_list=[x[经销商名称]forxinreader]
打印(姓名列表)
运行效果如下图所示:
获得经销商名字对应的列表
一般来说,我们不能直接将一段文字作为水印添加到另一个PDF文件中。我们只能先从这个文本生成一个图片或者水印PDF文件,然后把这个图片或者水印PDF作为一个“图层”叠加在目标PDF上。
因此,现在需要为每个发行商生成相应的水印PDF文件。此PDF仅包含水印文本。效果如下图所示:
相应的代码create_watermark.py如下:
importcsv
frompathlibimportPath
fromreportlab.libimportunits
fromreportlab . pdfgenimportcanvas
fromreportlab . pdfbaseimportpdfmetrics
from reportlab . pdf base . ttfontsimportttfont
带有open(经销商信息. csv) ASF :
读者=csv。字典阅读器
Name_list=[x[经销商名称]forxinreader]
pdfmetrics.registerFont(TT
Font(Songti, Songti.ttc)) # 加载中文字体
water_mark_folder = Path(water_pdf) # 用一个文件夹存放所有的水印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)) # 生成画布,长宽都是200毫米
c.translate(0.1 * 200 * units.mm, 0.1 * 200 * units.mm)
c.rotate(45) # 把水印文字旋转45°
c.setFont(Songti, 35) # 字体大小
c.setStrokeColorRGB(0, 0, 0) # 设置字体颜色
c.setFillColorRGB(0, 0, 0) # 设置填充颜色
c.setFillAlpha(0.3) # 设置透明度,越小越透明
c.drawString(0, 0, f{name}专用价目表,严禁泄露!)
c.save()
代码的具体作用,已经写到注释中了。运行以后会在当前项目根目录生成water_pdf
文件夹,里面就是生成的水印PDF。
合并水印与目标PDF
最后一步,把每一个经销商的水印PDF与目标PDF进行合并。水印PDF作为一个图层覆盖到目标PDF上面。
使用pikepdf
完成这个工作非常简单,编写一个combine.py文件,代码如下:
import globfrom 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 # 每页多少列水印
row = 3 # 每页多少行水印
for path in water_pdf_list:
target = Pdf.open(./PythonisinstanceGolang.pdf) # 必须每次重新打开PDF,因为添加水印是inplace的操作
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): # 每一页显示多少行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))
运行以后,会在项目根目录生成一个result
文件夹,里面就是添加了水印的PDF文件了,如下图所示:
这里有必要对代码中的一些地方进行解释。带上行号的代码如下图所示:
代码第21行和22行,有两个for
循环,他们的作用是给一个页面上添加多个水印。请大家注意下图我画圈的地方:
每一页都有6个水印,分成3行2列。其中的3行对应了变量row
的值。2列对应了变量col的值。大家也可以根据自己的需要修改这两个数字。甚至每一页的水印随机变换位置,防止被去水印的程序移除。
page.trimbox[2]
是PDF页面的宽度,page.trimbox[3]
是PDF页面的高度。
总结
大家注意在这篇文章中,我把任务分成了3个部分,分别是:
- Excel转CSV,让Python方便读取
- Python读取CSV生成水印PDF
- 水印PDF与目标PDF文件合并
这三个部分的代码是可以合并在一个.py
文件里面的,但是我没有这样做,是考虑到问这个问题的同学不是程序员,Python水平只是入门,如果合并在一起,代码量多了以后,出问题都不知道错在哪里。
在计算机领域,所有问题都可以通过把问题拆分成多个部分分别单独运行或者增加若干个中间层来解决。今天用的方法就是把问题拆分的方法。对于初学者来说,每一步都是相对独立的,都能立刻看到效果。第二步只需要依赖第一步的结果,第三步只需要依赖第二步的结果,这样每一步的输入输出非常清楚,可以显著降低问题的复杂度。如果报错了,也更容易知道是哪个地方有问题。
到此这篇关于详解Python如何实现批量为PDF添加水印的文章就介绍到这了,更多相关Python PDF添加水印内容请搜索盛行IT软件开发工作室以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT软件开发工作室!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。