在日常工作中,要保护一下我们的商业机密嘛~ 如果按名单向客户逐一发文件,如果就发几份,那么可以采取用pdf软件逐份编辑,打个水印、加个密码咯。但面对成百上千份文件,就需要批量处理了!菜鸡在熬夜加班后终于发掘了这个东西的用法,分享给大家~

  • 首先简单设置一下
# encoding:utf-8
import os;
import pandas as pd;
import numpy as np;
import openpyxl;
import shutil;
  • 插入页面:向文件夹1中的每一个文件中都插入一页 新文件.pdf
# -*- coding: utf-8 -*-
# 读入pdf路径为path0,写出pdf路径为path1
path0 = 'D:\\举例\\文件夹1'
path1 = 'D:\\举例\\文件夹2'
filelist=os.listdir(path0)

# 读入新文件,假设新文件仅有一页,文件夹1中的文件均仅有2页
pdf2 = open( 'D:\\举例\\新文件.pdf','rb')
pdf_reader2 = PdfFileReader(pdf2)

for file in filelist:
    what = os.path.join(path0,file)
    pdf1 = open(what,'rb')
    pdf_reader = PdfFileReader(pdf1)
    pdf_writer = PdfFileWriter() 
    # 第一页为文件夹1中的文件第一页
    pdf_writer.addPage(pdf_reader.getPage(0))
    # 第二页为新文件第一页
    pdf_writer.addPage(pdf_reader2.getPage(0))
    # 第三页为文件夹1中的文件第二页
    pdf_writer.addPage(pdf_reader.getPage(1))
# 写入合并的pdf
    pdf_writer.encrypt(user_pwd="123123")
    output = os.path.join(path1,file)
    with open(output, 'wb') as out:
         pdf_writer.write(out)
  • 复制、改名称:先把要发的客户名称制作成name.txt,写个函数复制一下文件,把文件按客户名称命名好。
# 写函数:复制原文件并逐一对pdf文件按照name.txt更改文件名为【机构名称】,name.txt文件内仅有一列数据【机构名称】
def get_files():
    path='D:\\举例\\文件夹1'
    
    name = pd.read_table('D:\\举例\\文件夹1\\name.txt');
    
    name2 = np.array(name['机构名称']) ;
    
    n = name.iloc[:,0].size;
    
    for file in range(1,n+1):
   
        path_o = 'D:\\举例\\文件夹1\\正文.pdf'
        
        filename_new = name2[file]
        
        path_n = os.path.join(path,filename_new+'.pdf')
        
        shutil.copyfile(path_o, path_n);
        
        print(filename_new);

# 执行函数
get_files()
  • 然后准备上pypdf2的包,安排好汉字字体,准备当调包侠~
# 安装pyPDF2,准备批量打水印
#pip install pypdf2
from PyPDF2 import PdfFileReader, PdfFileWriter,PdfFileMerger
#!/usr/bin/env python
#!pip install reportlab
# encoding:utf-8
from PyPDF2 import PdfFileReader, PdfFileWriter
from reportlab.lib.units import cm
from reportlab.pdfbase import pdfmetrics 
from reportlab.pdfgen import canvas
from reportlab.pdfbase.ttfonts import TTFont 
pdfmetrics.registerFont(TTFont('song', 'C:/Windows/Fonts/simsun.ttc'))#宋体
import xlrd
  • 制作水印文件:开始安排水印文件,因为客户名称可能3个字也可能“乱七八糟真长真无语绝了有限公司”这种,水印无法自动调节大小,因此把字数不同长度做成不同的水印文件,一会儿循环的时候先判断一下~ 这边还有很多长度不同的水印函数,暂略。
# 因name.txt中【机构名称】字数不一,因此水印按照字数分组设置大小、位置、旋转角度等。
# 5个字以下的水印
# encoding:utf-8
def create_watermark5(content):
    """水印信息"""
    # 默认大小为21cm*29.7cm
    file_name = "mark.pdf"
    c = canvas.Canvas(file_name, pagesize=(30*cm, 30*cm))
    # 移动坐标原点(坐标系左下为(0,0))
    c.translate(4*cm, 14*cm)

    # 设置字体
    c.setFont('song', 120)
    # 指定描边的颜色
    c.setStrokeColorRGB(0, 1, 0)
    # 指定填充颜色
    c.setFillColorRGB(0, 1, 0)
    # 画一个矩形
    # c.rect(cm, cm, 7*cm, 17*cm, fill=1)
    # 旋转45度,坐标系被旋转
    c.rotate(45)
    # 指定填充颜色
    c.setFillColorRGB(0, 0, 0, 0.1)
    # 设置透明度,1为不透明
    # c.setFillAlpha(0.1)
    # 画几个文本,注意坐标系旋转的影响
    c.drawString(3*cm, 0*cm, content)
    c.setFillAlpha(0.6)
    # 关闭并保存pdf文件
    c.save()
    return file_name
  • 打水印&加密码:来吧,下面准备打水印函数,主要用来完成把水印文件贴在原文件上面这个步骤~ 同时还在函数中插入了加密码这个功能。
