Word+PDF自动化

word介绍

环境安装

  • 利用 python-docx 模块,Python可以批量创建和修改 Word 文档。
  • 运行 pip install python-docx,可以安装该模块
  • 注意:在第一次用 pip 安装 python-docx 时,注意要安装 python-docx,而不是 docx。
    • docx 是指另一个模块,这里我们不必介绍。
    • 但是,在导入 python-docx 模块时,需要执行 import docx,而不是 import python-docx。
import docx

读取Word文档

  • Word文档的组成结构:

    • .docx文档
    • 段落
    • 内容
  • python-docx使用说明

    • 和纯文本相比,.docx 文件有很多结构。这些结构在 python-docx 中用 3 种不同的类型来表示。在最高一层,Document 对象表示整个文档。Document 对象包含一个 Paragraph 对象的列表,表示文档中的段落(用户在 Word 文档中输入时,如果按下回车,新的段落就开始了)。每个 Paragraph 对象都包含一个 Run 对象的列表。下图的单句段落有 4 个 Run 对象
  • 基于Document方法读取word文档

import docx
#创建了一个指定的word文档对象
doc = docx.Document('./data/demo.docx')
doc
# <docx.document.Document at 0x10af84360>
  • 基于paragraphs属性读取文档所有段落
doc.paragraphs


"""
[<docx.text.paragraph.Paragraph at 0x10fb92518>,
 <docx.text.paragraph.Paragraph at 0x10fb92e48>,
 <docx.text.paragraph.Paragraph at 0x10fb920f0>,
 <docx.text.paragraph.Paragraph at 0x10fb92588>,
 <docx.text.paragraph.Paragraph at 0x10fb92978>,
 <docx.text.paragraph.Paragraph at 0x10fb92ac8>,
 <docx.text.paragraph.Paragraph at 0x10fbc9128>,
 <docx.text.paragraph.Paragraph at 0x10fbc9160>]
"""
#获取指定段落
doc.paragraphs[0]

# <docx.text.paragraph.Paragraph at 0x10fbc9518>
  • 基于text属性读取指定段落内容的所有内容
doc.paragraphs[2].text
# 'A plain paragraph with some bold and some italic'
  • 基于runs读取指定段落内容的组成部分和组成部分的内容
doc.paragraphs[2].runs

"""
[<docx.text.Run at 0x10b3432e8>,
 <docx.text.Run at 0x10b343198>,
 <docx.text.Run at 0x10b343b00>,
 <docx.text.Run at 0x10b343160>]
"""
doc.paragraphs[2].runs[3].text
# 'italic'
  • 如何区分python-docx对于run对象的切分
#中文段落进行run构成的探测
len(doc.paragraphs[1].runs)   #3
print(doc.paragraphs[1].runs[0].text)
print(doc.paragraphs[1].runs[1].text)
print(doc.paragraphs[1].runs[2].text)

"""
我是你的好朋友
,
那你喜欢我吗?
"""
#在中文段落中,是以标点符号进行run的构建/切分
#对英文段落进行run构成的探测
len(doc.paragraphs[2].runs)   #4
print(doc.paragraphs[2].runs[0].text)
print(doc.paragraphs[2].runs[1].text)
print(doc.paragraphs[2].runs[2].text)
print(doc.paragraphs[2].runs[3].text)

"""
A plain paragraph with some 
bold
 and some 
italic
"""
#在英文段落中是以内容的样式进行run的切分
  • Paragraph 对象调用 len(),结果告诉我们有 4 个 Run 对象。第一个对象包含'A plain paragraph with some '。然后,文本变为粗体样式,所以’bold’开始了一个新的 Run 对象。在这之后,文本又回到了非粗体的样式,这导致了第三个 Run 对象,' and some '。最后,第四个对象包含'italic',是斜体样式。

  • 从.docx 文件中取得完整的文本

    • 如果你只关心 Word 文档中的文本,不关心样式信息,就可以利用 getText()函数。它接受一个.docx 文件名,返回其中文本的字符串,当然getText函数需要自己实现。

