PyPDF2中主要涉及到的几个对象有 PdfFileReader、PdfFileWriter和PdfFileMerger以及PageObject
PdfFileReader对象:
import PyPDF2
PyPDF2.PdfFileReader(stream , strict=True , warndest=None , overwriteWarnings=True))
# 参数
# stream :一个 File 对象或支持类似于 File 对象;也可以是表示 PDF 文件路径的字符
# 初始化一个Reader对象
# pdfReader = PyPDF2.PdfFileReader(stream=open(file='pdf2.pdf', mode='rb'))
pdfReader = PyPDF2.PdfFileReader('pdf2.pdf')
PdfFileReader对象的一些属性和方法:
属性 | 说明 |
---|---|
documentInfo | 获取PDF文件的文档信息字典 |
isEncrypted | PDF文件是否加密 |
numPages | 返回PDF文件的页数 |
pages | 相当于返回PDF文件所有页面,每个页面pageObject对象的列表 |
pageLayout | 获取PDF文件的页面布局 |
pageMode | 获取PDF文件的页面模式 |
xmpMetadata | 从PDF文件根目录检索XMP数据 |
方法 | 说明 |
---|---|
decrypt(password) | 解密 |
getDocumentInfo() | 同documentInfo属性 |
getNumPages() | 同numPages 属性 |
getPage(pageNumber) | 获取PDF文件中第pageNumber+1页的PageObject对象 pageNumber基于0 |
getPageLayout() | 同pageLayout属性 |
getPageMode() | 同pageMode属性 |
getPageNumber(page) | 获取 PageObject对象所在PDFFileReader对象的页数 |
getXmpMetadata() | 同xmpMetadata属性 |
简单示例:
# 返回 PDF 文件的文档信息字典
print('PDF 文件的文档信息字典:', pdfReader.getDocumentInfo(), pdfReader.documentInfo)
# 返回PDF文件的页数
print('PDF文件的页数:', pdfReader.getNumPages(), pdfReader.numPages)
# PageObject = PdfFileReader.getPage(pageNumber)
# 获取PdfFileReader中第pageNumber+1页的PageObject对象 pageNumber基于0
page_obj = pdfReader.getPage(1)
print(type(page_obj))
# 获取 PageObject对象 所在PDFFileReader对象的页数 如果找不到页面 返回 -1
print('page_obj所在的页数:', pdfReader.getPageNumber(page=page_obj))
# 获取页面布局 返回当前使用的页面布局
print('获取页面布局:', pdfReader.getPageLayout())
# 获取页面模式 返回 当前使用的页面模式
print('获取页面模式:', pdfReader.getPageMode())
# 从 PDF 文档根目录检索 XMP 数据
print('检索 XMP 数据:', pdfReader.getXmpMetadata())
# 判断该PDF是否加密
print('判断该PDF是否加密:', pdfReader.isEncrypted)
# PDFFileReader的每页pageObject的list?
print(type(pdfReader.pages))
PyPDF2.PdfFileWriter
PdfFileWriter 用于写出PDF文件,通常由PdfFileReader生成的页面
import PyPDF2
pdfWriter = PyPDF2.PdfFileWriter()
主要方法:
方法 | 说明 |
---|---|
addPage(page) | 向此 PdfFileWriter 添加页面 该页面通常是从一个PdfFileReader实例中获取的 |
addBlankPage(width=None, height=None) | 追加一个空白页 |
insertBlankPage(width=None, height=None, index=0) | 将空白页插入此PdfFileWriter的指定页码并返回此页面的PageObject对象 |
insertPage(page, index=0) | 在此 PdfFileWriter中的指定位置插入一个pageObject对象,该页面通常是从一个 PdfFileReader实例中获取的,默认在最开始插入 |
getNumPages() | 获取PdfFileWrite中已有pageObject的页数 |
getPage(pageNumber) | 获取PdfFileWrite中指定页码的pageObject对象 |
addAttachment(fname, fdata) | 在PdfFileWriter 中嵌入文件 |
addBookmark(title, pagenum, parent=None, color=None, bold=False, italic=False, fit=’/Fit’, *args) | 添加书签 |
addJS(javascript) | 添加javascript代码 |
addLink(pagenum, pagedest, rect, border=None, fit=’/Fit’, *args) | 添加 超链接 |
addMetadata(infos) | 添加 Metadata |
encrypt(user_pwd, owner_pwd=None, use_128bit=True) | 添加密码 |
removeImages(ignoreByteStringObject=False) | 从此PdfFileWriter中删除图像 |
removeLinks() | 从此PdfFileWriter中删除链接和注释 |
setPageLayout(layout) | 设置页面布局 |
getPageLayout() | 获取页面布局 PdfFileWriter.pageLayout |
setPageMode(mode) | 设置页面模式 对应属性 PdfFileWriter.pageMode |
getPageMode() | 获取页面模式 |
write(stream) | 将添加到PdfFileWriter对象的所有页面 写入PDF文件 |
示例代码:
addPage 方法
# addPage 向此 PDF 文件添加页面 该页面通常是从一个PdfFileReader实例中获取的
for page in pdfReader.pages:
pdfWriter.addPage(page)
addBlankPage方法:
# addBlankPage(width=None, height=None) 追加一个空白页,如果没有指定width|height,则使用上一页的width|height
# 如果没有指定width|height并且也没有上一页 raise PageSizeNotDefinedError
pdfWriter.addBlankPage(width=None, height=None)
insertBlankPage方法:
# insertBlankPage 将空白页插入此 PDF 文件并返回此页面的PageObject对象
# insertBlankPage(width=None, height=None, index=0) 默认在最开始添加
pdfWriter.insertBlankPage()
insertPage方法:
# insertPage(page, index=0)
# 在此 PDF 文件中插入一个pageObject对象。该页面通常是从一个 PdfFileReader实例中获取的
# index指定插入位置 默认再最开始插入
# page_obj 从PdfFileReader中获取
pdfWriter.insertPage(page=page_obj, index=0)
getNumPages方法:
# getNumPages() PDF文件页数
print(pdfWriter.getNumPages())
getPage方法:
# getPage(pageNumber) 获取PdfFileWriter中第pageNumber+1页的PageObject对象 pageNumber基于0
page_obj_f_writer = pdfWriter.getPage(0)
addAttachment方法:
# addAttachment(fname, fdata) 在 PDF 中嵌入文件
# pdfWriter.addAttachment(fname="附件一.txt", fdata=b'Hello world!')
pdfWriter.addAttachment(fname="Attachment.txt", fdata=('Hello world!').encode(encoding='UTF-8'))
addBookmark方法:
# addBookmark(title, pagenum, parent=None, color=None, bold=False, italic=False, fit='/Fit', *args) 添加书签
# Parameters:
# title 书签的标题
# pagenum 书签对应的页码
# parent 对父书签的引用以创建嵌套书签
# color (tuple) 书签的颜色 Color of the bookmark as a red, green, blue tuple from 0.0 to 1.0
# bold (bool) 字体是否粗体
# italic (bool) 字体是否斜体
# fit 页面适合或“缩放”选项
pdfWriter.addBookmark(title="Mark", pagenum=0, color=(0.0, 0.5, 1.0), bold=True, italic=True, fit='/Fit')
addJS方法:
# addJS(javascript) 打开PDF时运行javascript代码 官网实例
pdfWriter.addJS("this.print({bUI:true,bSilent:false,bShrinkToFit:true});")
addLink 方法:
# addLink 添加从矩形区域到指定页面的内部链接 超链接?
# addLink(pagenum, pagedest, rect, border=None, fit='/Fit', *args)
# Parameters:
# pagenum (int) 放置链接的页面的索引
# pagedest (int) 链接指向的页面的索引
# rect RectangleObject对象 or array of four integers specifying the clickable rectangular area [xLL, yLL, xUR, yUR],
# or string in the form "[ xLL yLL xUR yUR ]".
# border 描述边框绘制的数组
# fit (str) 页面适合或“缩放”选项 默认 '/Fit'
# fit 取值:
# /Fit No additional arguments
# /XYZ [left] [top] [zoomFactor]
# /FitH [top]
# /FitV [left]
# /FitR [left] [bottom] [right] [top]
# /FitB No additional arguments
# /FitBH [top]
# /FitBV [left]
# from PyPDF2.generic import RectangleObject
# pdfWriter.addLink(pagenum=2, pagedest=1, rect=RectangleObject([100, 100, 600, 800]))
pdfWriter.addLink(pagenum=0, pagedest=1, rect=[100, 100, 600, 800])
addMetadata方法:
# addMetadata(infos) 添加 Metadata
# infos 一个Python字典,其中每个键是一个字段,每个值是Metadata
pdfWriter.addMetadata(infos={'/Producer': 'Mark'})
encrypt方法:
# encrypt 使用 PDF 标准加密处理程序加密此 PDF 文件
# encrypt(user_pwd , owner_pwd=None , use_128bit=True)
pdfWriter.encrypt(user_pwd='password', owner_pwd='password')
write方法:
# write(stream) 将添加到PdfFileWriter对象的所有页面 写入PDF文件
with open('output.pdf', mode='wb') as output:
pdfWriter.write(output)
PdfFileMerger对象可以将多个PDF文件通过任意组合合并到一起;是专门用来将多个PDF进行合并的,PdfFileMerger对象能实现的基本上PdfFileWriter对象也能实现
初始化PdfFileMerger对象:
import PyPDF2
# PyPDF2.PdfFileMerger(strict=True)
# PdfFileMerger对象可以将多个PDF文件通过任意组合合并到一起
# 初始化PdfFileMerger对象
pdfMerger = PyPDF2.PdfFileMerger(strict=False)
常用方法:
方法 | 说明 |
---|---|
append(fileobj, bookmark=None, pages=None, import_bookmarks=True) | 将fileobj所有页面连接到文件末尾 |
merge(position, fileobj, bookmark=None, pages=None, import_bookmarks=True) | 将给定fileobj中的页面合并到指定页码 |
write(fileobj) | 将所有已合并的数据写入fileobj文件 |
close() | 关闭并清除所有内存使用 |
addBookmark(title, pagenum, parent=None) | 添加书签 |
addMetadata(infos) | 添加Metadata |
setPageLayout(layout) | 设置页面布局 |
setPageMode(mode) | 设置页面模式 |
addNamedDestination |
代码示例:
append方法:
# 向PdfFileMerger对象末尾添加PDF文件
# append(fileobj, bookmark=None, pages=None, import_bookmarks=True)
# 直接指定PDF文件的路径追加到pdfMerger
pdfMerger.append(fileobj='pdf3.pdf')
# 使用PdfFileReader对象进行追加
pdfMerger.append(pdfReader)
# write(fileobj)
pdfMerger.write('output.pdf')
# close()
# 关闭所有文件描述符(输入和输出)并清除所有内存使用
pdfMerger.close()
merge方法:
# merge(position, fileobj, bookmark=None, pages=None, import_bookmarks=True)
# 参数 :
# position 合并到PdfFileMerger对象的位置
# fileobj 要合并的PDF文件或者PdfFileReader对象
# pages 一个tuple 表示要合并的fileobj的页码范围
pdfMerger.merge(position=1, fileobj=pdfReader, pages=(0, 1))
# write(fileobj)
pdfMerger.write('output.pdf')
# close()
# 关闭所有文件描述符(输入和输出)并清除所有内存使用
pdfMerger.close()
PageObject对象表示 PDF 文件中的单个页面,PageObject对象的一些方法主要来实现对PDF页面进行操作,比如添加水印,页面的旋转,缩放等功能
PageObject对象通常通过访问PdfFileReader对象的 getPage()方法来生成:
import PyPDF2
# PyPDF2.pdf.PageObject
# PyPDF2.pdf.PageObject(pdf=None,indirectRef=None)
pdf_reader_1 = PyPDF2.PdfFileReader(stream="pdf1.pdf")
page_obj_1 = pdf_reader_1.getPage(0)
常用的一些方法:
方法 | 说明 |
---|---|
extractText() | 提取页面文本 |
getContents() | 返回页面内容 |
mergePage(page2) | 将两个页面的内容合并为一个,可以实现水印效果 |
mergeRotatedPage(page2, rotation, expand=False) | 类似mergePage方法,可以对page2页面进行旋转操作 |
mergeScaledPage(page2, scale, expand=False) | 类似mergePage方法,可以对page2页面进行缩放操作 |
mergeTranslatedPage(page2, tx, ty, expand=False) | 类似mergePage方法,可以对page2页面进行平移操作 |
mergeRotatedScaledPage(page2, rotation, scale, expand=False) | 类似mergePage方法,可以对page2页面进行旋转以及缩放操作 |
mergeRotatedScaledTranslatedPage(page2, rotation, scale, tx, ty, expand=False) | 类似mergePage方法,可以对page2页面进行旋转、缩放以及平移操作 |
mergeRotatedTranslatedPage(page2, rotation, tx, ty, expand=False) | 类似mergePage方法,可以对page2页面进行旋转以及平移操作 |
mergeScaledTranslatedPage(page2, scale, tx, ty, expand=False) | 类似mergePage方法,可以对page2页面进行缩放以及平移操作 |
mergeTransformedPage(page2, ctm, expand=False) | 类似mergePage方法,可以对page2页面进行矩阵转换操作 |
rotateClockwise(angle) | 顺时针旋转页面,angle必须是 90 度的增量 |
rotateCounterClockwise(angle) | 逆时针旋转页面,angle必须是 90 度的增量 |
scale(sx, sy) | 缩放页面 |
scaleBy(factor) | 按固定XY轴比例缩放页面 |
scaleTo(width, height) | 页面缩放到指定尺寸 |
addTransformation(ctm) | 将转换矩阵应用于页面 |
最后附上一个实例:
获取某目录下所有PDF文件 合并到一个PDF文件 并为合并后的PDF文件所有页面添加水印
import os
import PyPDF2
def get_PDFs(path):
"""
:param path: 需要合并的PDF文件所在路径
:return: 路径下所有PDF文件的路径list
"""
return [os.path.join(path, x) for x in os.listdir(path) if os.path.splitext(x)[-1] == '.pdf']
def merge_pdf(output_pdf, page2_pdf, *pdf_objs):
"""
获取某目录下所有PDF文件 合并到一个PDF文件 并为合并后的PDF文件所有页面添加水印
:param output_pdf: 合并后的PDF文件
:param page2_pdf: 水印模板PDF文件
:param pdf_objs:需要合并的所有PDF文件
:return:None
"""
output_path = os.path.dirname(output_pdf)
if not os.path.exists(output_path):
os.makedirs(output_path, exist_ok=True)
pdf_writer = PyPDF2.PdfFileWriter()
pdf_reader = PyPDF2.PdfFileReader(stream=page2_pdf)
# 获取水印模板PDF文件对应的pageObject对象
page2 = pdf_reader.getPage(0)
for pdf in pdf_objs:
pdf_reader = PyPDF2.PdfFileReader(stream=pdf)
for page in pdf_reader.pages:
# 添加水印
merge_page(page, page2)
# 添加水印后的页面添加到PdfFileWriter
pdf_writer.addPage(page)
with open(output_pdf, "wb") as output:
pdf_writer.write(output)
def merge_page(page, page2):
"""
:param page: 需要添加水印的PDF页面
:param page2: 水印模板
:return:None
"""
page.mergeRotatedScaledTranslatedPage(page2, rotation=45, scale=0.5, tx=100, ty=100, expand=True)
if __name__ == '__main__':
pdf_objs = get_PDFs('./')
output_pdf = "./output/output.pdf"
page2_pdf = "pdf1.pdf"
merge_pdf(output_pdf, page2_pdf, *pdf_objs)
主要参考:PyPDF2 文档
以上就是对PyPDF2库的学习
如果有什么不对的地方,欢迎指正!