社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

使用Python为PDF文件批量添加水印的方法及进一步思考

Python小屋 • 5 年前 • 781 次点击  

感谢中国传媒大学胡凤国老师的分享!

============

问题描述:

想用Python把WORD文件转成PDF文件并加上水印。网上搜了一下资料,没发现有现成的解决方案。于是决定自己写一个Python程序。思路是分两步:第一步,将WORD文件转成PDF,第二步将生成的PDF文件添加水印。但是做的过程中出现了一些问题,解决的过程对我来说又十分困难,这里把我的思路、方法和经验教训总结一下,分享给需要的朋友。

系统环境:

32位Win7 + Python 3.6.4 + Office2010。

材料准备:

1、网上下载《千字文》全文,放入WORD文件中,每页25行,每行5列,每列4字,设定大小合适以填满两页,保存为“test.docx”。

2、另准备一个用来充当水印的图片“water.jpg”,用其他方法把它变成一个图案半透明的PDF文件“water.pdf”。

3、用WPS加载“test.docx”导出的PDF文件“testwps.pdf”。

4、用Acrobat加载WORD2010做成的“testword2010.pdf”导出的图片,保存目录是“testacrobat”。


第一步:将“test.docx”变成“testword2010.pdf”。

为适应批处理需要,这里不考虑手动用WORD2010另存为的办法得到PDF文件。

这一步,参考网上资料,直接写出Python程序word2pdf.py:


第二步:为PDF文件加水印

将“testword2010.pdf”变成“rword2010.pdf”。网上资料也很多,思路是使用PyPDF2扩展包,参考网址http://www.blog.pythonlibrary.org/2018/06/07/an-intro-to-pypdf2/给出的代码,写出Python程序addwatermark1.py:

运行程序发现出错。出错信息如下:
Traceback (most recent call last):
  File "C:\Python364\lib\site-packages\PyPDF2\generic.py", line 484, in readFromStream
    return NameObject(name.decode('utf-8'))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcb in position 8: invalid continuation byte

During handling of the above exception, another exception occurred:

这后面还跟着数十行出错信息。生成的PDF文件“rword2010.pdf”自然是打不开的。网上搜一圈,发现没有相关帖子。看来我这是小众问题,小概率事件发生在我身上,我怎么这么幸运呢?强忍住到世界杯去赌球的冲动,继续思考我的问题的解决办法。

第三步:寻求问题的原因

首先,我看出错信息有“decode('utf-8')”之类的字样,难道是PyPDF2不支持中文?

于是我又做了一个纯英文的WORD文件,用WORD2010手动导出成PDF,加水印也是失败的。这就排除了编码的问题,看来这个问题PDF文件是不是中文内容关系不是太大。

仍然是上网狂搜,变换各种关键词狂搜。终于搜到一篇相关的
https://blog.csdn.net/Li_Jiaqian/article/details/80299026
该帖子想用程序合并PDF文件,遇到跟本文一样的错误,贴文的作者说原来的pdf是1.5版本,合并出错。他将pdf转化为word,再在wps中将word输出为pdf,这时的pdf是1.7版本,合并就不再报错。
于是用WPS文字打开“test.docx”,用菜单“输出为PDF”生成PDF文件“testwps.pdf”,用上面的代码(当然得改一下文件名)加水印,成功。
用的WPS文字的版本是“WPS 文字 10.1.0.7400”,20180629官网下载。

到目前为止,我也怀疑这事儿跟所谓的PDF版本有关,但查不到相关资料,不知道word2010和wps文字导出的PDF到底是哪个版本的PDF。或许从这里突破还真有希望找到为PDF加水印的简单办法,但目前没太多精力,无奈放下,继续寻找为PDF加水印的成功办法。

于是继续上网搜,另外一个网友在贴子https://blog.csdn.net/Leafage_M/article/details/79705731里面提到一个奇怪的思路:

pdf = PdfFileReader(input_pdf)