getText()函数打开了 Word 文档,循环遍历 paragraphs 列表中的所有 Paragraph对象,然后将它们的文本添加到 fullText 列表中。循环结束后,fullText 中的字符串连接在一起,中间以换行符分隔

import docx
def getText(filename):
    doc = docx.Document(filename)
    fullText = []
    for para in doc.paragraphs:
        fullText.append(para.text)
    return '\n'.join(fullText)
print(getText('./data/demo.docx'))

"""
Document Title
我是你的好朋友,那你喜欢我吗?
A plain paragraph with some bold and some italic
Heading, level 1
Intense quote
first item in unordered list
first item in ordered list
"""

写入 Word 文档

  • 调用 add_paragraph()方法,添加段落
  • 调用 add_run()方法,向它传入一个字符串
#添加段落内容
dc = docx.Document() #创建了一个全新的文档对象
p1 = dc.add_paragraph(text='i am a student!i love reading!')
p2 = dc.add_paragraph(text='i am a Bobo!i love Money!')

dc.save('./data/new_word.docx')
#向指定的段落中添加run
dc = docx.Document() #创建了一个全新的文档对象
p1 = dc.add_paragraph(text='i am a student!i love reading!')
p2 = dc.add_paragraph(text='i am a Bobo!i love Money!')

p2.add_run(text='我是内容1.')
p2.add_run(text='我是内容2.')

dc.save('./data/new_word.docx')
  • 注意:新的 Paragraph 对象只能添加在文档的末尾,新的 Run 对象只能添加在 Paragraph 对象的末尾。

  • 添加样式

    • add_paragraph()和 add_run()都接受可选的第二个参数,它是表示 Paragraph 或Run 对象样式的字符串
      • 注意设置run的样式,在样式字符串结尾需要加上Char
dc = docx.Document() #创建了一个全新的文档对象
#指定段落的样式
p1 = dc.add_paragraph(text='i am a student!i love reading!',style='Heading1')
p2 = dc.add_paragraph(text='i am a Bobo!i love Money!',style='Heading5')

p2.add_run(text='我是内容1.')
p2.add_run(text='我是内容2.',style='QuoteChar')

dc.save('./data/new_word.docx')

单独设置文本样式

  • 设置文字大小
from docx import Document
from docx.shared import Pt

document = Document()
p = document.add_paragraph()
run = p.add_run('个人简历')  # 使用add_run添加文字
run.font.size = Pt(26) #字体大小设置,和word里面的字号相对应,小一

document.save('./data/styleBy.docx')  #保存文档
  • 设置对齐
    • 需要导入一个类WD_ALIGN_PARAGRAPH
from docx import Document
from docx.enum.text import WD_ALIGN_PARAGRAPH

document = Document()
p = document.add_paragraph()
run = p.add_run('自我介绍')  # 使用add_run添加文字
p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.RIGHT    #段落文字居中设置

document.save('./data/styleBy.docx')  #保存文档

左右对齐,WD_ALIGN_PARAGRAPH.LEFT/RIGHT

  • 设置文字颜色
    • 需要使用RGB颜色
from docx import Document
from docx.shared import RGBColor

document = Document()
p = document.add_paragraph()
run = p.add_run('自我介绍')  # 使用add_run添加文字

run.font.color.rgb = RGBColor(255,0,0)

document.save('./data/styleBy.docx')  #保存文档
  • 字体加粗
from docx import Document
document = Document()
p = document.add_paragraph()
run = p.add_run('自我介绍')  # 使用add_run添加文字
run_new = p.add_run('字体加粗')  # 使用add_run添加文字

run_new.bold = True

document.save('./data/styleBy.docx')  #保存文档
  • 设置字体
from docx import Document
from docx.oxml.ns import qn

document = Document()
p = document.add_paragraph()
run = p.add_run('天生我才必有用!')  # 使用add_run添加文字
document.styles['Normal'].font.name = '华文行楷'  # 设置字体
document.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), '华文行楷')

