亲宝软件园·资讯

展开

Python PDF添加水印

Python 集中营 人气:0

前言

可以通过设置批量PDF文件所在的路径及需要添加的水印名称可以实现批量添加PDF水印的效果。

实现思路是这样的,通过在批量PDF文件路径下面生成一个带有水印的PDF模板。最后,将批量文件的每个PDF页面和水印模板进行合并完成批量添加水印的效果。

图片

需要注意的是批量PDF文件必须和PDF模板水印文件的大小尺寸保持一致,这个可以在代码里面调节一下就成了。

实现步骤

首先将需要添加水印的PDF文件准备好放在一个文件夹下面。

图片

在代码中设置好PDF批量文件的路径及水印名称。

if __name__ == '__main__':
    main('C:/pdf', '我是一个水印')

内部实现过程都封装在main()函数里面了,这里改一下水印名称和批量PDF文件路径直接执行就好了。

启动以后,出现如下面的结果说明已经执行完成了。

图片

为了不覆盖原来的PDF文件,合并后的文件都是添加了"已合并"字样的PDF文件。

说完了怎么操作,看一下主要的代码块部分有哪些吧。

其中用到的第三方库有下面这些,里面我写了相关的注释。

import os  # 应用文件操作

# reportlab是Python的一个标准库,可以画图、画表格、编辑文字,最后可以输出PDF格式。
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

pdfmetrics.registerFont(TTFont('songti', 'C:/Windows/Fonts/simsun.ttc'))  # 加载宋体

# PyPDF2模块主要的功能是分割或合并PDF文件,裁剪或转换PDF文件中的页面。
from PyPDF2 import PdfFileWriter, PdfFileReader

import logging  # 日志打印库

日志模块的初始化也比较简单,前面的文章中都有过相关的调用。

# 初始化日志设置
logger = logging.getLogger('批量添加水印')
logging.basicConfig(format='%(asctime)s %(levelname)-8s: %(message)s')
logger.setLevel(logging.DEBUG)

日志初始化完成后在后面需要打印日志的地方调用就可以了。

实现过程主要有三个函数来实现的,一个是为了生成水印模板、另一个是使水印模板和批量PDF文件执行合并从而实现添加水印的功能、还有一个就是逐个遍历批量PDF文件使其能够逐个实现水印合并。

水印模板生成函数。

def generate_water_pdf(content):
    '''
    生成带有水印的PDF
    :param content: 水印名称
    :return:
    '''
    cans = canvas.Canvas('water_back.pdf', pagesize=(21 * cm, 29.7 * cm))
    cans.translate(10 * cm,
                   12 * cm)  # 移动原点坐标
    cans.setFont('songti', 23)  # 设置字体为宋体、大小为23号
    cans.setFillColorRGB(0.5, 0.5,
                         0.5)  # 设置字体背景颜色
    cans.rotate(45)  # 设置字体倾斜45度
    cans.drawString(-7 * cm, 0 * cm, content)
    cans.drawString(7 * cm, 0 * cm, content)
    cans.drawString(0 * cm, 7 * cm, content)
    cans.drawString(0 * cm, -7 * cm, content)
    cans.save()  # 保存水印的PDF文件

水印合成实现函数。

def insert_water_to_pdf(input_pdf, output_pdf, water_pdf):
    '''
    合并水印到PDF文件中
    :param input_pdf: 输入文件路径
    :param output_pdf: 输出文件路径
    :param water_pdf: 水印文件路径
    :return:
    '''
    water = PdfFileReader(water_pdf)  # 读取水印PDF
    water_page = water.getPage(0)  # 获取水印PDF的第一页
    pdf = PdfFileReader(input_pdf, strict=False)  # 读取需要添加水印的文件
    pdf_writer = PdfFileWriter()  # 创建PDF文件写入对象
    for page in range(pdf.getNumPages()):  # 遍历每一页PDF对象
        pdf_page = pdf.getPage(page)  # 获取PDF的当前页对象
        pdf_page.mergePage(water_page)  # 将水印页合并到当前页中
        pdf_writer.addPage(pdf_page)  # 将合并后的PDF对象页添加到PDF写入对象中
    output_file = open(output_pdf, 'wb')  # 打开PDF输出文件
    pdf_writer.write(output_file)  # 将文件写入到输出文件
    output_file.close()  # 关闭写入流

批量PDF文件遍历调用合成函数。

