Python PDF神器PyMuPDF使用指南 (六)——Document类详解

系列文章:

Python PDF神器PyMuPDF使用指南 (一)——安装和基础功能

Python PDF神器PyMuPDF使用指南 (二)——文件和文本功能

Python PDF神器PyMuPDF使用指南 (三)——图像和注释功能

Python PDF神器PyMuPDF使用指南 (四)——绘图、多线程和OCR功能

Python PDF神器PyMuPDF使用指南 (五)——命令行使用

Python PDF神器PyMuPDF使用指南 (六)——Document类详解

Python PDF神器PyMuPDF使用指南 (七)——Page类详解

Python PDF神器PyMuPDF使用指南 (八)——基础使用指南


正文:

PyMuPDF是一个高性能的Python库,用于PDF(和其他)文档的数据提取、分析、转换和操作。

Github地址为:pymupdf代码库

官方文档地址为:PyMuPDF文档

前面几篇文章详细介绍了PyMuPDF的主要功能以及命令行的使用,本文将开始介绍PyMuPDF做为Python库调用的主要类和方法。不过篇幅原因,估计只能详细介绍一部分,下一篇文章会继续介绍。

Document类概述

概述

这个类表示一个文档。它可以通过文件或内存来构建,并对文档进行各种操作。

这个类有别名open,即pymupdf.Document(...)pymupdf.open(...)是等效的。

注意“”
从v1.17.0版本开始,仅支持对EPUB文件的全新页面定位机制。该文档类型内部按章节组织,页面可以通过其所谓的“位置”来高效查找。位置是一个元组(章节,页码),由章节号和该章节中的页码组成。两个数字都是基于零的。
虽然仍然可以通过页面的(绝对)编号定位页面,但这可能意味着必须先布局整个EPUB文档才能定位该页面。如果文档非常大,这可能会显著影响性能。使用页面的(章节,页码)可以避免这种情况。
为了保持一致的API,PyMuPDF支持所有文件类型的页面位置语法——没有此功能的文档则只有一个章节。 Document.load_page()和等效的索引访问现在也支持位置参数。
有很多方法可以在页面编号和位置之间进行转换,用于确定章节数量、每个章节的页面数量、计算下一个和前一个位置,以及文档的最后一个页面位置。

核心API 概况

  • Document.add_layer():仅限PDF:创建新的可选内容配置
  • Document.add_ocg():仅限PDF:添加新的可选内容组
  • Document.authenticate():访问加密文档
  • Document.bake():仅限PDF:将注释/字段转化为永久内容
  • Document.can_save_incrementally():检查是否可以增量保存
  • Document.chapter_page_count():章节中的页面数量
  • Document.close():关闭文档
  • Document.convert_to_pdf():将文档转换为PDF格式并写入内存
  • Document.copy_page():仅限PDF:复制页面引用
  • Document.del_toc_item():仅限PDF:删除单个目录项
  • Document.delete_page():仅限PDF:删除页面
  • Document.delete_pages():仅限PDF:删除多页
  • Document.embfile_add():仅限PDF:从缓冲区添加新嵌入文件
  • Document.embfile_count():仅限PDF:嵌入文件的数量
  • Document.embfile_del():仅限PDF:删除嵌入文件条目
  • Document.embfile_get():仅限PDF:提取嵌入文件缓冲区
  • Document.embfile_info():仅限PDF:获取嵌入文件的元数据
  • Document.embfile_names():仅限PDF:列出嵌入文件
  • Document.embfile_upd():仅限PDF:修改嵌入文件
  • Document.extract_font():仅限PDF:按xref提取字体
  • Document.extract_image():仅限PDF:按xref提取嵌入的图像
  • Document.ez_save():仅限PDF:默认不同的保存文档
  • Document.find_bookmark():查找书签并返回其页面位置
  • Document.fullcopy_page():仅限PDF:复制页面
  • Document.get_layer():仅限PDF:列出OCG的状态(开、关、待渲染组)
  • Document.get_layers():仅限PDF:列出可选内容配置
  • Document.get_oc():仅限PDF:获取OCG/OCMD xref的图像/表单xobject
  • Document.get_ocgs():仅限PDF:获取所有可选内容组信息
  • Document.get_ocmd():仅限PDF:获取OCMD的定义
  • Document.get_page_fonts():仅限PDF:列出页面引用的字体
  • Document.get_page_images():仅限PDF:列出页面引用的图像
  • Document.get_page_labels():仅限PDF:列出页面标签定义
  • Document.get_page_numbers():仅限PDF:获取具有指定标签的页面编号
  • Document.get_page_pixmap():根据页面编号创建页面图像
  • Document.get_page_text():提取指定页面的文本
  • Document.get_page_xobjects():仅限PDF:列出页面引用的XObject
  • Document.get_sigflags():仅限PDF:确定签名状态
  • Document.get_toc():提取目录
  • Document.get_xml_metadata():仅限PDF:读取XML元数据
  • Document.has_annots():仅限PDF:检查文档是否包含注释
  • Document.has_links():仅限PDF:检查文档是否包含链接
  • Document.insert_page():仅限PDF:插入新页面
  • Document.insert_pdf():仅限PDF:从另一个PDF插入页面
  • Document.insert_file():仅限PDF:从任意文档插入页面
  • Document.journal_can_do():仅限PDF:哪些操作可以在文档中进行
  • Document.journal_enable():仅限PDF:启用文档的日志功能
  • Document.journal_load():仅限PDF:从文件加载日志
  • Document.journal_op_name():仅限PDF:返回日志步骤的名称
  • Document.journal_position():仅限PDF:返回日志状态
  • Document.journal_redo():仅限PDF:重做当前操作
  • Document.journal_save():仅限PDF:保存日志到文件
  • Document.journal_start_op():仅限PDF:开始“操作”并为其命名
  • Document.journal_stop_op():仅限PDF:结束当前操作
  • Document.journal_undo():仅限PDF:撤销当前操作
  • Document.layer_ui_configs():仅限PDF:列出可选内容的意图配置
  • Document.layout():重新分页文档(如果支持)
  • Document.load_page():读取页面
  • Document.make_bookmark():在可重排文档中创建页面指针
  • Document.move_page():仅限PDF:移动页面到文档中的不同位置
  • Document.need_appearances():仅限PDF:获取/设置NeedAppearances属性
  • Document.new_page():仅限PDF:插入新空白页面
  • Document.next_location():返回下一页的位置(章节,页码)
  • Document.outline_xref():仅限PDF:目录项的xref
  • Document.page_cropbox():仅限PDF:页面的未旋转矩形区域
  • Document.page_xref():仅限PDF:页面编号的xref
  • Document.pages():页面范围的迭代器
  • Document.pdf_catalog():仅限PDF:xref of catalog (root)
  • Document.pdf_trailer():仅限PDF:文档的尾部源
  • Document.prev_location():返回前一页的位置(章节,页码)
  • Document.reload_page():仅限PDF:提供页面的新副本
  • Document.resolve_names():仅限PDF:将目标名称转换为Python字典
  • Document.save():仅限PDF:保存文档
  • Document.saveIncr():仅限PDF:增量保存文档
  • Document.scrub():仅限PDF:去除敏感数据
  • Document.search_page_for():在页面上搜索字符串
  • Document.select():仅限PDF:选择页面的子集
  • Document.set_layer_ui_config():仅限PDF:暂时设置OCG的可见性
  • Document.set_layer():仅限PDF:批量改变OCG的状态
  • Document.set_markinfo():仅限PDF:设置MarkInfo值
  • Document.set_metadata():仅限PDF:设置元数据
  • Document.set_oc():仅限PDF:将OCG/OCMD附加到图像/表单xobject
  • Document.set_ocmd():仅限PDF:创建或更新OCMD
  • Document.set_page_labels():仅限PDF:添加/更新页面标签定义
  • Document.set_pagemode():仅限PDF:设置页面模式
  • Document.set_pagelayout():仅限PDF:设置页面布局
  • Document.set_toc_item():仅限PDF:修改单个目录项
  • Document.set_toc():仅限PDF:设置目录
  • Document.set_xml_metadata():仅限PDF:创建或更新XML元数据
  • Document.subset_fonts():仅限PDF:创建字体子集
  • Document.switch_layer():仅限PDF:激活OC配置
  • Document.tobytes():仅限PDF:将文档写入内存
  • Document.xref_copy():仅限PDF:将PDF字典复制到另一个xref
  • Document.xref_get_key():仅限PDF:获取字典键的值
  • Document.xref_get_keys():仅限PDF:列出xref对象的键
  • Document.xref_object():仅限PDF:获取xref对象的定义源

Document类详情

__init__(self, filename=None, stream=None, *, filetype=None, rect=None, width=0, height=0, fontsize=11)

自 v1.14.13 起:支持 io.BytesIO 用于内存中的文档。

自 v1.19.6 起:更清晰、更简洁且一致的异常信息。如果未指定文件类型,始终假定文件类型为“pdf”。空文件和内存区域将始终引发异常。

用于创建一个 Document 对象。

在默认参数下,将创建一个新的空 PDF 文档。

  • 如果提供了 stream,则从内存中创建文档,如果它不是 PDF,则 filename 或 filetype 必须指明其类型。
  • 如果 stream 为 None,则从指定的 filename 文件创建文档,其类型通过扩展名推断。也可以通过 filetype 来覆盖此行为。

参数说明:

  • filename (str, pathlib) – 一个 UTF-8 字符串或 pathlib 对象,表示文件路径。文档类型通过文件名扩展名推断。如果没有提供或扩展名不匹配支持的类型,则假定为 PDF 文档。对于内存文档,可以使用此参数代替 filetype(见下文)。
  • stream (bytes, bytearray, BytesIO) – 一个包含支持文档的内存区域。如果不是 PDF,则其类型必须通过 filename 或 filetype 指定。
  • filetype (str) – 一个字符串,指定文档类型。可以是类似文件名的字符串(例如 "x.pdf"),在这种情况下,MuPDF 使用扩展名来确定类型,或者像 application/pdf 这样的 MIME 类型。像 "pdf" 或 ".pdf" 的字符串也可以使用。对于 PDF 文档,可以省略此参数;否则,必须匹配支持的文档类型。
  • rect (rect_like) – 一个矩形,指定所需的页面大小。此参数仅对具有可变页面布局(如电子书或 HTML)的文档有意义,其他情况下将被忽略。如果指定,它必须是一个非空且有限的矩形,左上角坐标为 (0, 0)。与 fontsize 参数一起,每个页面将根据该布局进行排版,并且还会决定页面数量。
  • width (float) – 与 height 一起使用,作为 rect 的替代方案来指定布局信息。
  • height (float) – 与 width 一起使用,作为 rect 的替代方案来指定布局信息。
  • fontsize (float) – 可变文档类型的默认字体大小。如果没有指定 rect 或 width 和 height 参数,则忽略此参数。此参数用于计算页面布局。

异常:

  • TypeError – 如果任何参数的类型不符合要求。
  • FileNotFoundError – 如果文件/路径无法找到。已重新实现为 RuntimeError 的子类。
  • EmptyFileError – 如果文件/路径为空或内存中的字节对象长度为零。是 FileDataError 和 RuntimeError 的子类。
  • ValueError – 如果显式指定了一个未知的文件类型。
  • FileDataError – 如果文档的结构无效,或者根本不是文件(例如文件夹)。是 RuntimeError 的子类。

返回:

返回一个文档对象。如果无法创建文档,则会按上述顺序抛出异常。请注意,PyMuPDF 特定的异常 FileNotFoundErrorEmptyFileError 和 FileDataError 会在检查 RuntimeError 时被拦截。

遇到问题时,可以查看更详细的内部消息存储:print(pymupdf.TOOLS.mupdf_warnings())(此调用将清空警告,但也可以防止清空——请参考 Tools.mupdf_warnings())。

注意:并非所有文档类型在打开时都检查其有效格式。例如,光栅图像将在稍后访问其内容时才会抛出异常。其他类型(尤其是具有非二进制内容的类型)也可以被成功打开(有时甚至在格式内容无效的情况下):
HTM, HTML, XHTML:始终可以打开, metadata["format"] 将分别为“HTML5”和“XHTML”。
XML, FB2:始终可以打开, metadata["format"] 为“FictionBook2”。

