【Python实战】生成图片式不可复制的pdf文件

ocean-3605547_1920.jpg

郑老师经常要整理一些文档资料发给学生学习,资料都是郑老师辛辛苦苦整理的,也不希望被滥用,所以,每次发给学生的时候又是加水印,又是转pdf,又是加密,又是希望文本内容不可复制。

以前,都是找各种软件手动点点点弄完的。但是,一旦文档多了,这种手动点点点就显得有些低效了。

借着这次整理的资料,实现了上述需求的代码化,以后多少文档都可以批量实现了。

具体来说,在我的熏陶下,郑老师养成了用excel整理资料的习惯,知道给不同信息内容添加字段来归类整理。这样的话,总结这次的整理需求就是:

  1. 将excel的内容转成带有水印的word;
  2. 将word转为pdf;
  3. 将可编辑的pdf转为图片式不可复制的pdf;
  4. 给pdf加密;

代码参考来源:
python-docx 0.8.10 文档:osgeo.cn/python-docx/

python自动化办公——python操做Excel、Word、PDF集合大全:shangmayuan.com/a/9b82fb31500e473f83f46372.html#jump51

【Python】pdf2image模块+poppler将PDF转换为图片:blog.csdn.net/sinat_37967865/article/details/102477235

使用Python把Word文档转换为图片式不可修改的PDF文件:sohu.com/a/363087337_797291

1. 将excel内容转成带有水印的word

这个其实挺好实现的,用到pandaspython-docx包。

python-docx可以新建文档,也可以打开已有文档,并写入或者修改内容(不能是空文档)

所以,可以先新建个word文档(如下的muban.docx),把页码啊,水印啊,标题样式啊,一些格式上的问题先设置好,然后,只需要向这个文档写入excel数据就行。

以其中一个文档为例:

import pandas as pd    
from docx import Document
from docx.shared import Inches

# 读取excel
T2 = pd.read_excel('自己的文档.xlsx', sheet_name = 'Task2')

# Task2.docx
# 读取模板muban文档
document = Document('muban.docx')
# 添加标题
document.add_heading('口语Taks2阅读及听力文稿',0)
# 按行读取excel内容
for n,i in T2.iterrows():
    source = i['来源'].replace('TPO','套题')
    rtitle = '阅读文稿'
    reading = i['阅读']
    ltitle = '听力文稿'
    listening = i['听力文稿']
    # 删除文本中的空行
    lls = listening.split('\n')
    while '' in lls:
        lls.remove('')
    while ' ' in lls:
        lls.remove(' ')
    listening = '\n'.join(lls)
    
    # 添加一级标题
    document.add_heading(source, level = 1)
    # 添加二级标题
    document.add_heading(rtitle, level = 2)
    # 添加文本
    reading = document.add_paragraph(reading)
    # 添加二级标题
    document.add_heading(ltitle, level = 2)
    # 添加文本
    document.add_paragraph(listening)
    # 除了最后一页,新建一页
    if n >= 0 and n <= 69:
        document.add_page_break()
# 保存文档
document.save('Task2.docx')

最后生成文档如下图所示:

excel2word.png

2. 将word转为pdf

将word转为pdf就很好解决了,安装个包docx2pdf就行~

from docx2pdf import convert

# word转pdf
convert("Task2.docx")

3. 将可编辑的pdf转为图片式不可复制的pdf

这个步骤就稍微复杂一些,好在前人栽树,后人乘凉,改改别人的代码就行。

主要就是先把pdf文件按照每页一张,拆分成图片;然后,将这些图片又合并为1个pdf文件就行。

这里涉及到需要下载并安装配置poppler,可以参考:blog.csdn.net/sinat_37967865/article/details/102477235

from PyPDF2 import PdfFileReader, PdfFileWriter, PdfFileMerger
from os import remove, listdir, mkdir
from os.path import join, isdir, split, splitext, basename
from reportlab.lib.pagesizes import A4, landscape, portrait
from reportlab.pdfgen import canvas
from pdf2image import convert_from_path
from win32com.client import constants, gencache

# 把pdf文件拆成jpg图片,每页一张
def pdf2jpgs(file):
    # 路径和文件名
    dstDir, pdfFn = split(file)
    # 当前目录
    if not dstDir:
        dstDir = pdfFn[:-4]
    else:
        dstDir = join(dstDir, pdfFn[:-4])
    # 创建同名文件夹
    if not isdir(dstDir):
        mkdir(dstDir)
    # 转换图片,图片像素dpi为480
    images = convert_from_path(pdfFn, dpi = 480, fmt = 'JPEG', 
        thread_count = 4,
        poppler_path = r'D:\path\poppler0680\bin') 
    # 保存图片
    for index, image in enumerate(images):
        print(index,'已经保存')
        image.save('{}\{}.jpg'.format(dstDir,index))

# 把jpg图片合并为pdf文件
def merge_jpg2pdf(jpgpath):
    # 要合并的图片
    jpg_files = [join(jpgpath, fn) for fn in listdir(jpgpath)
                    if fn.endswith('.jpg')]
    jpg_files.sort(key = lambda fn: int(splitext(basename(fn))[0]))
    result_pdf = PdfFileMerger()
    # 临时文件
    temp_pdf = 'temp.pdf'

    # 依次转pdf,再合并pdf
    for fn in jpg_files:
        # 转pdf,portrait纵向页面,landscape横向页面
        c = canvas.Canvas(temp_pdf, pagesize = portrait(A4))
        c.drawImage(fn, 0 , 0, *portrait(A4))
        c.save()
        # 合并
        with open(temp_pdf, 'rb') as fp:
            pdf_reader = PdfFileReader(fp)
            result_pdf.append(pdf_reader)
    # 保存结果
    result_pdf.write(jpgpath+'.pdf')
    result_pdf.close
    remove(temp_pdf)

if __name__ == '__main__':
    # 转图片
    pdf2jpgs('Task2.pdf')
    # 图片合并成pdf
    merge_jpg2pdf(r'自己的文件路径\Task2')

生成的图片保存在以pdf文件名为名的文件夹里:

pdf2jpg.png

生成的图片式pdf,不可以复制,但是,需要注意,文档的大小同时也增加了,原来可能就600k的文档,转成图片pdf后,就有90M左右了。

当然,可以降低下图片的像素dpi来减小文件大小。

jpg2pdf.png

4. 给pdf加密

最后,就是给pdf加密了,使用PyPDF2包就可以。

如果是可复制的文字版的pdf,加密起来很快,但如果是图片不可复制的pdf,时间就会长些了。

from PyPDF2 import PdfFileReader, PdfFileWriter

# pdf加密
def add_encrypt(file,password):
    pdf_reader = PdfFileReader(file)
    pdf_writer = PdfFileWriter()
    for page in range(pdf_reader.getNumPages()):
        pdf_writer.addPage(pdf_reader.getPage(page))
    # 添加密码
    pdf_writer.encrypt(password)
    with open(file, "wb") as out:
            pdf_writer.write(out)  

if __name__ == '__main__':
    # 加密pdf
    password = 'xueweiguizhengshun'
    print('Task2开始加密')
    add_encrypt('Task2.pdf',password)

结果如图所示:

encrypt.png

当然,这次的文档内容主要是文字,如果有表格或者图片,可能会更复杂一些,但肯定也是能解决的啦~~

你可能感兴趣的:(【Python实战】生成图片式不可复制的pdf文件)