如何用Python写给PDF批量添加水印的功能
Admin 2022-09-16 群英技术资讯 323 次浏览
今天,一个做市场的朋友找我咨询PDF加水印的问题,如下图所示:
他有一个Excel文件,文件里面有10000个经销商的名字,他要把价目表PDF发给这些经销商,每个经销商收到的PDF文件上面的水印都是这个经销商自己的名字。
这个需求手动操作肯定要累死人。但是如果用Python来做,就非常简单。代码不超过30行。
要完成这个需求,需要安装两个模块,分别叫做reportlab
和pikepdf
。使用Pip安装就可以了:
python3 -m pip install reportlab pikepdf
然后,需要找到一个.ttf
或者.ttc
格式的中文字体。你可以直接从网上下载中文字体文件。也可以使用系统自带的中文字体。这里以寻找macOS系统默认的宋体为例。
macOS系统字体在/System/Library/Fonts
,宋体对应的.ttc
文件地址是/System/Library/Fonts/Supplemental/Songti.ttc
。对于系统默认的字体,我们只需要知道它的对应的文件名叫做Songti.ttc
就可以了。如果是从网上下载的第三方字体,需要使用绝对路径或者相对于项目代码的相对路径。
由于这位朋友不会使用pandas,那么我们就尽量使用Python原生的方法来获得经销商名字列表。假设经销商信息对应的Excel如下图所示:
我们首先把这个Excel文件导出成csv文件:
然后,我们用Python读取这个csv文件,获得经销商名字列表:
import csv with open('经销商信息.csv') as f: reader = csv.DictReader(f) name_list = [x['经销商名字'] for x in reader] print(name_list)
运行效果如下图所示:
一般来说,我们不能直接把一段文字作为水印添加到另一个PDF文件中。我们只有先把这段文字生成图片或者生成水印PDF文件,然后把这个图片或者水印PDF作为『图层』覆盖到目标PDF上面。
因此,现在需要给每一个经销商生成对应的水印PDF文件。这个PDF中只含有水印文字。效果如下图所示:
对应的代码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('经销商信息.csv') as f: reader = csv.DictReader(f) name_list = [x['经销商名字'] for x in reader] pdfmetrics.registerFont(TTFont('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上面。
使用pikepdf
完成这个工作非常简单,编写一个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 # 每页多少列水印 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个部分,分别是:
这三个部分的代码是可以合并在一个.py
文件里面的,但是我没有这样做,是考虑到问这个问题的同学不是程序员,Python水平只是入门,如果合并在一起,代码量多了以后,出问题都不知道错在哪里。
在计算机领域,所有问题都可以通过把问题拆分成多个部分分别单独运行或者增加若干个中间层来解决。今天用的方法就是把问题拆分的方法。对于初学者来说,每一步都是相对独立的,都能立刻看到效果。第二步只需要依赖第一步的结果,第三步只需要依赖第二步的结果,这样每一步的输入输出非常清楚,可以显著降低问题的复杂度。如果报错了,也更容易知道是哪个地方有问题。
关于“如何用Python写给PDF批量添加水印的功能”的内容今天就到这,感谢各位的阅读,大家可以动手实际看看,对大家加深理解更有帮助哦。如果想了解更多相关内容的文章,关注我们,群英网络小编每天都会为大家更新不同的知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要介绍了通过使用OpenCV进行基于深度学习的对象检测以及使用OpenCV检测视频,文中的示例代码讲解详细,需要的可以参考一下
这篇文章给大家分享的是怎样用python写一个自动生成日历功能的内容。小编觉得挺实用的,因此分享给大家做个参考,接下来一起跟随小编看看吧。
tcp协议的socket是只能和一个客户端通信的,使用socketserver可以实现和多个客户端通信,他是在socket的基础上进行的封装,底层还是调用的socket。
目录题目描述示例 2:示例 3:单向构造(哈希表计数)双向构造(双指针)最后题目描述 这是 LeetCode 上的 1743. 从相邻元素对还原数组 ,难度为 中等。 Tag : 「哈希表」、「双指针」、「模拟」 存在一个由 n 个不同元素组成的整数数组 nums...
分词工具在Python中,会经常使用到,而比较常的分词工具有jieba 分词、pkuseg 分词、FoolNLTK 分词和THULAC,这四种,那么究竟哪个更好用呢?
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008