可能的打开方式概览:

>>> # from a file
>>> doc = pymupdf.open("some.xps")
>>> # handle wrong extension
>>> doc = pymupdf.open("some.file", filetype="xps")
>>>
>>> # from memory, filetype is required if not a PDF
>>> doc = pymupdf.open("xps", mem_area)
>>> doc = pymupdf.open(None, mem_area, "xps")
>>> doc = pymupdf.open(stream=mem_area, filetype="xps")
>>>
>>> # new empty PDF
>>> doc = pymupdf.open()
>>> doc = pymupdf.open(None)
>>> doc = pymupdf.open("")
注意:光栅图像即使文件扩展名错误(但仍是支持的类型)也不会有问题。MuPDF 会在实际访问文件内容时确定正确的图像类型并处理它。因此, pymupdf.open("file.jpg") 即使是 PNG 图像也能正常工作。

Document 类还可以作为上下文管理器使用。在退出时,文档会自动关闭。

>>> import pymupdf
>>> with pymupdf.open(...) as doc:
        for page in doc: print("page %i" % page.number)
page 0
page 1
page 2
page 3
>>> doc.is_closed
True
>>>

get_oc(xref)

(新功能:v1.18.4)

返回与图像或表单 XObject 关联的 OCG 或 OCMD 的交叉引用号。

参数:

  • xref (int) – 图像或表单 XObject 的交叉引用号。有效的交叉引用号可以通过 Document.get_page_images() 或 Document.get_page_xobjects() 获取。如果是无效的交叉引用号,将引发异常。

返回:

  • int – 如果存在与图像或表单 XObject 关联的可选内容对象,返回其交叉引用号;如果没有,返回零。

set_oc(xref, ocxref)

(新功能:v1.18.4)

如果 xref 代表一个图像或表单 XObject,设置或移除其关联的可选内容对象的交叉引用号。

参数:

  • xref (int) – 图像或表单 XObject 的交叉引用号。
  • ocxref (int) – OCG 或 OCMD 的交叉引用号。如果为零,则移除所有 OC 引用;如果不为零,则会引发异常。

get_layers()

(新功能:v1.18.3)

显示可选层配置。始终存在一个标准层,不会包含在响应中。

>>> for item in doc.get_layers(): print(item)
{'number': 0, 'name': 'my-config', 'creator': ''}
>>> # use 'number' as config identifier in add_ocg

add_layer(name, creator=None, on=None)

(新功能:v1.18.3)

添加一个可选内容配置。层配置作为 ON/OFF 状态的集合,可以在文档中快速切换不同的视图。

参数:

  • name (str) – 任意名称。
  • creator (str) – (可选)创建软件。
  • on (sequ) – 一个 OCG xref 号的序列,指定激活此层时应设置为 ON 的 OCG。如果没有列出,所有 OCG 都将设置为 OFF。

switch_layer(number, as_default=False)

(新功能:v1.18.3)

切换到由指定可选层配置定义的文档视图。此切换是临时的,除非将其设为默认视图。

参数:

  • number (int) – 配置号,来自 Document.layer_configs()
  • as_default (bool) – 如果为 True,则将此配置设为默认配置。

add_ocg(name, config=-1, on=True, intent='View', usage='Artwork')

(新功能:v1.18.3)

添加一个可选内容组(OCG)。OCG 是决定对象可见性的最重要单位。对于 PDF,必须至少存在一个 OCG 才能被视为具有可选内容。

参数:

  • name (str) – 任意名称,显示在支持的 PDF 查看器中。
  • config (int) – 层配置号,默认值为 -1(标准配置)。
  • on (bool) – 指定 OCG 对象的标准可见性状态。
  • intent (str, list) – 字符串或字符串列表,声明 OCG 的可见性意图。可以选择 PDF 标准值:“View”和“Design”。
  • usage (str) – 另一个影响 OCG 可见性的因素。标准值:“Artwork”和“Technical”。默认是“Artwork”。

返回:

返回创建的 OCG 的交叉引用号。可以用作在支持的对象中作为 oc 参数的入口。

注意:可以创建多个具有相同参数的 OCG,它们不会导致问题。 Document.save() 的垃圾选项 3 将删除任何重复项。

set_ocmd(xref=0, ocgs=None, policy='AnyOn', ve=None)

新增于 v1.18.4

创建或更新 OCMD(可选内容成员字典)。

参数:

  • xref (int) – 要更新的 OCMD 的 xref,或者使用 0 来创建一个新的 OCMD。
  • ocgs (list) – 一个包含现有 OCG PDF 对象的 xref 编号的序列。
  • policy (str) – 策略类型,可以是以下之一:"AnyOn"(默认)、"AnyOff""AllOn""AllOff"(支持大小写)。
  • ve (list) – "可见性表达式"。这是一个包含任意嵌套子列表的列表(详见说明)。如果需要制定更复杂的条件,可以作为 ocgs 和 policy 的替代方法。

返回类型:

  • int:返回 OCMD 的 xref。可以将其作为 oc=xref 参数,传递给支持的对象,进一步用于 Document.set_oc() 或 Annot.set_oc()
注意:OCMD 和 OCG 一样,具有开/关状态,并且可以像 OCG 一样使用。与 OCG 不同的是,OCMD 的状态是通过评估一个或多个 OCG 的状态,使用特殊的布尔表达式来决定的。如果表达式结果为真,则 OCMD 的状态为 ON,否则为 OFF。
有两种方法来制定 OCMD 的可见性:
1. 使用 ocgs 和 policy 的组合:政策值的含义如下:
1)AnyOn –(默认)如果至少有一个 OCG 是 ON,则为 true。
2)AnyOff – 如果至少有一个 OCG 是 OFF,则为 true。
3)AllOn – 如果所有 OCG 都是 ON,则为 true。
4)AllOff – 如果所有 OCG 都是 OFF,则为 true。
假设你希望两个 PDF 对象同时显示,且在一个对象是 ON 时,另一个必须是 OFF: 解决方案:为对象 1 使用一个 OCG,为对象 2 使用 OCMD。创建 OCMD,使用  set_ocmd(ocgs=[xref], policy="AllOff"),并将 OCG 的 xref 提供给 OCMD。
2. 使用可见性表达式(ve):这是一个包含两个或更多项的列表。第一项是逻辑关键词:可以是  “and”“or” 或  “not”。第二项及其后的项必须是整数或另一个列表。整数应为 OCG 的 xref。列表必须符合先前的规则。
示例:
1) set_ocmd(ve=["or", 4, ["not", 5], ["and", 6, 7]])。这表示当下列条件为真时,OCMD 为 ON: 4 是 ON,或者 5 是 OFF,或者 6 和 7 都是 ON
2) set_ocmd(ve=["not", xref])。这与使用 ocgs 和 policy 创建 OCMD 时的效果相同。
有关详细信息和示例,请参见  Adobe PDF 参考手册第 224 页。还可以查看 此处的示例脚本。
可见性表达式(/VE)是 PDF 规范 1.6 版本的一部分,因此并非所有 PDF 查看器/阅读器都已支持此功能。因此,在这些查看器中可能会以标准方式进行处理。

get_ocmd(xref)

新增于 v1.18.4

检索 OCMD 的定义。

参数:

  • xref (int) – OCMD 的 xref。

返回类型:

  • dict:返回一个字典,包含 xrefocgspolicy 和 ve 键。

get_layer(config=-1)

新增于 v1.18.3

列出指定配置中的可选内容组及其状态。这是一个字典,包含在数组 /ON/OFF 或某些单选按钮组(/RBGroups)中的 OCG 的 xref 列表。

参数:

  • config (int) – 配置层(默认值是标准配置层)。

示例:

>>> pprint(doc.get_layer())
{'off': [8, 9, 10], 'on': [5, 6, 7], 'rbgroups': [[7, 10]]}
>>> 

set_layer(config, *, on=None, off=None, basestate=None, rbgroups=None, locked=None)

新增于 v1.18.3,v1.22.5 中更新:支持锁定 OCG 的列表

批量更改可选内容组的状态。永久设置 OCG 的状态。

参数:

  • config (int) – 所需的配置层,使用 -1 表示默认配置层。
  • on (list) – 要设置为 ON 的 OCG xref 列表。会替换之前的值。如果 basestate="ON",则必须指定此项。
  • off (list) – 要设置为 OFF 的 OCG xref 列表。会替换之前的值。如果 basestate="OFF",则必须指定此项。
  • basestate (str) – 未在 on 或 off 中提及的 OCG 的状态。可能的值有 “ON”、“OFF” 或 “Unchanged”。支持大小写。
  • rbgroups (list) – 子列表的列表,替换之前的值。每个子列表应包含两个或更多 OCG xref。属于同一子列表的 OCG 会像单选按钮组一样处理:将一个设置为 ON,自动将其他组成员设置为 OFF。
  • locked (list) – 一个包含 OCG xref 编号的列表,表示无法通过用户界面更改。

示例:

>>> doc.set_layer(-1, basestate="OFF")  # only changes the base state
>>> pprint(doc.get_layer())
{'basestate': 'OFF', 'off': [8, 9, 10], 'on': [5, 6, 7], 'rbgroups': [[7, 10]]}

get_ocgs()

新增于 v1.18.3

返回所有可选内容组的详细信息。这是一个字典,字典的键为 OCG 的 xref,值为另一个字典,包含相关的 OCG 信息。

示例:

>>> pprint(doc.get_ocgs())
{13: {'on': True,
      'intent': ['View', 'Design'],
      'name': 'Circle',
      'usage': 'Artwork'},
14: {'on': True,
      'intent': ['View', 'Design'],
      'name': 'Square',
      'usage': 'Artwork'},
15: {'on': False, 'intent': ['View'], 'name': 'Square', 'usage': 'Artwork'}}
>>>

layer_ui_configs()

新增于 v1.18.3

显示可以通过用户界面修改的可选内容的可见性状态。仅报告当前所选配置层中的项目。

返回的是一个包含字典的列表,每个字典表示一个项目的可见性信息。

字典字段含义:

  • depth:项目在 /Order 数组中的嵌套级别。
  • locked:如果无法通过用户界面更改,则为 true
  • number:项目的运行序号。
  • on:项目状态。
  • text:来源 OCG 的文本字符串或名称字段。
  • type:类型,可能为 “label”(由文本字符串设置)、"checkbox"(由单个 OCG 设置)或 “radiobox”(由一组连接的 OCG 设置)。

set_layer_ui_config(number, action=0)

新增于 v1.18.3

修改可选内容组的可见性状态。此方法类似于一些 PDF 查看器提供的用户界面功能。

参数:

  • number (int, str) – 项目在 Document.layer_configs() 中的序列号,或这些项目的“text”。
  • action (int) – PDF_OC_ON(设置为 ON,默认)、PDF_OC_TOGGLE(切换 ON/OFF)、PDF_OC_OFF(设置为 OFF)。

authenticate(password)

解密文档

使用提供的密码解密文档。如果成功,文档数据可以访问。对于 PDF 文档,"所有者"(owner)和"用户"(user)具有不同的权限,因此可能存在不同的密码来授权这两种角色。该方法会自动为提供的密码建立适当的访问权限(无论是所有者权限还是用户权限)。

参数:

  • password (str) – 所有者密码或用户密码。

返回类型:

  • int:如果成功,返回一个正值;否则返回零(表示密码与任何密码都不匹配)。如果返回值为正,则 Document.is_encrypted 设置为 False。正值的返回码包含以下信息:
    • 1 => 已认证,但 PDF 没有所有者密码或用户密码。
    • 2 => 使用用户密码认证。
    • 4 => 使用所有者密码认证。
    • 6 => 已认证,且两个密码相同——这可能是一个罕见情况。
注意:文档可能只有所有者密码,而没有用户密码。通过  doc.authenticate("") == 2 可以检测到这种情况。这允许在不进行身份验证的情况下打开并读取文档,但根据  Document.permissions 的值,其他操作可能会受到限制。与任何 PDF 查看器不同,PyMuPDF(像 MuPDF 一样)在这种情况下会忽略这些限制。因此,你可以提取文本或添加/修改内容,即使相关的权限标志如  PDF_PERM_COPYPDF_PERM_MODIFYPDF_PERM_ANNOTATE 等已关闭!构建符合法律合规要求的应用程序,仍然是你的责任。