# 打水印函数
def add_watermark(pdf_file_in, pdf_file_mark, pdf_file_out):
    """把水印添加到pdf中"""
    pdf_output = PdfFileWriter()
    input_stream = open(pdf_file_in, 'rb')
    pdf_input = PdfFileReader(input_stream, strict=False)
    # 获取PDF文件的页数
    pageNum = pdf_input.getNumPages()
    # 读入水印pdf文件
    pdf_watermark = PdfFileReader(open(pdf_file_mark, 'rb'), strict=False)
    # 给每一页打水印
    for i in range(pageNum):
        page = pdf_input.getPage(i)
        page.mergePage(pdf_watermark.getPage(0))
        page.compressContentStreams()  # 压缩内容
        pdf_output.addPage(page)
    # 添加密码
    pdf_writer.encrypt(user_pwd="abc")
    output = os.path.join(path1,file)
    with open(output, 'wb') as out:
         pdf_writer.write(out)
  
    pdf_output.write(open(pdf_file_out, 'wb'))
  • 设置打水印路径
# 设置打水印读入、写出路径,打水印读入文件路径为path00,写出文件路径为path11
# 注意:前置步骤需将文件夹1中全部未打水印的文件复制到文件夹2中
path00 = 'D:\\举例\\文件夹1'
path11 = 'D:\\举例\\文件夹2'
filelist00=os.listdir(path00)
filelist11=os.listdir(path11)
  • 循环开始
# 写条件循环语句,完成不同字数长度的文件水印
# encoding:utf-8
if __name__ == '__main__':
    for i,j in zip(filelist00,filelist11):
        pdf_file_in = os.path.join(path00,i)
        pdf_file_out = os.path.join(path11,j)
        mark_name = os.path.splitext(i)[0]
        if len(mark_name) <= 5:
            pdf_file_mark = create_watermark5(mark_name)
        elif len(mark_name) <= 8:
            pdf_file_mark = create_watermark8(mark_name)
        elif len(mark_name) <= 13:
            pdf_file_mark = create_watermark13(mark_name)
        elif len(mark_name) <= 15:
            pdf_file_mark = create_watermark15(mark_name)
        else: 
            pdf_file_mark = create_watermark18(mark_name)
        add_watermark(pdf_file_in, pdf_file_mark, pdf_file_out)
        print(mark_name)
  • 有的公司还要加盖电子章,可以仿照打水印的操作,做一个电子章的页面,重新调用打水印函数将电子章贴上去~
# 写电子章函数,可重复调用add_watermark进行打批量电子章
def create_stamp(content):
    """盖章"""
    # 默认大小为21cm*29.7cm
    file_name = "stamp.pdf"
    c = canvas.Canvas(file_name, pagesize=(30*cm, 30*cm))
    # 移动坐标原点(坐标系左下为(0,0))
    c.translate(10*cm, 0.5*cm)

    # 设置字体
    c.setFont('song', 120)
    # 指定描边的颜色
    c.setStrokeColorRGB(0, 1, 0)
    # 指定填充颜色
    c.setFillColorRGB(0, 1, 0)
    # 画一个矩形
    # c.rect(cm, cm, 7*cm, 17*cm, fill=1)
    # 旋转45度,坐标系被旋转
    c.rotate(45)
    # 指定填充颜色
    c.setFillColorRGB(0, 0, 0, 0.1)
    # 设置透明度,1为不透明
    # c.setFillAlpha(0.1)
    # 画几个文本,注意坐标系旋转的影响
    c.drawString(3*cm, 0*cm, content)
    c.setFillAlpha(0.6)
    # 关闭并保存pdf文件
    c.save()
    return file_name
  • 分类放置:打好水印、加好密码的文件可以按照名字自动移动至相应文件夹,避免手动分类烦恼喔~
# 按分支机构地区进行文件分类,location的格式是两列数据,分别为【机构名称】、【分支机构地区】
# encoding:utf-8
name11 = pd.read_table('D:\\举例\\location.txt')
name11 = pd.DataFrame(name11)

# 循环逻辑:如【机构名称】中带有“公司”二字,划分至企业文件夹,其余按照location.txt划分至对应的【分支机构地区】
# -*- coding: utf-8 -*-
for file in filelist:
    filename=os.path.splitext(file)[0]
    if  filename.find('公司') > 0:
        old_path = os.path.join(path0,file)
        new_pat = os.path.join(path1,'企业')
        new_path = os.path.join(new_pat,file)
        os.rename(old_path,new_path)
        print("移动到企业")
    else:
        location = name11[name11['机构名称'] == filename]
        location = location['分支机构地区'].iloc[0]
        old_path = os.path.join(path0,file)
        new_pat = os.path.join(path1,location)
        new_path = os.path.join(new_pat,file)
        os.rename(old_path,new_path)
        print("移动到分支机构")

至此,文件已复制为按照【机构名称】命名的文件,文件上每页均有【机构名称】字样、由左下角至右上角的灰色大水印,每一个文件都需要输入密码“abc”才能打开,且按照分类移动至所属文件夹。

Pypdf2作为Python批量处理pdf文件的包,其功能完整,操作难度小,可以说有效提升办公效率。