document.save('./data/styleBy.docx')  #保存文档
  • 添加标题
    • 调用 add_heading()将添加一个段落,并使用一种标题样式
    • add_heading()的参数,是一个标题文本的字符串,以及一个从 0 到 4 的整数。整数 0 表示标题是 Title 样式,这用于文档的顶部。整数 1 到 4 是不同的标题层次,1是主要的标题,4 是最低层的子标题。add_heading()返回一个 Paragraph 对象,让你不必多花一步从 Document 对象中提取它。
doc = docx.Document()
doc.add_heading('Header 0', 0)
doc.add_heading('Header 1', 1)
doc.add_heading('Header 2', 2)
doc.add_heading('Header 3', 3)
doc.add_heading('Header 4', 4)
doc.save('./data/headings.docx')
  • 添加换行符和换页符
    • 要添加换行符(而不是开始一个新的段落),可以在 Run 对象上调用 add_break()方法,换行符将出现在它后面。如果希望添加换页符,可以将 docx.text.WD_BREAK.PAGE作为唯一的参数,传递给 add_break()
#换行符
dc = docx.Document()
dc.add_paragraph('i am a teacher!')
dc.paragraphs[0].runs[0].add_break() #添加一个换行符
dc.paragraphs[0].add_run('hello!!!')
dc.add_paragraph('i am a student!')
print(len(dc.paragraphs))  # 2
dc.save('./data/new.docx')
#换页符号
dc = docx.Document()
dc.add_paragraph('i am a teacher!')
dc.paragraphs[0].runs[0].add_break(docx.text.WD_BREAK.PAGE)    #添加一个换页符
dc.add_paragraph('i am a student!')
print(len(dc.paragraphs))  # 2
dc.save('./data/new.docx')

添加图像

  • Document 对象有一个 add_picture()方法,让你在文档中添加图像

    • 第一个参数是一个字符串,表示图像的文件名。
    • 可选的 width 和 height 关键字参数,将设置该图像在文档中的宽度和高度。如果省略,宽度和高度将采用默认值,即该图像的正常尺寸。
      • 你可能愿意用熟悉的单位来指定图像的高度和宽度,诸如英寸或厘米。所以在指定width 和height 关键字参数时,可以使用docx.shared.Inches()和 docx.shared.Cm()函数。
  • 向新文档任意位置添加图片

doc = docx.Document()
doc.add_paragraph('This is on the first page!')

doc.add_picture('./data/zophie.png', width=docx.shared.Inches(10),height=docx.shared.Cm(20))

doc.add_paragraph('This is on the second page!')
doc.save('./data/twoPage.docx')
  • 向已有的文档添加添加图片
doc = docx.Document('./data/twoPage.docx')
doc.add_picture('./data/zophie.png', width=docx.shared.Inches(3),height=docx.shared.Cm(5))
doc.save('./data/twoPage.docx')

添加表格

  • 创建表格
    • 基于Document的add_table方法增加一个表格
    • 参数:
      • rows
      • cols
      • style
doc = docx.Document()
tb = doc.add_table(rows=3,cols=3,style='Light List Accent 3')
  • 常用的表格样式:

    • Light Shading
    • Light Shading Accent 1-6
    • Light List Accent 1-6
    • Light Grid Accent 1-6
    • Medium Shading 1 Accent 1-6
    • ......
  • 向表格中添加数据

    • 依次访问到表格中的每一个cell,然后按照指定要求填充数据即可
      • 基于rows属性和cells属性可以逐步访问到表格中的cell
      • 基于add_paragraph方法即可像cell里添加文本
#rows返回所有的行对象
list(tb.rows)

"""
[<docx.table._Row at 0x10e1e6ba8>,
 <docx.table._Row at 0x10e1e6e80>,
 <docx.table._Row at 0x10e1e6908>]
"""
#columns返回所有列对象
list(tb.columns)
"""
[<docx.table._Column at 0x10e1e5e10>,
 <docx.table._Column at 0x10e1e5ef0>,
 <docx.table._Column at 0x10e1e5cc0>]
"""
#cells返回行中所有的单元格
tb.rows[0].cells 
"""
(<docx.table._Cell at 0x10e1e5f98>,
 <docx.table._Cell at 0x10e1e5048>,
 <docx.table._Cell at 0x10e1e52b0>)
"""
#向cell中添加数据
tb.rows[0].cells[0].add_paragraph('hello')
# <docx.text.paragraph.Paragraph at 0x10e26e080>
#批量填充表格
alist = ['name','salary','address','bobo','10000','BJ','bobo1','20000','SH']
i = 0
for row in tb.rows:
    for cell in row.cells:
        cell.add_paragraph(text=alist[i])
        i+=1