get_page_numbers(label, only_one=False)

新增于 v1.18.6

仅限 PDF:返回具有指定标签的页面编号——请注意,标签在 PDF 中可能不是唯一的。这意味着要对所有页面编号进行顺序搜索,以比较它们的标签。

注意:实现细节:此方法不会加载页面。

参数:

  • label (str) – 要查找的标签,例如 “vii” (罗马数字 7)。
  • only_one (bool) – 在找到第一个匹配后停止查找。对于标签已知唯一,或有很多页面的情况非常有用。默认会检查每个页面编号。

返回类型:

  • list:返回一个包含所有具有此标签的页面编号的列表。如果未找到,返回空列表。

get_page_labels()

新增于 v1.18.7

仅限 PDF:提取页面标签定义的列表。通常在通过 Document.set_page_labels() 传入之前进行修改。

返回类型:

  • list:返回一个字典列表,每个字典定义了页面标签的设置。

set_page_labels(labels)

新增于 v1.18.6

仅限 PDF:添加或更新 PDF 的页面标签定义。

参数:

  • labels (list) – 标签的字典列表。每个字典定义了一个标签规则和一个 0 基的“起始”页面编号。该起始页面是规则开始应用的页面。每个字典最多包含 4 个条目,格式如下:python
    复制编辑
    {'startpage': int, 'prefix': str, 'style': str, 'firstpagenum': int}

字典项说明:

  • startpage (int):应用标签规则的第一个页面编号(0 基)。此项必须存在。该规则会应用到所有随后的页面,直到文档结束或被下一个更大页面编号的规则覆盖。
  • prefix (str):标签的前缀,可以是任意字符串,例如 “A-”。默认值为 “”。
  • style (str):编号样式。可以是以下之一:
    • D(十进制)
    • rR(罗马数字,大小写不敏感)
    • aA(字母数字编号:从 “a” 到 “z”,然后是 “aa” 到 “zz”等) 默认值是 “”。 如果为空,则不进行编号,标签将仅由前缀值组成。如果前缀也为空,则标签为 “”。
  • firstpagenum (int):开始编号的值。默认是 1,小于此值的会被忽略。

示例:

[{'startpage': 6, 'prefix': 'A-', 'style': 'D', 'firstpagenum': 10},
 {'startpage': 10, 'prefix': '', 'style': 'D', 'firstpagenum': 1}]

这将生成标签 “A-10”、 “A-11”、 “A-12”、 “A-13”、 “1”、 “2”、 “3”…,适用于第 6 页及之后的页面。第 0 至 5 页将没有标签(标签为空)。

make_bookmark(loc)

新增于 v1.17.3

在可重新布局的文档中返回一个页面指针。在重新布局文档后,可以使用此方法的结果来查找页面的新位置。

注意:

  • 请不要将此与目录中的项目(TOC)混淆。

参数:

  • loc (list, tuple) – 页面位置,必须是有效的 (chapter, pno)

返回类型:

  • pointer:返回一个长整型指针。该指针用于在重新布局文档后查找页面的新位置。请勿修改或重新分配。

find_bookmark(bookmark)

新增于 v1.17.3

返回重新布局文档后页面的新位置。

参数:

  • bookmark (pointer) – 使用 Document.make_bookmark() 创建的指针。

返回类型:

  • tuple:返回新位置的 (chapter, pno)

convert_to_pdf(from_page=-1, to_page=-1, rotate=0)

将当前文档转换为PDF并写入内存。所有文档类型都支持。参数与insert_pdf()相同。本质上,您可以限制转换的页面子集、指定页面旋转以及调整页面顺序。

  • from_page (int) – 要复制的第一页(从0开始)。默认是第一页。
  • to_page (int) – 要复制的最后一页(从0开始)。默认是最后一页。
  • rotate (int) – 旋转角度。默认值为0(不旋转)。应为整数n的倍数,即n * 90(未进行检查)。

返回类型bytes

返回: 一个Python字节对象,包含PDF文件图像。它是通过内部使用tobytes(garbage=4, deflate=True)创建的。您可以直接将其输出到磁盘或将其作为PDF打开。以下是一些示例:

# 将XPS文件转换为PDF
xps = pymupdf.open("some.xps")
pdfbytes = xps.convert_to_pdf()

# 可以这样做 -->
pdf = pymupdf.open("pdf", pdfbytes)
pdf.save("some.pdf")

# 或者这样 -->
pdfout = open("some.pdf", "wb")
pdfout.tobytes(pdfbytes)
pdfout.close()

# 将图像文件复制到PDF页面
# 每个页面将具有图像的尺寸
doc = pymupdf.open()                     # 新PDF文档
imglist = [ ... image file names ...]    # 例如图像文件目录
for img in imglist:
    imgdoc = pymupdf.open(img)           # 打开图像作为文档
    pdfbytes = imgdoc.convert_to_pdf()   # 将其转换为1页PDF
    imgpdf = pymupdf.open("pdf", pdfbytes)
    doc.insert_pdf(imgpdf)               # 插入图像PDF
doc.save("allmyimages.pdf")
注意:该方法使用与 mutool convert命令行相同的逻辑。在大多数情况下,它效果很好,但请注意以下限制:
1)图像文件: 完美,没有检测到问题。然而,图像的透明度会被忽略。如果您需要透明度(如水印),请使用 Page.insert_image()方法。否则,建议使用此方法,因为它具有更好的性能。
2)XPS: 外观非常好。链接正常工作,但书签(大纲)丢失,可以很容易恢复。
3)EPUB、CBZ、FB2: 与XPS类似。
4)SVG: 效果一般。大致与 svglib类似。

get_toc(simple=True)

创建一个文档的目录(TOC),从文档的大纲链中提取内容。

参数:

  • simplebool):指示是需要简单版还是详细版的目录。如果为 False,列表中的每一项都会包含一个字典,其中包括每个大纲项的 linkDest 详情。

返回类型:

  • list

返回值:

  • 返回一个包含列表的列表。每个列表项的格式是 [lvl, title, page, dest],每个项的含义如下:
    • lvl – 层级(正整数)。第一个条目总是 1。每一行的条目要么相等,要么递增 1,要么减少。
    • title – 标题(字符串)
    • page – 基于 1 的源页面编号(整数)。如果没有目标或超出文档范围,则为 -1。
    • dest – (仅当 simple=False 时包含)包含目录项的详情。包括以下内容:
      • kind:目标类型,参见链接目标类型。
      • file:如果 kind 为 LINK_GOTOR 或 LINK_LAUNCH,则为文件名。
      • page:目标页面,0 为基础,适用于 LINK_GOTOR 或 LINK_GOTO
      • to:目标页面上的位置(点)。
      • zoom:目标页面的缩放因子。
      • xref:项的 xref,如果没有 PDF,则为 0。
      • color:项目的颜色(PDF 中的 RGB 格式:红色、绿色、蓝色),如果没有 PDF,则省略。
      • bold:如果是粗体项文本,则为 true,如果没有则省略(仅限 PDF)。
      • italic:如果是斜体项文本,则为 true,如果没有则省略(仅限 PDF)。
      • collapse:如果子项被折叠,则为 true,如果没有则省略(仅限 PDF)。
      • nameddest:目标名称,如果 kind=4(PDF 仅限)。 (新功能,版本 1.23.7)

xref_get_keys(xref)

(新增于 v1.18.7)

仅限 PDF:返回由其 xref 编号提供的 PDF 字典对象的字典键。

参数:

  • xrefint):xref 编号(在 v1.18.10 中发生了变化)。使用 -1 来访问特殊字典“PDF trailer”。

返回类型:

  • tuple

返回值:

  • 返回一个包含字典键的元组。示例如下:
>>> from pprint import pprint
>>> import pymupdf
>>> doc=pymupdf.open("pymupdf.pdf")
>>> xref = doc.page_xref(0)  # xref of page 0
>>> pprint(doc.xref_get_keys(xref))  # primary level keys of a page
('Type', 'Contents', 'Resources', 'MediaBox', 'Parent')
>>> pprint(doc.xref_get_keys(-1))  # primary level keys of the trailer
('Type', 'Index', 'Size', 'W', 'Root', 'Info', 'ID', 'Length', 'Filter')
>>> 

xref_get_key(xref, key)

(新增于 v1.18.7)

仅限 PDF:返回给定 xref 的 PDF 字典键的类型和值。

参数:

  • xrefint):xref 编号(在 v1.18.10 中发生了变化)。使用 -1 来访问特殊字典“PDF trailer”。
  • keystr):所需的 PDF 键。必须完全匹配(区分大小写)Document.xref_get_keys() 中包含的键。

返回类型:

  • tuple

返回值:

一个元组(类型,值),其中类型是以下之一:“xref”、“array”、“dict”、“int”、“float”、“null”、“bool”、“name”、“string”或“unknown”(后者不应出现)。无论“类型”是什么,键的值始终以字符串格式呈现——请参见以下示例——并且(几乎总是)忠实地反映了PDF中存储的内容。在大多数情况下,值字符串的格式也能提供关于键类型的线索:

  • “name”总是以“/”斜杠开头。
  • “xref”总是以“ 0 R”结尾。
  • “array”总是被“[…]”括起来。
  • “dict”总是被“<<…>>”括起来。
  • “bool”或“null”始终等于“true”、“false”或“null”。
  • “float”和“int”由其字符串格式表示——因此它们不总是可区分的。
  • “string”会转换为UTF-8,因此可能与PDF中存储的内容有所不同。例如,PDF键“Author”可能在文件中的值为“”,但该方法将返回('string','Jorj X. McKie')。

示例:

>>> for key in doc.xref_get_keys(xref):
        print(key, "=" , doc.xref_get_key(xref, key))
Type = ('name', '/Page')
Contents = ('xref', '1297 0 R')
Resources = ('xref', '1296 0 R')
MediaBox = ('array', '[0 0 612 792]')
Parent = ('xref', '1301 0 R')
>>> #
>>> # Now same thing for the PDF trailer.
>>> # It has no xref, so -1 must be used instead.
>>> #
>>> for key in doc.xref_get_keys(-1):
        print(key, "=", doc.xref_get_key(-1, key))
Type = ('name', '/XRef')
Index = ('array', '[0 8802]')
Size = ('int', '8802')
W = ('array', '[1 3 1]')
Root = ('xref', '8799 0 R')
Info = ('xref', '8800 0 R')
ID = ('array', '[]')
Length = ('int', '21111')
Filter = ('name', '/FlateDecode')
>>> 

xref_set_key(xref, key, value)

新增功能: 从v1.18.7开始,v1.18.13做了更新。

v1.19.4更新: 如果设置值为“null”,则“物理”地删除该键。

仅限PDF: 设置(添加、更新、删除)给定xref的PDF字典对象的键值。

注意:这是一个专家级函数:如果你不知道自己在做什么,可能会导致PDF(部分)变得无法使用。请参考Adobe PDF参考文档,了解对象规范格式(第18页)以及像页面对象这样的特殊字典类型的结构。

参数:

  • xref (int) – xref编号。v1.18.13中进行了更改:要更新PDF trailer,请指定为 -1。
  • key (str) – 目标PDF键(不带前导“/”)。必须是非空的。可以是任何有效的PDF键——无论是对象中已有的(会被覆盖),还是新的键。可以使用PDF路径符号,如“Resources/ExtGState”——这会将“/ExtGState”键作为“/Resources”下的子对象。
  • value (str) – 键的值。必须是非空字符串,且根据所需的PDF对象类型,需要遵守以下规则。虽然有一些语法检查,但没有类型检查,也没有检查其是否符合PDF语义。即,没有语义检查。大小写非常重要!