改为

pdf = PdfFileReader(input_pdf, strict=False)

我按照这个思路去修改代码,程序运行不报错了,会在输出警告信息后生成“rword2010.pdf”,警告信息如下:

PdfReadWarning: Illegal character in Name Object [generic.py:489]

随后查看这个加水印后的PDF文件,发现只能看见水印,完全看不到中文内容。又做了一下英文PDF的实验,发现水印有,看不到英文内容。

现在,问题原因找到了:我们用PyPDF2扩展包为PDF文件添加水印之所以失败,是因为PDF是通过WORD2010将WORD文件转换来的。

那么,问题似乎解决了,用WPS文字把WORD文件做成PDF文件似乎是个好办法,然后再用我们第二步的代码就能为WPS生成的PDF文件加水印。但为现存的PDF文件加水印的问题还没有解决,因为我们的现存PDF文件总有很多是用WORD2010做成的。所以,还得继续寻找为PDF文件加水印的办法。

第四步:探求PDF加水印的通用办法

看来Python的扩展包PyPDF2的添加水印功能还是有很大缺点的,在它自身的版本升级之前,是不能考虑它了。本着吃不成鱼肉吃猪肉也行的原则,我们坚决抛开PyPDF2,另觅它途。既然一步到位不了,我们可以继续把整个任务分成两个子任务:

任务一:将PDF文件拆成图片,一页PDF文件变成一张图片。

任务二:将一张张的图片加上水印合并成PDF。

这两步似乎都不难。现分别实现之。


任务一:将PDF文件拆成图片

这个任务需要用到PyPDF2、PythonMagick和ghostscript三个扩展包,这里使用PyPDF2的其它功能。参考资料是

https://blog.csdn.net/sqlserverdiscovery/article/details/51425543

废话少说,直接上代码,函数如下:

任务二:将图片加上水印合并成PDF

这一个任务主要是用扩展包reportlab。代码也很简单,直接给出函数:

有了这两个函数,我们就好办了。将源PDF文件转成图片保存到中间目录,然后将中间目录的图片加上水印合并成目标PDF文件,最后删掉中间目录。调用函数的代码如下:

运行一下,一切OK。

结语

虽然实现了为PDF文件添加水印的通用算法,为批量将WORD文件直接转换为带水印的PDF文件扫清了障碍。但是,还存在着如下的问题

第一、用本文的办法生成的图片质量不是太高,如果不删除中间结果目录的话,我们会看到,程序自动生成的图片远不如用Acrobat手动打开“testword2010.pdf”用菜单导出的图片清楚。所以,如何自动从PDF文件导出质量更高的图片,值得进一步研究。为了对比,本文在研究过程中将Acrobat导出的图片保存在“testacrobat”目录,用如下语句生成加水印的PDF文件:my_create_pdf_from_pictures_and_add_watermark("testacrobat", "r.pdf", waterfn)

第二、不相信PyPDF2的开发者比我们笨,所以说不定PyPDF2还有一些隐藏功能我们没发掘出来,因此寻求PyPDF2为PDF文件添加水印的完美解决办法还是有希望的。

第三、本文的思路和算法可能存在缺点和不足,请广大朋友批评指正。希望抛砖引玉,能找到更好的PDF添加水印的办法。

致谢

特别感谢Python界的大咖董付国老师,作为Python的小白,我在用Python处理WORD、PDF和图片的过程中得到董老师很多帮助。
也感谢我参考资料里面列出网址的帖子的楼主,他们给了我启发。

测试文件与代码下载地址:

链接: https://pan.baidu.com/s/1967jzOb3hFi-e5zSoboQwQ 密码: c8hw


中国传媒大学,胡凤国,2018年6月30日




---------董付国老师Python系列教材--------

1)《Python程序设计(第2版)》(2018年5月第6次印刷)