doc.save('./data/table.docx')
  • 添加行列
    • add_row()
    • add_column()
tb.add_row()
tb.add_column(docx.shared.Cm(3))
doc.save('./data/table.docx')
  • 设置表格列宽 & 行高
    • 列宽:基于表格的cell设置其width属性
    • 行高:基于表格的行设置其height属性
#设置下行高
tb.rows[0].height = docx.shared.Cm(3)
#设置列宽
tb.rows[0].cells[0].width = docx.shared.Cm(10)
doc.save('./data/table.docx')
  • 表格cell的合并
    • merge方法
c1 = tb.cell(0,1)
c2 = tb.cell(1,1)
c1.merge(c2)
doc.save('./data/table.docx')

实践:生成电视剧简介海报

from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
from docx.shared import RGBColor
from docx.shared import Inches
#标题
document = Document()
p = document.add_paragraph()
run = p.add_run('琅琊榜')  # 使用add_run添加文字
run.font.size = Pt(26) #字体大小设置,和word里面的字号相对应,小一
p.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER    #段落文字居中设置
run.bold = True  # 字体加粗
document.styles['Normal'].font.name = '宋体'  # 设置字体
document.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), '宋体')
run.font.color.rgb = RGBColor(255,0,0) #颜色设置,这里是用RGB颜色

#图片
pic = document.add_picture('./data/huge.png',width = Inches(5))  # 添加图片
last_paragraph = document.paragraphs[-1]
last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER      #图片居中设置

#剧情简介
p = document.add_paragraph()
run = p.add_run('剧情简介')
run.font.size = Pt(22)  # 二号
run.bold = True

p = document.add_paragraph()
run = p.add_run('梅长苏(胡歌饰)本远在江湖,却名动帝辇。江湖传言:“江左梅郎,麒麟之才,得之可得天下。”作为天下第一大帮“江左盟”的首领,梅长苏“梅郎”之名响誉江湖。然而,有着江湖至尊地位的梅长苏,却是一个病弱青年、弱不禁风,背负着十多年前巨大的冤案与血海深仇,就连身世背后也隐藏着巨大的秘密。')
p_format = p.paragraph_format
p_format.first_line_indent = Inches(0.2)  # 首行缩进

document.add_paragraph(text='\r', style=None)  # 换行

p = document.add_paragraph()
run = p.add_run('音乐原声')
run.font.size = Pt(22)  # 二号
run.bold = True

table = document.add_table(rows=4, cols=5) 
def th(x,y,content):
    """
    th样式
    :param x: x坐标
    :param y: y坐标
    :param content: 内容
    :return: None
    """
    # print(grid,content)
    run = table.cell(x,y).paragraphs[0].add_run(content)
    run.bold = True  # 加粗

def td_red(table,x, y,content):
    """
    td红色字体
    :param table: 表格对象
    :param x: x坐标
    :param y: y坐标
    :param content: 内容
    :return: None
    """
    run = table.cell(x, y).paragraphs[0].add_run(content)
    run.font.size = Pt(11)
    run.font.color.rgb = RGBColor(255, 0, 0)

th(0,0,"歌曲")
th(0,1,"演唱者")
th(0,2,"作曲")
th(0,3,"作词")
th(0,4,"类型")

table.cell(1,0).text = "《风起时》"
td_red(table,1,1,"胡歌")
table.cell(1,2).text = "孟可"
table.cell(1,3).text = "海宴"
table.cell(1,4).text = "主题曲、片尾曲"

table.cell(2,0).text = "《红颜旧》"
table.cell(2,1).text = "刘涛"
table.cell(2,2).text = "赵佳霖"
table.cell(2,3).text = "袁亮"
table.cell(2,4).text = "插曲"