具体的规则说明:

  • xref – 必须以“nnn 0 R”格式提供,其中“nnn”是有效的xref编号。后缀“0 R”是必须的,以便PDF应用程序能够识别该xref。
  • array – 字符串形式,类似于“[a b c d e f]”。括号是必需的。数组项之间必须至少用一个空格分隔(不像Python中的逗号)。空数组“[]”是可以的,它等同于删除该键。数组项可以是任何PDF对象,如字典、xref、其他数组等。像Python一样,数组项可以是不同类型的。
  • dict – 字符串形式,类似于“<< ... >>”。括号是必需的,必须包含有效的PDF字典定义。空字典“<<>>”也是可以的,等同于删除该键。
  • int – 整数,作为字符串表示。
  • float – 浮动数,作为字符串表示。PDF不允许科学计数法(带指数)。
  • null – 字符串“null”。这是PDF中相当于Python的None,它会导致该键被忽略,但不一定被删除,删除操作会在保存时通过垃圾回收完成。v1.19.4更新:如果该键没有路径层次结构(即不包含斜杠“/”),那么它将被完全删除。
  • bool – 字符串“true”或“false”之一。
  • name – 有效的PDF名称,必须以斜杠“/”开头,例如“/PageLayout”。参见Adobe PDF参考文档第16页。
  • string – 有效的PDF字符串。所有PDF字符串必须用括号括起来。空字符串表示为“()”。根据内容,可能的括号有:
    • “(…)”表示仅包含ASCII字符的文本。保留PDF字符必须用反斜杠转义,非ASCII字符必须用3位数字的八进制反斜杠转义表示,包括前导零。例如:12 = 0x0C必须编码为014。
    • “<…>”表示十六进制编码文本。每个字符必须用两个十六进制数字表示(无论大小写)

如果不确定,强烈建议使用get_pdf_str()函数! 该函数会自动生成正确的括号、转义符号以及整体格式。例如,它会像这样进行转换:

  • 由于包含€符号,以下内容会生成UTF-16BE BOM:
    pymupdf.get_pdf_str("Pay in $ or €.")
    结果为:''
  • 对于括号和非ASCII字符的转义:
    pymupdf.get_pdf_str("Prices in EUR (USD also accepted). Areas are in m².")
    结果为:'(Prices in EUR \\(USD also accepted\\). Areas are in m\\262.)'

get_page_pixmap(pno: int, *, matrix: matrix_like = Identity, dpi=None, colorspace: Colorspace = csRGB, clip: rect_like = None, alpha: bool = False, annots: bool = True)

从页面 pno(基于 0 的页面编号)创建一个 Pixmap。

参数:

  • pnoint):页面编号,基于 0 的编号。
  • 其余参数是关键字参数,可以用于进一步自定义生成的 Pixmap。

返回类型:

  • Pixmap

get_page_xobjects(pno)

新增功能: 从v1.16.13开始,v1.18.11做了更新。

仅限PDF: 返回页面引用的所有XObject(非图像)列表。

参数:

  • pno (int) – 页面编号,从0开始,-∞ < pno < 页面总数(page_count)。

返回类型:

  • list – 返回一个列表,包含所有页面引用的XObjects(非图像)。这些对象通常代表从其他PDF嵌入(而不是复制)的页面。例如,Page.show_pdf_page()会创建这种类型的对象。

返回内容:

该列表中的每个项都有以下布局:

  • xref (int) – XObject的xref编号。
  • name (str) – 引用该XObject的符号名称。
  • invoker (int) – 调用该XObject的xref编号,若页面直接调用,则为零。
  • bbox (Rect) – XObject在页面上的边界框位置,采用未变换的坐标。要获取实际的、未旋转的页面坐标,可将其与页面的变换矩阵Page.transformation_matrix相乘。

更新: v1.18.11中,bbox现在格式化为Rect对象。

get_page_images(pno, full=False)

仅限PDF: 返回页面引用的所有图像(直接或间接)的列表。

参数:

  • pno (int) – 页面编号,从0开始,-∞ < pno < 页面总数(page_count)。
  • full (bool) – 是否包括引用者的xref(如果是页面直接引用,则为零)。

返回类型:

  • list – 返回一个列表,包含该页面引用的所有图像。每个项的格式如下:
    (xref, smask, width, height, bpc, colorspace, alt_colorspace, name, filter, referencer)

每个字段的含义:

  • xref (int) – 图像对象的编号。
  • smask (int) – 图像的软蒙版(soft-mask)图像的对象编号。
  • width (int) – 图像的宽度。
  • height (int) – 图像的高度。
  • bpc (int) – 每个组件的位数(通常是8)。
  • colorspace (str) – 颜色空间的名称(如 DeviceRGB)。
  • alt_colorspace (str) – 根据colorspace的值,可能存在的备用颜色空间。
  • name (str) – 用于引用图像的符号名称。
  • filter (str) – 图像的解码滤镜(见Adobe PDF References,第22页)。
  • referencer (int) – 引用者的xref编号。若由页面直接引用,则为零。仅在full=True时存在。
注意:通常,这不是实际显示的图像列表。此方法仅解析若干PDF对象以收集对嵌入图像的引用。它不会分析页面内容,其中所有实际的图像显示命令被定义。要获取这些信息,请使用 Page.get_image_info()方法。同时,可以查看“ 结构化字典输出”部分的讨论。

get_page_fonts(pno, full=False)

仅限PDF: 返回页面引用的所有字体(直接或间接)的列表。

参数:

  • pno (int) – 页面编号,从0开始,-∞ < pno < 页面总数(page_count)。
  • full (bool) – 是否包括引用者的xref。如果为True,返回的每个条目会多一个元素。如果需要知道页面是否直接引用了该字体,请使用此选项。在这种情况下,最后一个条目是0。如果该字体是由页面的/XObject引用的,则在此处找到其xref。

返回类型:

  • list – 返回一个列表,包含该页面引用的所有字体。每个条目的格式如下:
    (xref, ext, type, basefont, name, encoding, referencer)

字段含义:

  • xref (int) – 字体对象编号(如果PDF直接使用内置字体,则可能为零)。
  • ext (str) – 字体文件扩展名(例如“ttf”,见字体文件扩展名)。
  • type (str) – 字体类型(例如“Type1”或“TrueType”等)。
  • basefont (str) – 基本字体名称。
  • name (str) – 用于引用字体的符号名称。
  • encoding (str) – 字体的字符编码(如果与其内置编码不同,见Adobe PDF References,第254页)。
  • referencer (int, 可选) – 引用者的xref。如果页面直接引用,则为零;如果通过/XObject引用,则为该/XObject的xref。仅在full=True时返回。

示例:

>>> pprint(doc.get_page_fonts(0, full=False))
[(12, 'ttf', 'TrueType', 'FNUUTH+Calibri-Bold', 'R8', ''),
 (13, 'ttf', 'TrueType', 'DOKBTG+Calibri', 'R10', ''),
 (14, 'ttf', 'TrueType', 'NOHSJV+Calibri-Light', 'R12', ''),
 (15, 'ttf', 'TrueType', 'NZNDCL+CourierNewPSMT', 'R14', ''),
 (16, 'ttf', 'Type0', 'MNCSJY+SymbolMT', 'R17', 'Identity-H'),
 (17, 'cff', 'Type1', 'UAEUYH+Helvetica', 'R20', 'WinAnsiEncoding'),
 (18, 'ttf', 'Type0', 'ECPLRU+Calibri', 'R23', 'Identity-H'),
 (19, 'ttf', 'Type0', 'TONAYT+CourierNewPSMT', 'R27', 'Identity-H')] 
注意:该列表没有重复条目: xrefname 和  referencer 的组合是唯一的。通常,这是一个包含该页面实际使用字体的超集。例如,PDF创建者可能指定了一个全局字体列表,而每个页面只使用其中的一部分。

get_page_text(pno, output='text', flags=3, textpage=None, sort=False)

提取页面的文本,给定其页面编号 pno(从0开始)。调用 Page.get_text() 方法。

参数:

  • pno (int) – 页面编号,从0开始,-∞ < pno < 页面总数(page_count)。
  • 其他参数参考页面方法的说明。

返回类型:

  • str – 返回页面的文本内容。

layout(rect=None, width=0, height=0, fontsize=11)

重新分页(“重新流式化”)文档,根据给定的页面尺寸和字体大小。这只会影响某些文档类型,如电子书和HTML文档。如果文档不支持此功能,则会被忽略。支持的文档会在属性 is_reflowable 中显示为 True

参数:

  • rect (rect_like) – 期望的页面尺寸。必须是有限的,非空,并且从点(0,0)开始。
  • width (float) – 与 height 一起使用,作为 rect 的替代。
  • height (float) – 与 width 一起使用,作为 rect 的替代。
  • fontsize (float) – 期望的默认字体大小。

select(s)

仅限PDF: 保留文档中页面编号在列表中的页面。空的序列或超出范围的元素会导致 ValueError。有关更多详细信息,请参阅本章节底部的备注。

参数:

  • s (sequence) – 要包含的页面编号的序列(从0开始)。不在序列中的页面将被删除(从内存中),并且在重新打开文档之前不可用。页面编号可以重复出现,且顺序不需要特定:生成的文档将完全反映指定的序列。
注意:序列中的页面编号不需要唯一,且不需要按任何特定顺序排列。这使得该方法成为一个多功能工具,例如选择仅偶数页或仅奇数页,或满足其他某些条件等。从技术层面来看,该方法总是会创建一个新的页面树。当只处理少量页面时,使用  copy_page()move_page() 或  delete_page() 方法会更简单。实际上,当文档包含许多页面时,它们也会快得多——至少快一个数量级。

set_metadata(m)

仅限PDF: 设置或更新文档的元数据,m 是一个Python字典。

参数:

  • m (dict) – 一个字典,包含与元数据相同的键(见下文)。所有键都是可选的。PDF的格式和加密方法不能设置或更改,因此会被忽略。如果任何值不应包含数据,则不要指定其键或将值设置为 None。如果使用空字典 {},则所有元数据将被清空并设置为字符串“none”。如果只想选择性地更改某些值,请修改 doc.metadata 的副本,并将其作为参数传递。可以指定任意的UTF-8编码的Unicode值。

注意:

  • 从v1.18.4版本开始,空值或“none”不再写入,而是完全省略。

get_xml_metadata()

仅限PDF: 获取文档的XML元数据。

返回类型:

  • str – 返回文档的XML元数据。如果没有XML元数据,或者文档不是PDF格式,则返回空字符串。

set_xml_metadata(xml)

仅限PDF: 设置或更新文档的XML元数据。

参数:

  • xml (str) – 新的XML元数据。应该是XML语法,但此方法不会进行任何检查,接受任何字符串。

set_pagelayout(value)

新功能 v1.22.2

仅限PDF: 设置 /PageLayout

参数:

  • value (str) – 其中一个字符串:"SinglePage""OneColumn""TwoColumnLeft""TwoColumnRight""TwoPageLeft""TwoPageRight"。支持小写。

set_pagemode(value)

新功能 v1.22.2

仅限PDF: 设置 /PageMode

参数:

  • value (str) – 其中一个字符串:"UseNone""UseOutlines""UseThumbs""FullScreen""UseOC""UseAttachments"。支持小写。

set_markinfo(value)

新功能 v1.22.2

仅限PDF: 设置 /MarkInfo 的值。

参数:

  • value (dict) – 一个字典,像这样:{"Marked": False, "UserProperties": False, "Suspects": False}。该字典包含有关使用标签PDF约定的信息。有关详细信息,请参阅PDF规格。

set_toc(toc, collapse=1)

仅限PDF: 用提供的参数替换当前的完整大纲树(目录)。成功执行后,可以通过 Document.get_toc() 或 Document.outline 正常访问新的大纲树。与其他输出导向方法一样,只有在使用 save()(支持增量保存)之后,修改才会成为永久性的。内部,该方法包括以下两个步骤。示例如下所示。

步骤 1 删除所有现有的书签。

步骤 2 根据 toc 中包含的条目创建新的目录。