出版社官方链接(亚马逊、京东、当当均有销售):https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-16232114860.18.24a52226hIi8Bj&id=534581929248&rn=9311dcbc68fffcf57b7ae352800e485d&abbucket=6

2)《Python可以这样学》(2018年2月第5次印刷)(本书已发行繁体版)

出版社官方链接(亚马逊、京东、当当均有销售):https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-16232114860.16.24a52226hIi8Bj&id=544817105410&rn=9311dcbc68fffcf57b7ae352800e485d&abbucket=6

3)《Python程序设计基础(第2版)(2018年5月第2次印刷)

出版社官方链接(亚马逊、京东、当当均有销售):https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-16232114860.24.24a52226hIi8Bj&id=565581275846&rn=9311dcbc68fffcf57b7ae352800e485d&abbucket=6

4)《中学生可以这样学Python》2018年5月第2次印刷)

出版社官方链接(亚马逊、京东、当当均有销售):https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-16232114860.20.24a52226hIi8Bj&id=560808221053&rn=9311dcbc68fffcf57b7ae352800e485d&abbucket=6

5)《Python程序设计开发宝典》(2018年2月第3次印刷)

出版社官方链接(亚马逊、京东、当当均有销售):https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-16232114860.52.24a52226hIi8Bj&id=556093887133&rn=9311dcbc68fffcf57b7ae352800e485d&abbucket=6

6)《玩转Python轻松过二级》(2018年5月隆重上架)

出版社官方链接(亚马逊、京东、当当均有销售):https://detail.tmall.com/item.htm?spm=a1z10.3-b-s.w4011-16232114860.84.24a52226hIi8Bj&id=569250004069&rn=9311dcbc68fffcf57b7ae352800e485d&abbucket=6


董付国老师6本Python系列图书阅读指南

董付国老师6本Python系列教材被北大、复旦等近百所高校选作教材

热烈庆祝《Python可以这样学》在台湾发行繁体版


董老师127课免费视频地址: https://pan.baidu.com/s/1jJeAs8Q 密码: px59


----------相关阅读----------

教学课件

1900页Python系列PPT分享一:基础知识(106页)

1900页Python系列PPT分享二:Python序列(列表、元组、字典、集合)(154页)

1900页Python系列PPT分享三:选择与循环结构语法及案例(96页)

1900页Python系列PPT分享四:字符串与正则表达式(109页)

1900页Python系列PPT分享五:函数设计与应用(134页)

1900页Python系列PPT分享六:面向对象程序设计(86页)

1900页Python系列PPT分享七:文件操作(132页)

1900页Python系列PPT分享八:异常处理结构与程序调试、测试(70页)

报告PPT(163页):基于Python语言的课程群建设探讨与实践

非计算机专业《Python程序设计基础》教学参考大纲

计算机相关专业“Python程序设计”教学大纲(参考)

报告PPT(123页):Python编程基础精要

《Python程序设计》实验指导书(30个实验)


系列题库分享

1000道Python题库系列分享一(17道)

1000道Python题库系列分享二(48道)

1000道Python题库系列分享三(30道)

1000道Python题库系列分享四(40道)

1000道Python题库系列分享五(40道)

1000道Python题库系列分享六(40道)

1000道Python题库系列分享七(30道)

1000道Python题库系列分享八(29道)

1000道Python题库系列分享九(31道)

1000道Python题库系列分享十(37道)

1000道Python题库系列分享十一(9道)


相关阅读

Python+pywin32批量转换Word文件为PDF文件

Python批量提取PDF文件中的文本

Python查找Word文件中红色和加粗的文字(附元宵节送书活动中奖名单)

使用Python写入docx文件并控制字体颜色

Python批量提取Word文件题库中的答案

Python操作docx文档设置居中并创建表格

Python把docx文档中的题库导入SQLite数据库

Python提取docx文档中例题、插图、表格清单


今天看啥 - 高品质阅读平台
本文地址:http://www.jintiankansha.me/t/h6TJ37UqQS
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/19642
 
781 次点击