table.cell(3,0).text = "《赤血长殷》"
table.cell(3,1).text = "王凯"
table.cell(3,2).text = "于海航"
table.cell(3,3).text = "清彦、冰封"
table.cell(3,4).text = "插曲"

table.style = document.styles['Table Grid']  # 表格样式

document.save('./data/琅琊榜.docx')  #保存文档

批量生成审批报告

from docx import Document
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.shared import Pt      
from docx.oxml.ns import qn     
from docx.shared import Inches 
import time
#客户名单
company_list = ['客户张三','客户李四']
today = time.strftime("%Y{y}%m{m}%d{d}",time.localtime()).format(y='年',m='月',d='日') #获取今日时间,整理成年月日格式

for i in company_list:
    document = Document()
    document.styles['Normal'].font.name = u'宋体'  #设置文档的基础字体
    document.styles['Normal'].element.rPr.rFonts.set(qn('w:eastAsia'),u'宋体')  #设置文档的基础中文字体
    document.styles['Normal'].font.size = Pt(14)#设置文档字体为14磅
    
    #插入图片
    document.add_picture('./data/logo.png', height=Inches(1))  # 在文档上方插入图片作为文件红头,宽度为6英寸
    last_paragraph = document.paragraphs[-1]
    last_paragraph.alignment = WD_ALIGN_PARAGRAPH.CENTER
    
    #建立第一个自然段
    p1 = document.add_paragraph()  #初始化建立第一个自然段
    p1.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  #对齐方式为居中,没有这句默认为左对齐
    run1 = p1.add_run('审批报告说明')
    run1.font.name = u'微软雅黑'   #设置西文字体
    run1.element.rPr.rFonts.set(qn('w:eastAsia'),u'微软雅黑')  #设置段中文字体
    run1.font.size = Pt(21)   #设置字体大小为21磅
    run1.font.bold = True    #设置加粗


    #建立第二个自然段
    p2 = document.add_paragraph()  #初始化建立第二个自然段
    run2 = p2.add_run('尊敬的%s:'%i)   #这个是对客户称谓
    run2.font.name = u'仿宋_GB2312'   #设置西文字体
    run2.element.rPr.rFonts.set(qn('w:eastAsia'),u'仿宋_GB2312')  #设置段中文字体
    run2.font.size = Pt(16)   #设置字体大小为16磅
    run2.font.bold = True    #设置加粗

    #建立第三个自然段
    p3 = document.add_paragraph()  #初始化建立第三个自然段
    run3 = p3.add_run('   非常感谢贵公司长期以来对我公司支持。我公司同意了该项目的审核批复,今后与贵公司的联络和业务跟进工作由我公司Bobo负责,请贵公司一如既往得给与合作和支持。谢谢')   #内容
    run3.font.name = u'仿宋_GB2312'   #设置西文字体
    run3.element.rPr.rFonts.set(qn('w:eastAsia'),u'仿宋_GB2312')  #设置段中文字体
    run3.font.size = Pt(16)   #设置字体大小为16磅
    run3.font.bold = True    #设置加粗

    #建立第四个自然段
    p4 = document.add_paragraph()  #初始化建立第四个自然段
    p4.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT  # 对齐方式为居中
    run4 = p4.add_run('联系人:小明  电话:188888888888')   #内容
    run4.font.name = u'仿宋_GB2312'   #设置西文字体
    run4.element.rPr.rFonts.set(qn('w:eastAsia'),u'仿宋_GB2312')  #设置段中文字体
    run4.font.size = Pt(16)   #设置字体大小为16磅
    run4.font.bold = True    #设置加粗


    #插入表格
    table = document.add_table(rows=3,cols=3,style="Table Grid")   #添加3行3列表格
    table.cell(0,0).merge(table.cell(0,2))   #将第一行合并,将0行0列合并到0行2列
    table_run1 = table.cell(0,0).paragraphs[0].add_run('%s产品报价表'%i)
    table_run1.font.name = u'隶书'
    table_run1.element.rPr.rFonts.set(qn('w:eastAsia'),u'隶书')
    table.cell(0,0).paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

    table.cell(1,0).text = '日期'
    table.cell(1,1).text = '价格'
    table.cell(1,2).text = '备注'
    table.cell(2,0).text = today
    table.cell(2,1).text = str('100.00')
    table.cell(2,2).text = ''


    document.save('./data/%s-审批报告.docx' % i)