参数:

  • toc (sequence) – 一个包含所有书签条目的列表/元组,这些条目将形成新的目录。get_toc() 的输出变体是可以接受的。如果要完全删除目录,指定空序列或 None。每个条目必须是一个列表,格式如下:
    [lvl, title, page [, dest]]
    • lvl 是条目的层级(整数 > 0),第一个条目的层级必须为 1,并且不能大于上一个条目的层级 1。
    • title (str) 是显示的标题,假设是UTF-8编码(对于多字节字符是相关的)。
    • page (int) 是目标页面编号(注意:基于1的编号)。如果是正数,必须在有效范围内。如果没有目标,或者目标是外部的,可以设置为 -1。
    • dest (可选) 是一个字典或数字。如果是数字,它将被解释为该条目在页面上应指向的目标高度(以点为单位)。可以使用字典(例如 get_toc(False) 输出的字典)来详细控制书签的属性,详细信息请参阅 Document.get_toc()
  • collapse (int) – (v1.16.9 新增)控制目录项应该在哪个层级开始默认显示为折叠状态。默认值 1 仅显示层级 1,更高层级必须通过 PDF 查看器展开。如果要展开所有内容,可以指定一个较大的整数、0 或 None

返回类型:

  • int – 返回插入或删除的条目数。

注意:

从 v1.23.8 版本开始,目标 ‘to’ 坐标应与 get_toc() 返回的坐标系相同(内部会通过 page.cropbox 和 page.rotation_matrix 进行转换)。因此,像 set_toc(get_toc()) 现在会给出未更改的目标 ‘to’ 坐标。

outline_xref(idx)

v1.17.7 新增

仅限PDF: 返回大纲项的 xref。此方法主要用于内部用途。

参数:

  • idx (int) – Document.get_toc() 列表中的条目索引。

返回:

  • xref – 返回对应的大纲项的 xref。

del_toc_item(idx)

v1.17.7 新增

v1.18.14 变更: 不再删除条目的文本,而是将其显示为灰色。

仅限PDF: 删除此目录项。这是一个高效的方法,它禁用相应的条目,但保持整个目录结构完整。物理上,该条目仍然存在于目录树中,但会显示为灰色,并且不再指向任何目标。

这也意味着,当需要时,可以使用 Document.set_toc_item() 为该条目分配一个新的目标。

参数:

  • idx (int) – Document.get_toc() 列表中的条目索引。

set_toc_item(idx, dest_dict=None, kind=None, pno=None, uri=None, title=None, to=None, filename=None, zoom=0)

v1.17.7 新增

v1.18.6 变更

仅限PDF: 更改由索引标识的目录项。可以更改条目的标题、目标、外观(颜色、加粗、斜体)或折叠子项,甚至完全删除该条目。

如果只需要对选定条目进行特定更改,并且希望避免替换整个目录,可以使用此方法。这在处理大型目录时特别有用。

参数:

  • idx (int) – Document.get_toc() 列表中条目的索引。
  • dest_dict (dict) – 新的目标。可以使用 doc.get_toc(False) 输出的最后一项条目的字典作为模板。当提供时,其他参数将被忽略——除非 title 被提供。
  • kind (int) – 链接类型,参见链接目标类型。如果是 LINK_NONE,则所有其他参数将被忽略,且该目录项将被移除——相当于 Document.del_toc_item()。如果是 None,则只修改标题,忽略其他参数。其他值将使用后续参数创建新的目标字典。
  • pno (int) – 基于1的页面编号,值应在 1 <= pno <= doc.page_count 范围内。对于 LINK_GOTO 类型必填。
  • uri (str) – URL文本。对于 LINK_URI 类型必填。
  • title (str) – 新的标题。如果不修改标题,设置为 None
  • to (point_like) – (可选)指向目标页面上的一个坐标。对于 LINK_GOTO 类型相关。如果未提供,将选择页面顶部附近的点。
  • filename (str) – 对于 LINK_GOTOR 和 LINK_LAUNCH 类型必填。
  • zoom (float) – 显示目标页面时使用的缩放因子。

示例使用: 更改SWIG手册的目录以实现以下效果:

  • 折叠所有顶级以下的内容,并将Python支持章节显示为红色、加粗和斜体:
>>> import pymupdf
>>> doc=pymupdf.open("SWIGDocumentation.pdf")
>>> toc = doc.get_toc(False)  # we need the detailed TOC
>>> # list of level 1 indices and their titles
>>> lvl1 = [(i, item[1]) for i, item in enumerate(toc) if item[0] == 1]
>>> for i, title in lvl1:
        d = toc[i][3]  # get the destination dict
        d["collapse"] = True  # collapse items underneath
        if "Python" in title:  # show the 'Python' chapter
            d["color"] = (1, 0, 0)  # in red,
            d["bold"] = True  # bold and
            d["italic"] = True  # italic
        doc.set_toc_item(i, dest_dict=d)  # update this toc item
>>> doc.save("NEWSWIG.pdf",garbage=3,deflate=True)

在上面的示例中,我们只更改了文件中 1240 个目录项中的 42 个。

bake(*, annots=True, widgets=True)

仅限PDF: 将注释和/或表单控件转换为页面的永久部分。此方法将修改PDF文档。如果 widgets 设置为 True,文档将不再是“表单PDF”。

所有页面看起来将是一样的,但将不再包含注释或表单字段。可见的部分将根据需要转换为标准文本、矢量图形或图像。

此方法可以作为PDF到PDF转换的有效替代方法,使用 Document.convert_to_pdf()

请注意,注释是复杂的对象,可能包含超出其视觉外观的更多数据。例如,“文本”注释和“附件文件”注释。当使用此方法将注释/表单控件“嵌入”时,所有这些底层信息(附加文件、评论、相关的PopUp注释等)将会丢失,并在下一次垃圾回收时被删除。

例如,在 Page.show_pdf_page() 中(该方法不支持注释和表单控件)当源页面应在目标中完全相同显示时,可以使用此功能。

参数:

  • annots (bool) – 是否转换注释。
  • widgets (bool) – 是否转换表单控件。执行后,文档将不再是“表单PDF”。

can_save_incrementally()

v1.16.0 新增

检查文档是否可以增量保存。使用此方法可以在选择正确选项时避免遇到异常。

scrub(attached_files=True, clean_pages=True, embedded_files=True, hidden_text=True, javascript=True, metadata=True, redactions=True, redact_images=0, remove_links=True, reset_fields=True, reset_responses=True, thumbnails=True, xml_metadata=True)

v1.16.14 新增

仅限PDF: 从PDF中移除潜在的敏感数据。此功能灵感来源于Adobe Acrobat产品中的类似“Sanitize”功能。该过程可以通过多个选项进行配置。

参数:

  • attached_files (bool) – 搜索‘FileAttachment’注释并移除文件内容。
  • clean_pages (bool) – 移除页面绘制源中的所有评论。如果此选项设置为 False,则同时也会清除隐藏文本和删减部分。
  • embedded_files (bool) – 移除嵌入的文件。
  • hidden_text (bool) – 移除OCR识别的文本和不可见文本。
  • javascript (bool) – 移除JavaScript源代码。
  • metadata (bool) – 移除PDF标准元数据。
  • redactions (bool) – 应用删减注释。
  • redact_images (int) – 如果应用删减时,如何处理图像。值为 0(忽略)、1(覆盖重叠部分)或 2(移除)。
  • remove_links (bool) – 移除所有链接。
  • reset_fields (bool) – 重置所有表单字段为默认值。
  • reset_responses (bool) – 移除所有注释中的响应。
  • thumbnails (bool) – 移除页面缩略图。
  • xml_metadata (bool) – 移除XML元数据。

save(outfile, garbage=0, clean=False, deflate=False, deflate_images=False, deflate_fonts=False, incremental=False, ascii=False, expand=0, linear=False, pretty=False, no_new_id=False, encryption=PDF_ENCRYPT_NONE, permissions=-1, owner_pw=None, user_pw=None, use_objstms=0)

v1.18.7 变更

v1.19.0 变更

v1.24.1 变更

仅限PDF: 保存文档的当前状态。

参数:

  • outfile (str, Path, fp) – 要保存到的文件路径,pathlib.Path或文件对象。如果是文件对象,必须先通过 open(...) 或 io.BytesIO() 创建。选择 io.BytesIO() 类似于 Document.tobytes(),等同于内部创建的 io.BytesIO().getvalue() 输出。
  • garbage (int) – 执行垃圾回收。正值表示不包括“增量”。
    • 0 = 无操作
    • 1 = 移除未使用(未引用)对象
    • 2 = 除了1,还会压缩xref表
    • 3 = 除了2,还会合并重复对象
    • 4 = 除了3,还会检查流对象的重复。由于这些数据通常较大,因此可能会很慢。
  • clean (bool) – 清理和消毒内容流。[1] 相当于“mutool clean -sc”。
  • deflate (bool) – 压缩未压缩的流。
  • deflate_images (bool) – (v1.18.3 新增)压缩未压缩的图像流。[4]
  • deflate_fonts (bool) – (v1.18.3 新增)压缩未压缩的字体文件流。[4]
  • incremental (bool) – 仅保存对PDF的更改。排除“垃圾回收”和“线性化”。仅当 outfile 为字符串或 pathlib.Path 且等于 Document.name 时可使用。如果文件已解密或修复,并且在某些其他情况下,不能使用此选项。为确保此选项可用,请检查 Document.can_save_incrementally()。如果返回 False,则需要保存为新文件。
  • ascii (bool) – 将二进制数据转换为ASCII。
  • expand (int) – 解压缩对象。生成可以更好地被其他程序读取的版本,并会导致文件变大。
    • 0 = 无操作
    • 1 = 图像
    • 2 = 字体
    • 255 = 所有
  • linear (bool) – 保存线性化版本的文档。此选项创建一个文件格式,以提高Internet访问性能。排除“增量”和“use_objstms”选项。
  • pretty (bool) – 美化文档源代码,使其更具可读性。PDF对象将被重新格式化,以类似 Document.xref_object() 的默认输出方式呈现。
  • no_new_id (bool) – 禁止更新文件的/ID字段。如果文件本身没有此字段,也禁止创建新字段。默认值为 False,因此每次保存将导致文件标识的更新。
  • permissions (int) – (v1.16.0 新增)设置所需的权限级别。请参阅 Document Permissions 了解可能的值。默认值为授予所有权限。
  • encryption (int) – (v1.16.0 新增)设置所需的加密方法。请参阅 PDF 加密方法代码,了解可能的值。
  • owner_pw (str) – (v1.16.0 新增)设置文档的所有者密码。(v1.18.3 变更)如果未提供所有者密码,将使用用户密码(如果提供)。密码长度不得超过40个字符。
  • user_pw (str) – (v1.16.0 新增)设置文档的用户密码。密码长度不得超过40个字符。
  • use_objstms (int) – (v1.24.0 新增)压缩选项,将合适的PDF对象定义转换为存储在其他对象流数据中的信息。根据 deflate 参数的值,转换后的对象定义将被压缩,这可以显著减少文件大小。

警告:该方法不会检查是否已经存在该名称的文件,因此不会要求确认,直接覆盖文件。作为开发者,你需要自行处理文件覆盖的逻辑。

注意:

  • 文件大小压缩
    • 使用像 garbage=3|4deflate=Trueuse_objstms=True|1 等保存选项。不要更改默认值 expand=False|0clean=False|0incremental=False|0linear=False|0。这是“无损”的文件大小压缩。也有一个便捷的版本 Document.ez_save(),默认设置了这些值,请参见下面的说明。
    • 有损的文件大小压缩 本质上必须在图像方面做出某些妥协,例如:(a) 移除所有图像 (b) 将图像替换为灰度版本 (c) 降低图像分辨率。在 PyMuPDF 工具中,“replace-image”文件夹里有相关示例。

ez_save(*args, **kwargs)
新增于 v1.18.11

仅限PDF:与 Document.save() 相同,但默认设置已更改:deflate=Truegarbage=3use_objstms=1

saveIncr()

仅限PDF:增量保存文档。这是 doc.save(doc.name, incremental=True, encryption=PDF_ENCRYPT_KEEP) 的便捷缩写。

注意:如果文档包含已验证的签名,保存时可能需要使用增量保存,否则保存为新文件会使签名失效。

tobytes(garbage=0, clean=False, deflate=False, deflate_images=False, deflate_fonts=False, ascii=False, expand=0, linear=False, pretty=False, no_new_id=False, encryption=PDF_ENCRYPT_NONE, permissions=-1, owner_pw=None, user_pw=None, use_objstms=0)