def main(diretory, current):
    if os.path.isdir(diretory):
        logger.info('文件夹[' + diretory + ']校验成功!')
        os.chdir(diretory)
        logger.info('当前路径为[' + os.getcwd() + ']')
        generate_water_pdf(current)
        logger.info('水印PDF文件生成成功!')
        for file_path, dir_names, file_names in os.walk(r'' + os.getcwd()):
            for file_name in file_names:
                try:
                    name = file_name.split('.')[0]
                    if name == 'water_back':
                        continue
                    else:
                        file_name_path = os.path.join(file_path, file_name)
                        output_file_path = file_name_path.split('.')[0] + '_已添加水印.pdf'
                        insert_water_to_pdf(file_name_path, output_file_path, 'water_back.pdf')
                        logger.info('[' + file_name_path + ']完成水印合并!')
                except Exception as e:
                    logger.error('[' + file_name_path + ']发生异常,执行下一个!')
                    logger.error('异常信息:' + repr(e))
    else:
        logger.info('文件夹[' + diretory + ']校验失败!')

主要实现过程就是通过上面三个函数来完成的,最后调用后台入口函数将mian()函数调用执行就可以了。

完整代码

# -*- coding:utf-8 -*-
# @author Python 集中营
# @date 2022/1/27
# @file test4.py

# done

# 批量向PDF文件添加中文水印

import os  # 应用文件操作

# reportlab是Python的一个标准库,可以画图、画表格、编辑文字,最后可以输出PDF格式。
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

pdfmetrics.registerFont(TTFont('songti', 'C:/Windows/Fonts/simsun.ttc'))  # 加载宋体

# PyPDF2模块主要的功能是分割或合并PDF文件,裁剪或转换PDF文件中的页面。
from PyPDF2 import PdfFileWriter, PdfFileReader

import logging  # 日志打印库

# 初始化日志设置
logger = logging.getLogger('批量添加水印')
logging.basicConfig(format='%(asctime)s %(levelname)-8s: %(message)s')
logger.setLevel(logging.DEBUG)


def generate_water_pdf(content):
    '''
    生成带有水印的PDF
    :param content: 水印名称
    :return:
    '''
    cans = canvas.Canvas('water_back.pdf', pagesize=(21 * cm, 29.7 * cm))
    cans.translate(10 * cm,
                   12 * cm)  # 移动原点坐标
    cans.setFont('songti', 23)  # 设置字体为宋体、大小为23号
    cans.setFillColorRGB(0.5, 0.5,
                         0.5)  # 设置字体背景颜色
    cans.rotate(45)  # 设置字体倾斜45度
    cans.drawString(-7 * cm, 0 * cm, content)
    cans.drawString(7 * cm, 0 * cm, content)
    cans.drawString(0 * cm, 7 * cm, content)
    cans.drawString(0 * cm, -7 * cm, content)
    cans.save()  # 保存水印的PDF文件


def insert_water_to_pdf(input_pdf, output_pdf, water_pdf):
    '''
    合并水印到PDF文件中
    :param input_pdf: 输入文件路径
    :param output_pdf: 输出文件路径
    :param water_pdf: 水印文件路径
    :return:
    '''
    water = PdfFileReader(water_pdf)  # 读取水印PDF
    water_page = water.getPage(0)  # 获取水印PDF的第一页
    pdf = PdfFileReader(input_pdf, strict=False)  # 读取需要添加水印的文件
    pdf_writer = PdfFileWriter()  # 创建PDF文件写入对象
    for page in range(pdf.getNumPages()):  # 遍历每一页PDF对象
        pdf_page = pdf.getPage(page)  # 获取PDF的当前页对象
        pdf_page.mergePage(water_page)  # 将水印页合并到当前页中
        pdf_writer.addPage(pdf_page)  # 将合并后的PDF对象页添加到PDF写入对象中
    output_file = open(output_pdf, 'wb')  # 打开PDF输出文件
    pdf_writer.write(output_file)  # 将文件写入到输出文件
    output_file.close()  # 关闭写入流


def main(diretory, current):
    if os.path.isdir(diretory):
        logger.info('文件夹[' + diretory + ']校验成功!')
        os.chdir(diretory)
        logger.info('当前路径为[' + os.getcwd() + ']')
        generate_water_pdf(current)
        logger.info('水印PDF文件生成成功!')
        for file_path, dir_names, file_names in os.walk(r'' + os.getcwd()):
            for file_name in file_names:
                try:
                    name = file_name.split('.')[0]
                    if name == 'water_back':
                        continue
                    else:
                        file_name_path = os.path.join(file_path, file_name)
                        output_file_path = file_name_path.split('.')[0] + '_已添加水印.pdf'
                        insert_water_to_pdf(file_name_path, output_file_path, 'water_back.pdf')
                        logger.info('[' + file_name_path + ']完成水印合并!')
                except Exception as e:
                    logger.error('[' + file_name_path + ']发生异常,执行下一个!')
                    logger.error('异常信息:' + repr(e))
    else:
        logger.info('文件夹[' + diretory + ']校验失败!')


if __name__ == '__main__':
    main('C:/pdf', '我是一个水印')

加载全部内容

相关教程
猜你喜欢
用户评论