PDF介绍

  • 在学习和工作中大家一定对pdf非常熟悉。事实上,pdf也是非常重要并且应用广泛的一种数字媒体。PDF全称是Portable Document Format,即可移植的文档格式。它使用.pdf作为扩展名。用于可靠的呈现和交换文档,与软件,硬件和操作系统无关。
  • pdf使用Adobe公司开发,现在由国际标准化组织ISO进行维护。

环境安装

  • Python处理PDF
    • 用于处理 PDF 的模块是 PyPDF2。
    • 要安装它,就从命令行运行 pip install PyPDF2
      • 这个模块名称是区分大小写的,所以要确保 y 是小写,其他字母都是大写
import PyPDF2
  • PyPDF2可以实现:
    • 提取文档信息(标题,作者,...)
    • 按页拆分文档
    • 逐页合并文档
    • 裁剪页面
    • 合并多个页面到一个页
    • 对pdf文档进行加密解密
    • ......

读取PDF文件操作

  • 打开指定文件
import PyPDF2
pdfFile = open('./data/example.pdf','rb')
  • 创建读取器对象
pdfReader = PyPDF2.PdfFileReader(pdfFile)
# <PyPDF2.pdf.PdfFileReader at 0x10afe1cf8>
  • 返回总页码数
pdfReader.numPages # 40
  • 获取指定页面对象
page = pdfReader.getPage(0)
  • 提取出页面中的文字
page.extractText()
  • 注意:
    • 虽然PDF文件非常适合以一种便于打印和阅读的方式显示文本,但是对于程序来说,将其解析为纯文本并不容易。因此,PyPDF2在从PDF中提取文本时可能会出错,甚至可能根本无法打开某些PDF。很不幸的是,我们对此无能为力。

PDF的写入操作

  • 将一个完整pdf拆分成两个单独的pdf文件进行保存,且去除不想要的指定页面
import PyPDF2
pdfFile = open('./data/example.pdf','rb')
#创建读取器对象
pdfReader = PyPDF2.PdfFileReader(pdfFile)
#创建写入器对象
pdfWriter1 = PyPDF2.PdfFileWriter()
pdfWriter2 = PyPDF2.PdfFileWriter()

all_pages = pdfReader.numPages
for page in range(all_pages):
    #去除不想要的页面
    if page in [1,3,5,7,9]:
        continue
    #获取中间页码值
    middle_num = all_pages // 2
    #提取一页数据
    pageObj = pdfReader.getPage(page)
    if page <= middle_num:
        pdfWriter1.addPage(pageObj)
    else:
        pdfWriter2.addPage(pageObj)
        
f1 = open('./data/example_1.pdf','wb')  
f2 = open('./data/example_2.pdf','wb')
pdfWriter1.write(f1)
pdfWriter2.write(f2)

pdfFile.close()
f1.close()
f2.close()
  • 注意:

    • PyPDF2 不能在 PdfFileWriter 对象中间插入页面,addPage()方法只能够在末尾添加页面。
  • 旋转页面

    • 利用 rotateClockwise()和 rotateCounterClockwise()方法,PDF 文档的页面也可以 旋转 90 度的整数倍。向这些方法传入整数 90、180 或 270 就可以了
#翻转第一张页面
import PyPDF2
minutesFile = open('./data/example.pdf', 'rb')
pdfReader = PyPDF2.PdfFileReader(minutesFile)
page = pdfReader.getPage(0)
page.rotateCounterClockwise(90)

#创建写入器,将翻转的第一张页面添加到写入器中
pdfWriter = PyPDF2.PdfFileWriter()
pdfWriter.addPage(page)
#将翻转的页面写入到一个新的pdf中
resultPdfFile = open('./data/rotatedPage.pdf', 'wb')
pdfWriter.write(resultPdfFile)
resultPdfFile.close()
minutesFile.close()
  • 叠加页面
    • PyPDF2 也可以将一页的内容叠加到另一页上,这可以用来在页面上添加公司标志、时间戳或水印。利用 Python,很容易为多个文件添加水印,并且只针对程序 指定的页面添加。