更新于 v1.18.7

更新于 v1.19.0

更新于 v1.24.1

仅限PDF:将文档的当前内容写入字节对象,而不是写入文件。显然,需要注意内存要求。各参数的含义与 save() 相同。章节FAQ中有一个使用此方法作为 pdfrw 预处理器的示例。

(更新于 v1.16.0) 增强的加密支持。

返回类型:bytes
返回:包含完整文档的字节对象。

search_page_for(pno, text, quads=False)

搜索页号为 pno 的页面上的“text”。与对应的 Page.search_for() 完全相同。任何整数 -∞ < pno < page_count 都是有效的。

insert_pdf(docsrc, from_page=-1, to_page=-1, start_at=-1, rotate=-1, links=True, annots=True, widgets=True, show_progress=0, final=1)

仅限PDF:复制 docsrc PDF 文档中的页面范围 [from_page, to_page](包括两者)到当前文档。插入将从页面号 start_at 开始。-1 表示使用默认值。所有复制的页面将根据指定值旋转。可以排除链接、注释和小部件,详见下文。所有页码都是基于0的。

参数:

  • docsrc (Document) – 一个已打开的PDF文档,不能是当前文档。它可能与同一文件相关。
  • from_page (int) – docsrc 中的第一页,默认为零。
  • to_page (int) – 要复制的 docsrc 中的最后一页,默认是最后一页。
  • start_at (int) – 复制的第一页面,将成为目标文档中的 start_at 页面。默认为-1,将页面范围附加到末尾。如果是0,则在当前第一页之前插入页面范围。
  • rotate (int) – 所有复制的页面将按指定的值(以度为单位,90的整数倍)进行旋转。
  • links (bool) – 是否包括链接(内部和外部)在复制中。默认为 True。始终排除命名链接(LINK_NAMED)和指向复制页面范围外部的内部链接。
  • annots (bool) – 是否包括注释在复制中。
  • widgets (bool) – 是否包括小部件(表单字段)在复制中。如果为 True 且源页面包含表单字段,则目标PDF将转换为表单PDF(如果还不是的话)。
  • show_progress (int) – 新于 v1.17.7,指定大于零的间隔大小,以便在 sys.stdout 上查看进度消息。每次间隔后,将打印类似“已插入 30 个页面中的 47 个”的消息。
  • final (int) – 新于 v1.18.0,控制是否在此方法调用后丢弃已复制对象的列表,默认为 True。对于从同一源PDF中进行的多个插入,除最后一个外应设置为 0。这可以显著节省目标文件的大小并加快执行速度。

注意:
这是一个基于页面的方法。因此,源文档的文档级信息通常会被忽略。示例包括可选内容、嵌入文件、结构元素、目录、页面标签、元数据、命名目标(及其他命名条目)等。

如果 from_page > to_page,页面将按反向顺序复制。如果 0 <= from_page == to_page,则只会复制一页。

docsrc 的目录条目不会被复制。不过,可以轻松恢复结果文档的目录。可以查看下面的示例和 examples 目录中的程序 join.py,它可以连接PDF文档并同时将相应部分的目录合并。

insert_file(infile, from_page=-1, to_page=-1, start_at=-1, rotate=-1, links=True, annots=True, show_progress=0, final=1)

新于 v1.22.0

仅限PDF:将任意支持的文档添加到当前PDF。打开 “infile” 作为文档,将其转换为PDF,然后调用 Document.insert_pdf()。参数与该方法相同。此方法提供了一种简便的方式将图像作为完整页面添加到输出PDF中。

参数:

  • infile (multiple) – 要插入的输入文档。可以是有效文件名的规范,也可以是PixMap。

new_page(pno=-1, width=595, height=842)

仅限PDF:插入一个空白页面。

参数:

  • pno (int) – 新页面应插入的位置页码。必须满足 1 < pno <= page_count。特殊值 -1 和 doc.page_count 表示插入到最后一页之后。
  • width (float) – 页面宽度。
  • height (float) – 页面高度。

返回类型:Page
返回:返回创建的页面对象。

insert_page(pno, text=None, fontsize=11, width=595, height=842, fontname='helv', fontfile=None, color=None)

仅限PDF:插入一个新页面并添加一些文本。这个便捷函数结合了 Document.new_page() 和 Page.insert_text() 的部分功能。

参数:

  • pno (int) – 新页面插入的位置(基于0的页码)。必须在 (-1, doc.page_count + 1) 范围内。特殊值 -1 和 doc.page_count 表示插入到最后一页之后。
  • 其他参数详见上述方法。

返回类型:int
返回:返回 Page.insert_text() 的结果(成功插入的行数)。

delete_page(pno=-1)

仅限PDF:删除指定页码的页面,页码范围为 -∞ < pno < page_count - 1

更新于 v1.18.14: 支持 Python 的 del 语句。

参数:

  • pno (int) – 要删除的页面。负数表示从文档末尾倒数。例如,-1 表示最后一页。默认是最后一页。

delete_pages(*args, **kwds)

更新于 v1.18.13: 增强了删除页面的灵活性。
更新于 v1.18.14: 支持 Python 的 del 语句。

**仅限PDF:**删除多个页面,页面号为基于0的数字。

格式 1:使用关键字。代表旧格式。删除连续范围的页面。

  • from_page:要删除的第一页,若省略默认为0。
  • to_page:要删除的最后一页,若省略默认为文档中的最后一页。to_page 必须不小于 from_page

格式 2:两个页码作为位置参数,处理方式如格式 1。

格式 3:一个位置参数作为整数,相当于 Page.delete_page()

格式 4:一个位置参数为列表、元组或 range() 类型的页面号。该序列的项目可以是任意顺序并且可以包含重复项。

格式 5:(新于 v1.18.14)现在可以使用 Python 的 del 语句和索引/切片表示法。

注意:(更新于 v1.14.17,优化于 v1.17.7) 为了保持有效的PDF结构,delete_page() 和此方法也会禁用指向已删除页面的目录项(书签)。这里的“禁用”意味着书签将指向无处,且在支持的PDF查看器中标题会显示为灰色。整体目录结构保持不变。它还会删除指向已删除页面的其他页面上的链接。对于页面数较多的文档,这可能需要较长的时间来响应。以下所有示例都将删除页面 500 到 519:

  • doc.delete_pages(500,519)
  • doc.delete_pages(from_page=500,to_page=519)
  • doc.delete_pages((500,501,502,...,519))
  • doc.delete_pages(range(500,520))
  • deldoc[500:520]
  • deldoc[(500,501,502,...,519)]
  • deldoc[range(500,520)]
    对于Adobe PDF参考,执行上述操作大约需要0.6秒,因为剩下的1290页必须清理无效链接。

通常,执行此方法的性能取决于剩余页面的数量,而非已删除页面的数量:例如,如果删除所有页面,剩下20页,所需的时间会大大减少。

copy_page(pno, to=-1)

仅限PDF: 在文档内复制一个页面引用。

参数:

  • pno (int) – 要复制的页面。必须在 0 <= pno < page_count 范围内。
  • to (int) – 要插入复制页面的位置页码。默认值是插入到最后一页之后。

注意:
此方法仅创建页面对象的一个新引用,而不是一个新的页面对象。所有复制的页面将具有相同的属性值,包括 Page.xref。这意味着对其中一个副本的任何更改将出现在所有副本中。

fullcopy_page(pno, to=-1)

新功能于 v1.14.17:
仅限PDF: 完全复制(重复)一个页面。

参数:

  • pno (int) – 要复制的页面。必须在 0 <= pno < page_count 范围内。
  • to (int) – 要插入复制页面的位置页码。默认值是插入到最后一页之后。

注意:
与 copy_page() 不同,此方法创建一个新的页面对象(具有新的 xref),可以独立于原始页面进行更改。

任何弹出窗口和“IRT”(响应)注释都不会被复制,以避免可能的错误情况。

move_page(pno, to=-1)

仅限PDF: 在文档内移动(复制并删除原始页面)一个页面。

参数:

  • pno (int) – 要移动的页面。必须在 0 <= pno < page_count 范围内。
  • to (int) – 要插入移动页面的位置页码。默认值是将页面移动到最后一页之后。

need_appearances(value=None)

新功能于 v1.17.4:
仅限PDF: 获取或设置表单PDF的 /NeedAppearances 属性。
引用:“(可选)一个标志,指定是否为文档中的所有小部件注释构建外观流和外观字典… 默认值:false。” 这有助于控制某些阅读器/查看器的行为。

参数:

  • value (bool) – 设置该属性的值。如果省略或为 None,则查询当前值。

返回类型:bool
返回:

  • None:不是表单PDF,或属性未定义。
  • True / False:该属性的值(无论是刚设置还是已有值)。如果没有表单PDF,则无效。

get_sigflags()

仅限PDF: 返回文档是否包含签名字段。这是一个可选的PDF属性:如果不存在(返回值为 -1),则无法得出结论—PDF创建者可能根本没有使用它。

返回类型:int
返回:

  • -1:不是表单PDF / 没有记录签名字段 / 未找到 SigFlags
  • 1:至少存在一个签名字段。
  • 3:包含的签名可能会被作废,如果文件以某种方式保存(写入),改变了它之前的内容,而不是增量更新。

embfile_add(name, buffer, filename=None, ufilename=None, desc=None)

更新于 v1.14.16: 参数顺序已更改,以符合其他函数的调用模式。

仅限PDF: 嵌入一个新文件。所有字符串参数,除了名称外,均可为 Unicode(在早期版本中,只有 ASCII 正确工作)。文件内容将被压缩(在有利的情况下)。

参数:

  • name (str) – 条目标识符,不能为空且不得与现有名称冲突。
  • buffer (bytes, bytearray, BytesIO) – 文件内容。
    (更新于 v1.14.13)现在也支持 io.BytesIO
  • filename (str) – 可选文件名,仅用于文档,如果为 None,则设置为 name
  • ufilename (str) – 可选Unicode文件名,仅用于文档,如果为 None,则设置为 filename
  • desc (str) – 可选描述,仅用于文档,如果为 None,则设置为 name

返回类型:int
返回:

  • 更新于 v1.18.13: 方法现在返回插入文件的 xref。此外,文件对象将自动获得PDF的 /CreationDate 和 /ModDate 键,基于当前的日期时间。

embfile_count()

更新于 v1.14.16: 现在是一个方法,在早期版本中是一个属性。

仅限PDF: 返回嵌入文件的数量。

embfile_get(item)

仅限PDF: 根据条目号或名称检索嵌入文件的内容。如果文档不是PDF,或无法找到该条目,将引发异常。

参数:

  • item (int, str) – 条目的索引或名称。整数必须在 embfile_count() 范围内。

返回类型:bytes

embfile_del(item)

更新于 v1.14.16: 现在可以通过索引删除条目。

仅限PDF: 从 /EmbeddedFiles 中移除条目。正如往常一样,嵌入的文件内容的物理删除(以及文件空间的回收)仅会在文档保存为新文件并使用适当的垃圾回收选项时发生。

参数:

  • item (int/str) – 条目的索引或名称。

警告:
当指定条目名称时,此函数仅删除第一个具有该名称的条目。请注意,非PyMuPDF创建的PDF可能包含重复的名称。因此,您可能需要采取适当的预防措施。

embfile_info(item)

更新于 v1.18.13:
仅限PDF: 检索给定条目的嵌入文件信息,可以通过条目号或名称来检索。

参数:

  • item (int/str) – 条目的索引或名称。整数必须在 embfile_count() 范围内。

返回类型:dict

返回:一个字典,包含以下键:

  • name – (str) 该条目存储的名称
  • filename – (str) 文件名
  • ufilename – (unicode) 文件名
  • description – (str) 描述
  • size – (int) 原始文件大小
  • length – (int) 压缩后的文件长度
  • creationDate – (str) 项目创建日期时间,以PDF格式表示
  • modDate – (str) 最后修改日期时间,以PDF格式表示
  • collection – (int) 关联的PDF投资组合项目的xref,如果没有,则为零
  • checksum – (str) 存储文件内容的哈希值,作为十六进制字符串。根据PDF规范,应该是MD5,但也可能使用其他哈希算法。