import PyPDF2
#打开需要添加水印的pdf
pythonFile = open('./data/example.pdf', 'rb')
#对需要添加水印的pdf生成器读取器
pdfReader = PyPDF2.PdfFileReader(pythonFile)

#生成水印pdf的读取器
pdfWatermarkReader = PyPDF2.PdfFileReader(open('./data/watermark.pdf', 'rb'))
#创建写入器对象
pdfWriter = PyPDF2.PdfFileWriter()
#遍历需要添加水印pdf的每一页
for pageNum in range(0, pdfReader.numPages): 
    #获取页面对象
    pageObj = pdfReader.getPage(pageNum)
    #添加水印(叠加两张页面)
    pageObj.mergePage(pdfWatermarkReader.getPage(0))
    #添加到写入器中(注意:写入器中已经添加了水印)
    pdfWriter.addPage(pageObj)
resultPdfFile = open('./data/watermarkedCover.pdf', 'wb') 
pdfWriter.write(resultPdfFile)
minutesFile.close()
resultPdfFile.close()

  • 加密 PDF
    • PdfFileWriter 对象也可以为 PDF 文档进行加密
    • encrypt()方法,传入口令字符串。PDF 可以有一个用户口令(允许查看这个PDF)和一个拥有者口令(允许设置打印、注释、 提取文本和其他功能的许可)。用户口令和拥有者口令分别是 encrypt()的第一个和第二个参数。如果只传入一个字符串给 encrypt(),它将作为两个口令。
import PyPDF2
pdfFile = open('./data/watermark.pdf', 'rb') 
pdfReader = PyPDF2.PdfFileReader(pdfFile) 
pdfWriter = PyPDF2.PdfFileWriter()
for pageNum in range(pdfReader.numPages): 
    pdfWriter.addPage(pdfReader.getPage(pageNum))
pdfWriter.encrypt('1324')
resultPdf = open('./data/encryptedminutes.pdf', 'wb')
pdfWriter.write(resultPdf)
resultPdf.close()

  • 解密PDF

import itertools
from PyPDF2 import PdfFileReader

mylist = ("".join(x) for x in itertools.product("1234567890", repeat=4))
path = './data/encryptedminutes.pdf'
pdf reader = PdfFileReader(path)

while True:
       i = next(mylist)
       if pdf reader.decrypt(i):
            print(f'破解成功,密码为(i}')
            break
  • 项目:从多个 PDF 中合并选择的页面
    • 假定你有一个很无聊的任务,需要将几十个 PDF 文件合并成一个 PDF 文件。每 一个文件都有一个封面作为第一页,但你不希望合并后的文件中重复出现这些封 面。即使有许多免费的程序可以合并 PDF,很多也只是简单的将文件合并在一起。 让我们来写一个 Python 程序,定制需要合并到 PDF 中的页面。
    • 总的来说,该程序需要完成:
      • 找到当前工作目录中所有 PDF 文件。
      • 按文件名排序,这样就能有序地添加这些 PDF。
      • 除了第一页之外,将每个 PDF 的所有页面写入输出的文件。
    • 从实现的角度来看,代码需要完成下列任务:
      • 调用 os.listdir(),找到当前工作目录中的所有文件,去除掉非 PDF 文件。
      • 调用 Python 的 sort()列表方法,对文件名按字母排序。
      • 为输出的 PDF 文件创建 PdfFileWriter 对象。
      • 循环遍历每个 PDF 文件,为它创建 PdfFileReader 对象。
      • 针对每个 PDF 文件,循环遍历每一页,第一页除外。 将页面添加到输出的 PDF。
      • 将输出的 PDF 写入一个文件,名为 allminutes.pdf。
      • 针对这个项目,打开一个新的文件编辑器窗口,将它保存为 combinePdfs.py。
posted @ 2023-02-09 10:06  凫弥  阅读(121)  评论(0编辑  收藏  举报