embfile_names()

仅限PDF: 返回嵌入文件名称的列表。名称的顺序与文档中物理顺序相同。

返回类型:list

embfile_upd(item, buffer=None, filename=None, ufilename=None, desc=None)
仅限PDF: 更改嵌入文件,根据其条目号或名称。所有参数都是可选的,默认值会导致无操作。

参数:

  • item (int/str) – 条目的索引或名称。整数必须在 embfile_count() 范围内。
  • buffer (bytes, bytearray, BytesIO) – 新的文件内容。
    (更新于 v1.14.13)现在也支持 io.BytesIO
  • filename (str) – 新的文件名。
  • ufilename (str) – 新的Unicode文件名。
  • desc (str) – 新的描述。

更新于 v1.18.13: 此方法现在返回文件对象的 xref

返回类型:int

返回:文件对象的 xref。同时,自动将其 /ModDate PDF键更新为当前的日期时间。

close()

释放与文档关联的对象和空间分配。如果是从文件创建的,也会关闭文件名(将控制权交给操作系统)。显式关闭文档相当于删除文档,del doc 或将其赋值为其他内容,例如 doc = None

xref_object(xref, compressed=False, ascii=False)

新功能于 v1.16.8
更新于 v1.18.10

仅限PDF: 返回PDF对象的定义源。

参数:

  • xref (int) – 对象的xref。更新于 v1.18.10: 传入 -1 时返回PDF trailer源。
  • compressed (bool) – 是否生成不带换行符或空格的紧凑输出。
  • ascii (bool) – 是否对二进制数据进行ASCII编码。

返回类型:str

返回:对象的定义源。

pdf_catalog()

新功能于 v1.16.8

仅限PDF: 返回PDF目录(或根)对象的xref编号。使用此编号与 Document.xref_object() 一起查看其源。

pdf_trailer(compressed=False)

新功能于 v1.16.8

仅限PDF: 返回PDF的trailer源,通常位于PDF文件的末尾。这相当于使用 Document.xref_object() 并传入xref参数为 -1。

xref_stream(xref)

新功能于 v1.16.8

仅限PDF: 返回xref流对象的解压内容。

参数:

  • xref (int) – xref编号。

返回类型:bytes

返回:该对象的(解压缩)流。

xref_stream_raw(xref)

新功能于 v1.16.8

仅限PDF: 返回未修改的(特别是未解压缩的)xref流对象内容。否则与 Document.xref_stream() 相同。

返回类型:bytes

返回:该对象的(原始,未修改的)流。

update_object(xref, obj_str, page=None)

新功能于 v1.16.8

仅限PDF: 用提供的字符串替换xref对象的定义。如果xref是新的,则此指令完成对象定义。如果还提供了页面对象,它的链接和注释将在之后重新加载。

参数:

  • xref (int) – xref编号。
  • obj_str (str) – 包含有效PDF对象定义的字符串。
  • page (Page) – 页面对象。如果提供,表示该页面的注释应在反映链接和/或注释变化后刷新(重新加载)。

返回类型:int

返回:如果成功返回零,否则将引发异常。

update_stream(xref, data, new=False, compress=True)

新功能于 v1.16.8
更新于 v1.19.2: 新增了“compress”参数
更新于 v1.19.6: 弃用了“new”参数。现在确认对象是PDF字典对象。

仅限PDF: 替换由xref标识的对象的流,如果该对象不是流,则将其转化为流。此功能会在有益的情况下自动执行压缩操作(“deflate”)。

参数:

  • xref (int) – xref编号。
  • stream (bytes|bytearray|BytesIO) – 流的新内容。
    更新于 v1.14.13:现在也支持 io.BytesIO 对象。)
  • new (bool) – 已弃用并被忽略。在 v1.20.0 后将被移除。
  • compress (bool) – 是否压缩插入的流。如果为 True(默认值),流将使用 /FlateDecode 压缩(如果有益),否则流将按原样插入。

引发:

  • ValueError – 如果xref不是PDF字典对象,则会引发此异常。空字典 <<>> 被接受。所以如果您刚创建了xref并想给它插入流,首先执行 doc.update_object(xref, "<<>>"),然后使用此方法插入流数据。

此方法主要(但不完全是)用于操作包含PDF操作符语法的流(例如页内容流)。

示例:假设您不再希望页面上显示某个图像。可以通过删除其内容源中的相关引用来实现——图像将在重新加载页面后消失。但页面的资源对象仍会显示该图像作为页面的引用。此时,可以使用 save 参数 clean=True 来确保PDF操作符源和对象结构的一致性。

xref_copy(source, target, *, keep=None)

新功能于 v1.19.5

仅限PDF: 将目标xref设置为源xref的精确副本。如果源是流数据,那么这些数据也会被复制。

参数:

  • source (int) – 源xref。必须是现有的字典对象。
  • target (int) – 目标xref。必须是现有的字典对象。如果xref刚刚被创建,请确保将其初始化为具有最小规范 <<>> 的PDF字典。
  • keep (list) – 一个可选的顶级键列表,这些键在复制过程中不应从目标中移除。

注意:

  • 此方法与Python的字典方法 copy() 很相似。
  • 这两个xref编号必须表示现有的字典对象。
  • 在从源复制数据之前,目标字典中的所有键将被删除。您可以在 keep 列表中指定要排除的例外键。如果源中有同名的键,它的值仍会替换目标中的值。
  • 如果源是流对象,那么这些数据也会被复制,目标将转换为流对象。
  • 一个典型的使用场景是替换或移除现有的图像,而不使用编辑注释。可以在此处看到示例脚本。

extract_image(xref)

仅限PDF: 提取文档中存储的图像数据和元信息。输出可以直接用来作为图像文件存储,或作为PIL、Pixmap创建的输入等。此方法尽量避免使用pixmaps来呈现图像,而是以图像的原始格式(例如JPEG)提供。

参数:

  • xref (int) – 图像对象的xref。如果不在 range(1, doc.xref_length()) 范围内,或者对象不是图像,或者发生其他错误,将返回 None,并且不会抛出异常。

返回类型:dict

返回:一个字典,包含以下键:

  • ext (str) 图像类型(例如 'jpeg'),可用作图像文件扩展名
  • smask (int) stencil(/SMask)图像的xref编号,或者为零
  • width (int) 图像宽度
  • height (int) 图像高度
  • colorspace (int) 图像的颜色空间编号
  • cs-name (str) 图像的颜色空间名称
  • xres (int) x方向的分辨率,请参见分辨率。
  • yres (int) y方向的分辨率,请参见分辨率。
  • image (bytes) 图像数据,可作为图像文件内容使用

例如:

>>> d = doc.extract_image(1373)
>>> d
{'ext': 'png', 'smask': 2934, 'width': 5, 'height': 629, 'colorspace': 3, 'xres': 96,
'yres': 96, 'cs-name': 'DeviceRGB',
'image': b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x05\ ...'}
>>> imgout = open(f"image.{d['ext']}", "wb")
>>> imgout.write(d["image"])
102
>>> imgout.close()

注意:
此方法与 pix = pymupdf.Pixmap(doc, xref) 然后调用 pix.tobytes() 存在功能重叠。主要区别在于:

  1. extract_image 不总是提供PNG格式的图像;
  2. 对于非PNG图像,extract_image 通常比使用 Pixmap 快得多;
  3. 提取的图像通常占用更少的磁盘存储;
  4. 在错误情况下返回 None(不抛出异常)。

以下是相同PDF中的几个示例图像。

  • xref 1268 是PNG图像 – 执行时间相近,输出相同:
In [23]: %timeit pix = pymupdf.Pixmap(doc, 1268);pix.tobytes()
10.8 ms ± 52.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [24]: len(pix.tobytes())
Out[24]: 21462

In [25]: %timeit img = doc.extract_image(1268)
10.8 ms ± 86 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [26]: len(img["image"])
Out[26]: 21462
  • xref 1186 是JPEG图像 – Document.extract_image() 的速度要快得多,且输出文件要小得多(2.48MB vs. 0.35MB):
In [27]: %timeit pix = pymupdf.Pixmap(doc, 1186);pix.tobytes()
341 ms ± 2.86 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [28]: len(pix.tobytes())
Out[28]: 2599433

In [29]: %timeit img = doc.extract_image(1186)
15.7 µs ± 116 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
In [30]: len(img["image"])
Out[30]: 371177

extract_font(xref, info_only=False, named=None)

新增于 v1.19.4:如果 named 为 True,返回字典。

仅限 PDF:返回嵌入字体文件的数据和适当的文件扩展名。可以将此方法用于将字体存储为外部文件。该方法不会抛出异常(除非检查 PDF 和有效的 xref 时)。

参数:

  • xref (int) – 要提取的字体的 PDF 对象编号。
  • info_only (bool) – 仅返回字体信息,不返回缓冲区。用于仅获取信息,避免分配大量缓冲区空间。
  • named (bool) – 如果为 True,返回一个包含以下键的字典:name(字体基本名称)、ext(字体文件扩展名)、type(字体类型)、content(字体文件内容)。

返回类型:

  • tuple, dict

返回值:

  • 返回一个元组 (basename, ext, type, content),其中 ext 是建议的 3 字节文件扩展名(字符串),basename 是字体的名称(字符串),type 是字体的类型(例如,“Type1”),content 是一个字节对象,包含字体文件的内容(或 b"")。
  • 错误时返回:
    • ("", "", "", b"") – 无效的 xref 或 xref 不是有效的字体对象。
    • (basename, "n/a", "Type1", b"") – 字体没有嵌入,因此无法提取。例如,PDF 基本 14 字体和 Type 3 字体。
>>> # store font as an external file
>>> name, ext, _, content = doc.extract_font(4711)
>>> # assuming content is not None:
>>> ofile = open(name + "." + ext, "wb")
>>> ofile.write(content)
>>> ofile.close()

警告:
返回的 basename 在 PDF 中保持不变。因此,它可能包含某些字符(如空格),这可能不适合作为操作系统的文件名。请采取适当的措施。

注意:
返回的 basename 一般不是原始文件名,但它可能与原始文件名有一定相似性。

如果 named 为 True,将返回包含以下键的字典:{'name': 'T1', 'ext': 'n/a', 'type': 'Type3', 'content': b''}

xref_xml_metadata()

新增于 v1.16.8

仅限 PDF:返回文档的 XML 元数据的 xref。

has_links()

has_annots()

新增于 v1.18.7

仅限 PDF:检查文档中是否存在链接或注释。

返回值:True / False。与字段不同,链接和注释是存储在 PDF 文档的每个页面中的,因此只能通过解析每一页来检测。这些方法经过优化,可以高效地进行此操作,并在页面上找到时立即返回。如果文档包含成千上万的页面,但未找到链接或注释,可能会需要一些时间。

subset_fonts(verbose=False, fallback=False)

仅限 PDF:检查文档中字体的使用情况。如果字体是支持的,并且可以进行大小减小,则用一个只包含所用字符的版本替换该字体。

在保存文档之前立即使用此方法。

参数:

  • verbose (bool) – 启用时,将各种进度信息写入 sysout。这目前仅在 fallback 为 True 时有效。
  • fallback (bool) – 如果为 True,使用已弃用的算法,该算法依赖于 fontTools 包(因此必须安装)。如果使用推荐的值 False(默认值),则使用 MuPDF 的原生函数,这样速度更快并且可以子集化更多字体类型。不需要 fontTools 包。

在创建新 PDF 时,使用像亚洲文字那样的较大字体时,可以显著减少嵌入字体的大小。使用 Story 类或 Page.insert_htmlbox() 方法时,多个字体可能会自动包含,而程序员对此并不知情。

在这些情况下,实际使用的字符集通常比字体中包含的字形数量要小得多。使用此方法可以将嵌入的字体二进制文件大小减少两个数量级——从几兆字节缩小到低两位千字节数。

创建字体子集会留下大量未使用的 PDF 对象(“幽灵”)。因此,请确保在保存文件时压缩并进行垃圾回收。建议使用 Document.ez_save()

新增于 v1.18.7

更改于 v1.18.9

更改于 v1.24.2,使用 MuPDF 的原生功能。

journal_enable()

新增于 v1.19.0

仅限 PDF:启用日志记录。开始记录操作之前,使用此方法。

journal_start_op(name)

新增于 v1.19.0

仅限 PDF:开始记录一个由字符串 name 标识的“操作”。如果没有开始操作,日志记录的更新将失败。

journal_stop_op()

新增于 v1.19.0

仅限 PDF:停止当前操作。从开始到结束的所有更新属于同一个操作单元,可以一起撤销/重做。

journal_position()

新增于 v1.19.0

仅限 PDF:返回当前操作的编号和总操作数。

返回一个元组 (step, steps),其中 step 是当前操作的编号,steps 是总操作数。如果 step 为 0,表示处于日志的顶部;如果 step 等于 steps,则表示处于日志底部。任何非撤销或重做的更新都会删除当前操作之后的所有日志条目,新更新将成为日志中的最后一条条目,删除的操作将永久丢失。

journal_op_name(step)

新增于 v1.19.0

仅限 PDF:返回操作编号 step 的操作名称。

journal_can_do()

新增于 v1.19.0

仅限 PDF:查看是否可以从当前日志位置执行前进(“重做”)或后退(“撤销”)操作。

返回值是一个字典 {"undo": bool, "redo": bool}。当其值为 True 时,可以执行相应的方法。

journal_undo()

新增于 v1.19.0

仅限 PDF:撤销当前日志中的操作。此操作会向日志的顶部移动。

journal_redo()

新增于 v1.19.0

仅限 PDF:重做当前日志中的操作。此操作会向日志的底部移动。

journal_save(filename)

新特性:v1.19.0

仅限PDF:将日志保存到文件中。

参数

  • filename (str, fp) – 文件名(字符串)或以“wb”模式打开的文件对象(或io.BytesIO()对象)。

journal_load(filename)

新特性:v1.19.0

仅限PDF:从文件加载日志。启用文档的日志记录。如果日志已经启用,则会抛出异常。

参数

  • filename (str, fp) – 日志的文件名(字符串)或以“rb”模式打开的文件对象(或io.BytesIO()对象)。

save_snapshot()

新特性:v1.19.0

仅限PDF:保存文档的“快照”。这是一个PDF文档,具有与日志记录兼容的特殊增量保存格式,因此没有可用的保存选项。对于新文档,不可能保存快照。

这是一个普通的PDF文档,完全没有使用限制。如果它没有被修改,可以与其日志一起使用以撤销/重做操作或继续更新。

outline

包含文档的第一个大纲条目(或None)。可以用作遍历所有大纲项的起点。如果访问加密且未通过验证的文档的此属性,将抛出AttributeError

类型Outline

is_closed
如果文档仍然打开,则为False。如果已关闭,则大多数其他属性和方法将被删除或禁用。此外,引用此文档的Page对象(即使用Document.load_page()创建的对象)及其相关对象将不再可用。出于参考目的,Document.name仍然存在,并将包含原始文档的文件名(如果适用)。

类型bool

is_dirty

如果这是一个PDF文档并包含未保存的更改,则为True,否则为False

类型bool

is_pdf

如果这是一个PDF文档,则为True,否则为False

类型bool

is_form_pdf

如果这不是PDF或没有表单字段,则为False,否则返回根表单字段的数量(没有祖先的字段)。
(在v1.16.4中更改) 返回总的(根)表单字段数量。

类型boolint

is_reflowable

如果文档具有可变的页面布局(如电子书或HTML),则为True。在这种情况下,您可以在文档创建(打开)时或通过方法layout()设置所需的页面尺寸。

类型bool

is_repaired

新特性:v1.18.2

如果PDF在打开时已修复(因为存在重大结构问题),则为True。对于非PDF文档,始终为False。如果为True,则在TOOLS.mupdf_warnings()中存储了更多详细信息,并且Document.can_save_incrementally()将返回False

类型bool

is_fast_webaccess

新特性:v1.22.2

如果PDF是线性化格式,则为True。对于非PDF文档,则为False

类型bool

markinfo

新特性:v1.22.2

一个字典,表示/MarkInfo值。如果未指定,返回空字典。如果不是PDF,则返回None

类型dict

pagemode

新特性:v1.22.2

一个包含/PageMode值的字符串。如果未指定,则返回默认值"UseNone"。如果不是PDF,则返回None

类型str

pagelayout

新特性:v1.22.2

一个包含/PageLayout值的字符串。如果未指定,则返回默认值"SinglePage"。如果不是PDF,则返回None

类型str

version_count

新特性:v1.22.2

一个整数,计算文档中存在的版本数。如果不是PDF,则返回零,否则返回增量保存的次数加一。

类型int

needs_pass

指示文档是否受密码保护,不能访问。如果为True,即使文档已通过身份验证,该值也保持不变。为True时,无法执行增量保存。

类型bool

is_encrypted

此指示器最初等于Document.needs_pass。成功验证后,它被设置为False,以反映当前的情况。

类型bool

permissions

在v1.16.0中更改:现在这是一个由位指示符组成的整数。之前是字典。

包含访问文档的权限。这是一个整数,包含相应位位置的布尔值。例如,如果doc.permissions & pymupdf.PDF_PERM_MODIFY > 0,则表示您可以修改文档。有关详细信息,请参见Document Permissions

类型int

metadata

包含文档的元数据,作为Python字典或None(如果is_encrypted=TrueneedPass=True)。键包括formatencryptiontitleauthorsubjectkeywordscreatorproducercreationDatemodDatetrapped。所有项的值为字符串或None

除了formatencryption,对于PDF文档,键名称与PDF中的/Creator/Producer/CreationDate/ModDate/Title/Author/Subject/Trapped/Keywords有明显的对应关系。

format包含文档格式(例如‘PDF-1.6’,‘XPS’,‘EPUB’)。

encryption包含None(无加密)或命名的加密方法(例如‘Standard V4 R4 128-bit RC4’)。请注意,即使needs_pass=False,也可以指定加密方法。在这种情况下,可能没有授予所有权限。请检查Document.permissions以了解详细信息。

如果日期字段包含有效数据(不一定是必须的!),它们以PDF特定的时间戳格式“D:”表示,其中是12个字符的ISO时间戳(YYYYMMDDhhmmss),是时区值(相对于GMT的时间间隔)。

类型dict

name

包含创建Document时使用的文件名或文件类型值。

类型str

page_count

包含文档的页面数量。对于没有页面的文档,返回0。len(doc)也会返回此结果。

类型int

chapter_count

新特性:v1.17.0

包含文档中的章节数量。对于支持章节的文档(目前仅支持EPUB),始终至少为1。对于其他文档,返回1。

类型int

last_location

新特性:v1.17.0

包含文档最后一页的位置(章节、页面编号)。对于支持章节的文档(目前仅支持EPUB),返回有效的章节和页面编号。如果没有页面,则返回(0, -1)

类型int

FormFonts

一个包含在/AcroForm对象中定义的表单字段字体名称的列表。如果不是PDF,则返回None

类型list

注意
对于更改PDF结构的方法(如insert_pdf()select()copy_page()delete_page()等),请注意,程序中的对象或属性可能会失效或变成孤立对象。例如,Page对象及其子对象(链接、注释、控件)、保存的旧页面计数、目录等。记得保持这些变量的更新或删除孤立对象。还请参考PyMuPDF中的确保一致性。

Document典型样例

set_metadata()例子

清除元数据。如果出于隐私/数据保护考虑执行此操作,请确保将文档保存为新文件,并且垃圾回收器参数大于0。这样,旧的/Info对象将被从文件中物理移除。在这种情况下,您可能还需要清除由多个PDF编辑器插入的XML元数据:

>>> import pymupdf
>>> doc=pymupdf.open("pymupdf.pdf")
>>> doc.metadata             # look at what we currently have
{'producer': 'rst2pdf, reportlab', 'format': 'PDF 1.4', 'encryption': None, 'author':
'Jorj X. McKie', 'modDate': "D:20160611145816-04'00'", 'keywords': 'PDF, XPS, EPUB, CBZ',
'title': 'The PyMuPDF Documentation', 'creationDate': "D:20160611145816-04'00'",
'creator': 'sphinx', 'subject': 'PyMuPDF 1.9.1'}
>>> doc.set_metadata({})      # clear all fields
>>> doc.metadata             # look again to show what happened
{'producer': 'none', 'format': 'PDF 1.4', 'encryption': None, 'author': 'none',
'modDate': 'none', 'keywords': 'none', 'title': 'none', 'creationDate': 'none',
'creator': 'none', 'subject': 'none'}
>>> doc.del_xml_metadata()    # clear any XML metadata
>>> doc.save("anonymous.pdf", garbage = 4)       # save anonymized doc

set_toc() 例子

这展示了如何修改或添加目录。也可以查看 import.py 和 export.py 示例文件。

>>> import pymupdf
>>> doc = pymupdf.open("test.pdf")
>>> toc = doc.get_toc()
>>> for t in toc: print(t)                           # show what we have
[1, 'The PyMuPDF Documentation', 1]
[2, 'Introduction', 1]
[3, 'Note on the Name fitz', 1]
[3, 'License', 1]
>>> toc[1][1] += " modified by set_toc"               # modify something
>>> doc.set_toc(toc)                                  # replace outline tree
3                                                    # number of bookmarks inserted
>>> for t in doc.get_toc(): print(t)                  # demonstrate it worked
[1, 'The PyMuPDF Documentation', 1]
[2, 'Introduction modified by set_toc', 1]            # <<< this has changed
[3, 'Note on the Name fitz', 1]
[3, 'License', 1]

insert_pdf() 例子

(1) 合并两个文档并包括它们的目录:

>>> doc1 = pymupdf.open("file1.pdf")          # must be a PDF
>>> doc2 = pymupdf.open("file2.pdf")          # must be a PDF
>>> pages1 = len(doc1)                     # save doc1's page count
>>> toc1 = doc1.get_toc(False)     # save TOC 1
>>> toc2 = doc2.get_toc(False)     # save TOC 2
>>> doc1.insert_pdf(doc2)                   # doc2 at end of doc1
>>> for t in toc2:                         # increase toc2 page numbers
        t[2] += pages1                     # by old len(doc1)
>>> doc1.set_toc(toc1 + toc2)               # now result has total TOC

显然,可以在更一般的情况下找到类似的方法。只需确保层级不增加超过1即可。在toc2段之前和之后插入虚拟书签就能修复这种情况。还可以在示例目录中的 join.py 脚本中找到一个现成的GUI解决方案(wxPython)。

(2) 更多示例:

>>> # insert 5 pages of doc2, where its page 21 becomes page 15 in doc1
>>> doc1.insert_pdf(doc2, from_page=21, to_page=25, start_at=15)

>>> # same example, but pages are rotated and copied in reverse order
>>> doc1.insert_pdf(doc2, from_page=25, to_page=21, start_at=15, rotate=90)

>>> # put copied pages in front of doc1
>>> doc1.insert_pdf(doc2, from_page=21, to_page=25, start_at=0)

其他例子

提取PDF中所有页面引用的图像并保存为单独的PNG文件:

for i in range(doc.page_count):
    imglist = doc.get_page_images(i)
    for img in imglist:
        xref = img[0]                  # xref number
        pix = pymupdf.Pixmap(doc, xref)   # make pixmap from image
        if pix.n - pix.alpha < 4:      # can be saved as PNG
            pix.save("p%s-%s.png" % (i, xref))
        else:                          # CMYK: must convert first
            pix0 = pymupdf.Pixmap(pymupdf.csRGB, pix)
            pix0.save("p%s-%s.png" % (i, xref))
            pix0 = None                # free Pixmap resources
        pix = None                     # free Pixmap resources

旋转PDF的所有页面:

>>> for page in doc: page.set_rotation(90)

总结

本文详细介绍了PyMupdf中的Document类的各个方法和属性,便于Python调用参考。后续会继续介绍更多的类的详情和调用方法。

你可能感兴趣的:(Python学习笔记,pdf,python,PDF文件提取,PDF内容提取,PDF数据提取,PDF,RAG,PDF文件内容提取)