PyMuPDF-1-24-4-中文文档-一-

PyMuPDF 1.24.4 中文文档(一)

原文:https://pymupdf.readthedocs.io/en/latest/

PyMuPDF 文档 1.24.4

来源:pymupdf.readthedocs.io/en/latest/

关于

功能比较

原文:pymupdf.readthedocs.io/en/latest/about.html

功能矩阵

下表展示了 PyMuPDF 与其他典型解决方案的比较。

_images/icon-pdf.svg _images/icon-svg.svg _images/icon-xps.svg _images/icon-cbz.svg _images/icon-mobi.svg _images/icon-epub.svg _images/icon-image.svg _images/icon-fb2.svg _images/icon-txt.svg _images/icon-docx.svg _images/icon-pptx.svg _images/icon-xlsx.svg _images/icon-hangul.svg

功能 PyMuPDF pikepdf PyPDF2 pdfrw pdfplumber / pdfminer

| 支持多种文档格式 | PDF XPS EPUB MOBI FB2 CBZ SVG TXT 图片


DOCX XLSX PPTX HWPX 见 注释 | PDF | PDF | PDF | PDF |

实现方式 Python 和 C Python 和 C++ Python Python Python
渲染文档页面 所有文档类型 不支持渲染 不支持渲染 不支持渲染 不支持渲染

| 向 PDF 页面写入文本 | 见:Page.insert_htmlbox

或:

Page.insert_textbox

或:

TextWriter | | | | |

支持 CJK 字符
提取文本 所有文档类型 仅限 PDF 仅限 PDF
将文本提取为 Markdown (.md) 所有文档类型
提取表格 所有文档类型 仅限 PDF
提取矢量图形 所有文档类型 有限
绘制矢量图形(PDF)
基于现有的成熟库 MuPDF QPDF
自动修复损坏的 PDF
加密 PDF 有限 有限
线性化 PDF
增量更新
与 Jupyter 和 IPython 笔记本集成
将 PDF 与其他文档类型合并/合并 所有文档类型 仅限 PDF 仅限 PDF 仅限 PDF 仅限 PDF
OCR API 与 Tesseract 的无缝集成 所有文档类型
集成式检查点 / 重新启动功能(PDF)
PDF 可选内容
PDF 嵌入式文件 有限 有限
PDF 文件编辑
PDF 注释 完整 有限
PDF 表单字段 创建、读取、更新 有限,无创建
PDF 页面标签
支持字体子集化

_images/icon-docx.svg _images/icon-xlsx.svg _images/icon-pptx.svg _images/icon-hangul.svg

注意

关于 Office 文档类型(DOCX、XLXS、PPTX)和 Hangul 文档(HWPX)的说明。这些文档可以加载到 PyMuPDF 中,您将获得一个 文档 对象。

还有一些注意事项:

  • 我们将输入转换为 HTML 以布局内容。
  • 因此,原始页面分隔已经消失。

当保存结果时,不应期望任何忠实于原始布局的表示。

因此,输入文件大多以便于文本提取的形式呈现。

      • 特性矩阵

以下表格说明了 PyMuPDF 与其他典型解决方案的比较。

_images/icon-pdf.svg _images/icon-svg.svg _images/icon-xps.svg _images/icon-cbz.svg _images/icon-mobi.svg _images/icon-epub.svg _images/icon-image.svg _images/icon-fb2.svg _images/icon-txt.svg _images/icon-docx.svg _images/icon-pptx.svg _images/icon-xlsx.svg _images/icon-hangul.svg

特性 PyMuPDF pikepdf PyPDF2 pdfrw pdfplumber / pdfminer

| 支持多种文档格式 | PDF XPS EPUB MOBI FB2 CBZ SVG TXT Image


DOCX、XLSX、PPTX、HWPX 请见 注 | PDF | PDF | PDF | PDF |

实现 Python 和 C Python 和 C++ Python Python Python
渲染文档页面 所有文档类型 不进行渲染 不进行渲染 不进行渲染 不进行渲染

| 将文本写入 PDF 页面 | 参见:Page.insert_htmlbox

或者:

Page.insert_textbox

或者:

TextWriter | | | | |

支持 CJK 字符
提取文本 所有文档类型 仅限 PDF 仅限 PDF
提取 Markdown 格式的文本 (.md) 所有文档类型
提取表格 所有文档类型 仅限 PDF
提取矢量图形 所有文档类型 有限
绘制矢量图形(PDF)
基于现有成熟库 MuPDF QPDF
损坏 PDF 文件的自动修复
加密 PDF 有限 有限
线性化 PDF
增量更新
与 Jupyter 和 IPython 笔记本集成
合并 PDF 与其他文档类型 所有文档类型 仅限 PDF 仅限 PDF 仅限 PDF 仅限 PDF
无缝集成 OCR API 与 Tesseract 所有文档类型
集成的检查点/重启功能(PDF)
PDF 可选内容
PDF 嵌入文件 有限 有限
PDF 编辑
PDF 批注 完整 有限
PDF 表单字段 创建、读取、更新 有限,不支持创建
PDF 页面标签
支持字体子集

_images/icon-docx.svg _images/icon-xlsx.svg _images/icon-pptx.svg _images/icon-hangul.svg

注意

关于Office文档类型(DOCX、XLXS、PPTX)和Hangul文档(HWPX)的说明。这些文档可以加载到 PyMuPDF 中,您将收到一个文档对象。

这里有一些注意事项:

  • 我们将输入转换为HTML以布局内容。
  • 由于这个原始页面分隔已经消失。

在保存结果时,不能期望得到原始布局的忠实表示。

因此,输入文件大多数情况下是有利于文本提取的形式。


性能

为了对 PyMuPDF 在一系列任务中的性能进行基准测试,使用了一个固定的测试套件,其中包含了 8 个 PDF 文件,共 7031 页,包含文本和图像,以获取性能时间。

这里是按任务分组的当前结果:

复制

这是指打开文档,然后将其保存为新文件。此测试测量了读取 PDF 和重写为新 PDF 的速度。这一过程也是类似合并/连接多个文档的核心功能。因此,下面的数字适用于 PDF 合并和连接。

所有 7,031 页的结果如下:

600500400300200100

seconds3.0510.5433.57494.04PyMuPDFPDFrwPikePDFPyPDF2fastest←←slowest

文本提取

这是指从文档的每一页提取简单的纯文本,并将其存储在文本文件中。

所有 7,031 页的结果如下:

400300200100

seconds8.0127.42101.64227.27PyMuPDFXPDFPyPDF2PDFMinerfastest←←slowest

渲染

这是指根据给定 DPI 分辨率从文档的每一页制作图像(如 PNG)。此功能是在 GUI 窗口中显示文档的基础。

所有 7,031 页的结果如下:

1000800600400200

seconds367.04646851.52PyMuPDFXPDFPDF2JPGfastest← *注

有关这些性能计时方法的详细信息,请参阅:性能比较方法论。

许可和版权

PyMuPDF 和 MuPDF 现在都提供开源的 AGPL 和商业许可证。请阅读 AGPL 许可协议的完整文本,可在发行材料(COPYING 文件)和这里找到,以确保您的使用符合许可指南。如果确定无法满足 AGPL 的要求,请联系Artifex获取有关商业许可的更多信息。

Artifex 是 MuPDF 的独家商业许可代理。

Artifex、Artifex 标志、MuPDF 和 MuPDF 标志是 Artifex Software Inc. 的注册商标。


本文档涵盖了 PyMuPDF v1.24.4 的功能,截至 2024-05-16 00:00:01

PyMuPDFMuPDF 的主要版本和次要版本将始终保持一致。只有第三个限定符(补丁级别)可能与 MuPDF 稍有不同。

对本页有任何反馈意见吗?


本软件按“现状”提供,不附带任何明示或暗示的保证。本软件根据许可分发,除非根据该许可明确授权,否则不得复制、修改或分发。有关许可信息,请参阅artifex.com或联系美国加利福尼亚州旧金山 Mesa Street 39 号 108A 室的 Artifex Software Inc. 了解更多信息。

本文档涵盖所有版本直到 1.24.4。

Discord logo*

用户指南

安装:

原文:pymupdf.readthedocs.io/en/latest/installation.html

要求:

下面的所有示例都假设您正在运行 Python 虚拟环境中。请参阅:docs.python.org/3/library/venv.html 了解详细信息。我们还假设 pip 已经更新到最新版本。

例如:

  • Windows:

    py -m venv pymupdf-venv
    .\pymupdf-venv\Scripts\activate
    python -m pip install --upgrade pip 
    
  • Linux,MacOS:

    python -m venv pymupdf-venv
    . pymupdf-venv/bin/activate
    python -m pip install --upgrade pip 
    

安装:

PyMuPDF 应该使用 pip 进行安装:

pip install --upgrade pymupdf 

如果您的平台有 Python wheel 可用,将从 Python wheel 安装。

当没有合适的 Wheel 可用时的安装:

如果没有合适的 Python Wheel 可用,pip 将自动使用 Python sdist 从源代码构建。

这需要安装 C/C++ 开发工具

  • 在 Windows 上:

    • 安装 Visual Studio 2019. 如果未安装在标准位置,请将环境变量 PYMUPDF_SETUP_DEVENV 设置为 devenv.com 二进制文件的位置。

    • 如果安装了其他版本的 Visual Studio,例如 Visual Studio 2022,可能会出现问题,因为可能会出现 MuPDF 和 PyMuPDF 代码使用不同的编译器版本进行编译的情况。

构建将自动下载并构建 MuPDF。

安装后出现的问题:

注意事项:

Windows(32 位 Intel,64 位 Intel),Linux(64 位 Intel,64 位 ARM)和 Mac OSX(64 位 Intel,64 位 ARM)均提供 Wheels,在 devguide.python.org/versions/ 上标记为“Supported”的 Python 版本。

Windows 上不提供 Python 使用 Chocolatey 安装的 Wheels。而是使用来自 python.org 网站的 Windows 安装程序安装 Python,参见:www.python.org/downloads

PyMuPDF 不支持 Python 版本 3.8 之前的版本。旧版 Wheels 可在 仓库和 PyPI 上找到。请注意,我们通常遵循官方 Python 发布计划。对于停止官方支持的 Python 版本,这意味着将停止生成 Wheels。

没有强制要求的外部依赖项。但是,某些可选功能仅在安装了额外组件时才可用:

  • Pixmap.pil_save()Pixmap.pil_tobytes() 需要Pillow

  • Document.subset_fonts() 需要fontTools

  • pymupdf-fonts 是一组用于文本输出方法的漂亮字体集合。

  • 用于图像和文档页面光学字符识别的Tesseract-OCR。Tesseract 是独立软件,不是 Python 包。要在 PyMuPDF 中启用 OCR 功能,必须安装该软件,并定义系统环境变量"TESSDATA_PREFIX"并包含 Tesseract 安装位置的tessdata文件夹名称。见下文。

注意

您可以随时安装这些额外组件 - 在安装 PyMuPDF 之前或之后。PyMuPDF 将在导入时或使用相关功能时检测它们的存在。

从本地 PyMuPDF 源代码树构建和安装

初始设置:

  • 按照上述方式安装 C/C++开发工具。

  • 进入 Python 虚拟环境并更新 pip,如上所述。

  • 获取 PyMuPDF 源代码树:

然后可以以两种方式构建 PyMuPDF:

  • 使用默认 MuPDF 版本构建并安装 PyMuPDF:

    cd PyMuPDF && pip install . 
    

    这将自动下载一个特定的硬编码 MuPDF 源代码发布版,并将其构建到 PyMuPDF 中。

  • 或使用本地 MuPDF 源码树构建并安装 PyMuPDF:

    • 克隆 MuPDF git 仓库:

      git clone --recursive https://git.ghostscript.com/mupdf.git 
      
    • 构建 PyMuPDF 时,请使用环境变量PYMUPDF_SETUP_MUPDF_BUILD指定本地 MuPDF 树的位置:

      cd PyMuPDF && PYMUPDF_SETUP_MUPDF_BUILD=../mupdf pip install . 
      

另外,可以在同一个 PyMuPDF 树中为不同的 Python 版本构建:

  • PyMuPDF 将为运行pip的 Python 版本构建。要使用特定 Python 版本运行pip,请使用python -m pip而不是pip

    例如在 Windows 上可以构建不同版本:

    cd PyMuPDF && py -3.9 -m pip install . 
    

    或者:

    cd PyMuPDF && py -3.10-32 -m pip install . 
    

运行测试

有一个 PyMuPDF 树可用允许运行 PyMuPDF 的pytest测试套件:

pip install pytest fontTools
pytest PyMuPDF/tests 

使用非默认 MuPDF 的注意事项

通过设置环境变量PYMUPDF_SETUP_MUPDF_BUILD来使用非默认 MuPDF 版本可能会导致各种问题,因此通常不受支持:

  • 如果 MuPDF 的主版本号与 PyMuPDF 默认使用的不同,PyMuPDF 可能无法构建,因为 MuPDF 的 API 在主版本之间可能会发生变化。

  • 运行时行为可能会因为 MuPDF 不同次要版本的运行时行为而发生变化。这也可能会导致一些 PyMuPDF 测试失败。

  • 如果 MuPDF 是使用其默认配置而不是 PyMuPDF 的定制配置构建的(例如,如果 MuPDF 是系统安装的),可能会导致 tests/test_textbox.py:test_textbox3() 失败。可以通过在 pytest 命令行中添加 -k 'not test_textbox3' 来跳过此特定测试。

打包

参见 Linux 发行版的打包。

使用 Pyodide

参见 Pyodide。

启用集成 OCR 支持

如果您不打算使用此功能,请跳过此步骤。否则,它在安装路径和源代码两者上都是必需的 来自轮子和源代码。

PyMuPDF 已经包含了所有支持 OCR 功能所需的逻辑。但它还需要 Tesseract 的语言支持数据

必须通过将其存储在环境变量 "TESSDATA_PREFIX" 中或作为适用函数的参数来传递语言支持文件夹位置。

因此,为了使 OCR 功能正常工作,请确保完成此检查表:

  1. 定位 Tesseract 的语言支持文件夹。通常情况下,你可以在这里找到它:

    • Windows:C:/Program Files/Tesseract-OCR/tessdata

    • Unix 系统:/usr/share/tesseract-ocr/4.00/tessdata

  2. 设置环境变量 TESSDATA_PREFIX

    • Windows:setx TESSDATA_PREFIX "C:/Program Files/Tesseract-OCR/tessdata"

    • Unix 系统:declare -x TESSDATA_PREFIX=/usr/share/tesseract-ocr/4.00/tessdata

在 Windows 系统上,在启动脚本之前必须在 Python 之外完成此步骤。仅仅操作 os.environ 是不够的!

对此页面有任何反馈吗?


本软件按原样提供,不提供任何形式的保证,明示或暗示。本软件根据许可分发,未经许可不得复制、修改或分发。有关详细信息,请参阅 artifex.com,或联系美国加利福尼亚州旧金山 94129 号 Mesa Street 39 号,Artifex Software Inc.。

此文档涵盖所有版本直到 1.24.4。

Discord logo

要求

下面的所有示例假定您正在运行 Python 虚拟环境内。参见:docs.python.org/3/library/venv.html 获取详细信息。我们还假设 pip 已经更新。

例如:

  • Windows:

    py -m venv pymupdf-venv
    .\pymupdf-venv\Scripts\activate
    python -m pip install --upgrade pip 
    
  • Linux、MacOS:

    python -m venv pymupdf-venv
    . pymupdf-venv/bin/activate
    python -m pip install --upgrade pip 
    

安装

PyMuPDF 应该使用以下命令安装:pip install PyMuPDF

pip install --upgrade pymupdf 

如果适用于您的平台存在 Python 轮子,将从 Python 轮子安装。

在适当的轮子不可用时的安装

如果适当的 Python 轮子不可用,pip 将自动使用 Python sdist 从源代码构建。

这需要安装 C/C++ 开发工具

  • 在 Windows 上:

    • 安装 Visual Studio 2019。如果未安装在标准位置,请将环境变量PYMUPDF_SETUP_DEVENV设置为devenv.com二进制文件的位置。

    • 安装其他版本的 Visual Studio,例如 Visual Studio 2022,可能会导致问题,因为 MuPDF 和 PyMuPDF 代码可能使用不同的编译器版本编译。

构建将自动下载并构建 MuPDF。

安装后出现问题

对于支持的 Python 版本,“支持”标志为:“Windows(32 位 Intel,64 位 Intel),Linux(64 位 Intel,64 位 ARM)和 Mac OSX(64 位 Intel,64 位 ARM)”,有 Wheels 可用,详见 devguide.python.org/versions/

在 Windows 上,使用 Chocolatey 安装的 Python 不提供 Wheels。请使用来自 python.org 网站的 Windows 安装程序安装 Python,详见:www.python.org/downloads

PyMuPDF 不支持早于 3.8 版本的 Python。旧版本 Wheels 可在 仓库和 PyPI 上找到。请注意,我们通常遵循官方 Python 发布计划。对于不再得到官方支持的 Python 版本,我们将停止生成 Wheels。

没有强制性的外部依赖项。但是,仅当安装了额外组件时才可用某些可选功能。

  • 需要Pillow用于Pixmap.pil_save()Pixmap.pil_tobytes()

  • 需要fontTools用于Document.subset_fonts()

  • pymupdf-fonts 是一组用于文本输出方法的漂亮字体集合。

  • Tesseract-OCR 用于图像和文档页面的光学字符识别。Tesseract 是单独的软件,不是 Python 包。要在 PyMuPDF 中启用 OCR 功能,必须安装该软件并定义系统环境变量 "TESSDATA_PREFIX",其值应为 Tesseract 安装位置的 tessdata 文件夹名称。请参阅下文。

注意

您可以随时安装这些额外的组件 - 在安装 PyMuPDF 之前或之后。PyMuPDF 在导入时或使用相关函数时会检测它们的存在。

从本地 PyMuPDF 源码树构建和安装

初始设置:

  • 按照上述描述安装 C/C++ 开发工具。

  • 进入 Python venv 并按上述方法更新 pip。

  • 获取 PyMuPDF 源码树:

    • 克隆 PyMuPDF git 仓库:

      git clone https://github.com/pymupdf/PyMuPDF.git 
      
    • 或者从 github.com/pymupdf/PyMuPDF/releases 下载和解压缩 .zip.tar.gz 源代码发布。

然后可以以两种方式构建 PyMuPDF:

  • 使用默认 MuPDF 版本构建并安装 PyMuPDF:

    cd PyMuPDF && pip install . 
    

    这将自动下载一个特定的硬编码 MuPDF 源码发布版本,并将其构建到 PyMuPDF 中。

  • 或者使用本地 MuPDF 源码树构建并安装 PyMuPDF:

    • 克隆 MuPDF git 仓库:

      git clone --recursive https://git.ghostscript.com/mupdf.git 
      
    • 使用环境变量 PYMUPDF_SETUP_MUPDF_BUILD 指定本地 MuPDF 树的位置构建 PyMuPDF:

      cd PyMuPDF && PYMUPDF_SETUP_MUPDF_BUILD=../mupdf pip install . 
      

同样,可以在同一 PyMuPDF 树中为不同的 Python 版本构建:

  • PyMuPDF 将为正在运行 pip 的 Python 版本构建。要使用特定的 Python 版本运行 pip,请使用 python -m pip 而不是 pip

    例如,在 Windows 上可以构建不同版本:

    cd PyMuPDF && py -3.9 -m pip install . 
    

    或者:

    cd PyMuPDF && py -3.10-32 -m pip install . 
    

运行测试

有一个 PyMuPDF 树可用允许运行 PyMuPDF 的 pytest 测试套件:

pip install pytest fontTools
pytest PyMuPDF/tests 

使用非默认的 MuPDF 的注意事项

通过设置环境变量 PYMUPDF_SETUP_MUPDF_BUILD 使用非默认的 MuPDF 构建可能导致各种问题,因此通常不受支持:

  • 如果 MuPDF 的主要版本号与 PyMuPDF 默认使用的版本不同,PyMuPDF 可能构建失败,因为 MuPDF 的 API 可能在主要版本之间发生变化。

  • PyMuPDF 的运行时行为可能会改变,因为 MuPDF 在不同的次要版本之间的运行时行为会发生变化。这也可能导致一些 PyMuPDF 测试失败。

  • 如果 MuPDF 是使用其默认配置而不是 PyMuPDF 的定制配置构建的(例如,如果 MuPDF 是系统安装),可能会导致 tests/test_textbox.py:test_textbox3() 失败。可以通过在 pytest 命令行中添加 -k 'not test_textbox3' 跳过此特定测试。

使用非默认的 MuPDF 的注意事项

通过设置环境变量 PYMUPDF_SETUP_MUPDF_BUILD 使用非默认的 MuPDF 构建可能导致各种问题,因此通常不受支持:

  • 如果 MuPDF 的主要版本号与 PyMuPDF 默认使用的版本不同,PyMuPDF 可能构建失败,因为 MuPDF 的 API 可能在主要版本之间发生变化。

  • PyMuPDF 的运行行为可能会因 MuPDF 在不同小版本之间的运行行为变化而改变。这可能会导致一些 PyMuPDF 测试失败。

  • 如果 MuPDF 是使用其默认配置而不是 PyMuPDF 的定制配置构建的(例如,如果 MuPDF 是系统安装的),则可能会导致tests/test_textbox.py:test_textbox3()测试失败。可以通过在pytest命令行中添加-k 'not test_textbox3'来跳过这个特定的测试。

打包

参见 Linux 发行版的打包。

使用 Pyodide

参见 Pyodide。

启用集成 OCR 支持

如果您不打算使用此功能,请跳过此步骤。否则,它在两种安装路径上都是必需的:从 wheel 和从源代码安装。

PyMuPDF 已经包含了所有支持 OCR 功能所需的逻辑。但它还需要Tesseract 的语言支持数据

必须通过将语言支持文件夹位置存储在环境变量"TESSDATA_PREFIX"中或作为适用函数的参数来传达。

因此,为了使 OCR 功能正常工作,请确保完成以下检查列表:

  1. 定位 Tesseract 的语言支持文件夹。通常您会在这里找到它:

    • Windows:C:/Program Files/Tesseract-OCR/tessdata

    • Unix 系统:/usr/share/tesseract-ocr/4.00/tessdata

  2. 设置环境变量TESSDATA_PREFIX

    • Windows:setx TESSDATA_PREFIX "C:/Program Files/Tesseract-OCR/tessdata"

    • Unix 系统:declare -x TESSDATA_PREFIX=/usr/share/tesseract-ocr/4.00/tessdata

注意

在 Windows 系统上,这必须在 Python 之外完成——在启动脚本之前。仅仅操作os.environ是不起作用的!

对此页面有任何反馈吗?


本软件按原样提供,不带任何明示或暗示的担保。本软件根据许可分发,未经许可不得复制、修改或分发。请参阅artifex.com的许可信息或联系美国加利福尼亚州旧金山市 Mesa 街 39 号 108A 套房的 Artifex Software Inc.获取更多信息。

本文档涵盖所有版本直至 1.24.4。

Discord logo

基础知识

原文:pymupdf.readthedocs.io/en/latest/the-basics.html

打开文件

要打开文件,请执行以下操作:

import pymupdf

doc = pymupdf.open("a.pdf") # open a document 

注意

深入了解

请参阅 supported file types 和如何打开文件指南了解更多高级选项。

      • 从 PDF 中提取文本

要从 PDF 文件中提取所有文本,请执行以下操作:

import pymupdf

doc = pymupdf.open("a.pdf") # open a document
out = open("output.txt", "wb") # create a text output
for page in doc: # iterate the document pages
    text = page.get_text().encode("utf8") # get plain text (is in UTF-8)
    out.write(text) # write text of page
    out.write(bytes((12,))) # write page delimiter (form feed 0x0C)
out.close() 

当然,不仅 PDF 可以提取文本 - 所有 supported document file formats 如 MOBI、EPUB、TXT 等都可以提取其文本。

注意

深入了解

如果您的文档包含基于图像的文本内容,则在页面上使用 OCR 进行后续文本提取:

tp = page.get_textpage_ocr()
text = page.get_text(textpage=tp) 

有许多其他示例可以解释如何从特定区域提取文本或从文档中提取表格。请参阅文本操作指南。

现在您也可以以 Markdown 格式提取文本了提取文本。

API 参考

  • Page.get_text()
      • 从 PDF 中提取图像

要从 PDF 文件中提取所有图像,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document

for page_index in range(len(doc)): # iterate over pdf pages
    page = doc[page_index] # get the page
    image_list = page.get_images()

    # print the number of images found on the page
    if image_list:
        print(f"Found {len(image_list)} images on page {page_index}")
    else:
        print("No images found on page", page_index)

    for image_index, img in enumerate(image_list, start=1): # enumerate the image list
        xref = img[0] # get the XREF of the image
        pix = pymupdf.Pixmap(doc, xref) # create a Pixmap

        if pix.n - pix.alpha > 3: # CMYK: convert to RGB first
            pix = pymupdf.Pixmap(pymupdf.csRGB, pix)

        pix.save("page_%s-image_%s.png" % (page_index, image_index)) # save the image as png
        pix = None 

注意

深入了解

有许多其他示例可以解释如何从特定区域提取文本或从文档中提取表格。请参阅文本操作指南。

API 参考

  • Page.get_images()

  • Pixmap ## 提取矢量图形

要从文档页面提取所有矢量图形,请执行以下操作:

doc = pymupdf.open("some.file")
page = doc[0]
paths = page.get_drawings() 

这将返回在页面上找到的任何矢量图形的路径字典。

注意

深入了解

请参阅:如何提取绘图。

API 参考

  • Page.get_drawings()
      • 合并 PDF 文件

要合并 PDF 文件,请执行以下操作:

import pymupdf

doc_a = pymupdf.open("a.pdf") # open the 1st document
doc_b = pymupdf.open("b.pdf") # open the 2nd document

doc_a.insert_pdf(doc_b) # merge the docs
doc_a.save("a+b.pdf") # save the merged document with a new filename 

使用其他类型文件合并 PDF 文件

使用Document.insert_file()方法来合并 supported files 与 PDF。例如:

import pymupdf

doc_a = pymupdf.open("a.pdf") # open the 1st document
doc_b = pymupdf.open("b.svg") # open the 2nd document

doc_a.insert_file(doc_b) # merge the docs
doc_a.save("a+b.pdf") # save the merged document with a new filename 

注意

深入了解

使用Document.insert_pdf() & Document.insert_file()很容易合并 PDF。通过打开的 PDF 文档,您可以从一个文档复制页面范围到另一个文档。您可以选择复制页面的位置,可以恢复页面顺序,还可以更改页面旋转。这篇维基文章包含了详细说明。

GUI 脚本join.py使用此方法合并文件列表,同时还合并了相应的目录段。看起来像这样:

_images/img-pdfjoiner.jpg

API 参考

  • Document.insert_pdf()

  • Document.insert_file()


使用坐标工作

使用PyMuPDF时,有一个数学术语您应该熟悉 - “坐标”。请快速查看坐标部分,了解坐标系统,以帮助您定位对象并了解文档空间。


给 PDF 添加水印

要向 PDF 文件添加水印,请执行以下操作:

import pymupdf

doc = pymupdf.open("document.pdf") # open a document

for page_index in range(len(doc)): # iterate over pdf pages
    page = doc[page_index] # get the page

    # insert an image watermark from a file name to fit the page bounds
    page.insert_image(page.bound(),filename="watermark.png", overlay=False)

doc.save("watermarked-document.pdf") # save the document with a new filename 

注意

深入了解

添加水印本质上就是在每个 PDF 页面底部添加一个图像。您应确保图像具有所需的不透明度和纵横比,使其看起来符合您的需求。

在上述示例中,每个文件引用都创建了一个新图像,但为了更高效(节省内存和文件大小),应该仅引用此图像数据一次 - 有关实现,请参阅Page.insert_image()的代码示例和解释。

API 参考

  • Page.bound()

  • Page.insert_image()

      • 向 PDF 添加图像

要向 PDF 文件添加图像,例如标志,请执行以下操作:

import pymupdf

doc = pymupdf.open("document.pdf") # open a document

for page_index in range(len(doc)): # iterate over pdf pages
    page = doc[page_index] # get the page

    # insert an image logo from a file name at the top left of the document
    page.insert_image(pymupdf.Rect(0,0,50,50),filename="my-logo.png")

doc.save("logo-document.pdf") # save the document with a new filename 

注意

深入了解

就像水印示例一样,如果可能,应确保通过仅引用一次图像来提高性能 - 有关实现,请参阅Page.insert_image()的代码示例和解释。

API 参考

  • 矩形

  • Page.insert_image()

      • 旋转 PDF

要向页面添加旋转,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open document
page = doc[0] # get the 1st page of the document
page.set_rotation(90) # rotate the page
doc.save("rotated-page-1.pdf") 

注意

API 参考

  • Page.set_rotation()
      • 裁剪 PDF

要将页面裁剪为定义的矩形,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open document
page = doc[0] # get the 1st page of the document
page.set_cropbox(pymupdf.Rect(100, 100, 400, 400)) # set a cropbox for the page
doc.save("cropped-page-1.pdf") 

注意

API 参考

  • Page.set_cropbox()
      • 附加文件

要向页面附加另一个文件,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open main document
attachment = pymupdf.open("my-attachment.pdf") # open document you want to attach

page = doc[0] # get the 1st page of the document
point = pymupdf.Point(100, 100) # create the point where you want to add the attachment
attachment_data = attachment.tobytes() # get the document byte data as a buffer

# add the file annotation with the point, data and the file name
file_annotation = page.add_file_annot(point, attachment_data, "attachment.pdf")

doc.save("document-with-attachment.pdf") # save the document 

注意

深入了解

使用Page.add_file_annot()添加文件时,请注意filename的第三个参数应包括实际的文件扩展名。如果没有这个,附件可能无法被识别为可以打开的内容。例如,如果filename只是“附件”,则在查看生成的 PDF 并尝试打开附件时可能会出现错误。但是,使用“附件.pdf”则可以被 PDF 查看器识别并打开为有效的文件类型。

附件的默认图标默认是“推销钉”,但您可以通过设置icon参数来更改它。

API 参考

  • Document.tobytes()

  • Page.add_file_annot()

      • 嵌入文件

要将文件嵌入文档中,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open main document
embedded_doc = pymupdf.open("my-embed.pdf") # open document you want to embed

embedded_data = embedded_doc.tobytes() # get the document byte data as a buffer

# embed with the file name and the data
doc.embfile_add("my-embedded_file.pdf", embedded_data)

doc.save("document-with-embed.pdf") # save the document 

注意

进一步进行

就像附加文件时,使用Document.embfile_add()添加文件时,请注意filename的第一个参数应包括实际的文件扩展名。

API 参考

  • Document.tobytes()

  • Document.embfile_add()

      • 删除页面

要从文档中删除页面,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document
doc.delete_page(0) # delete the 1st page of the document
doc.save("test-deleted-page-one.pdf") # save the document 

要从文档中删除多个页面,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document
doc.delete_pages(from_page=9, to_page=14) # delete a page range from the document
doc.save("test-deleted-pages.pdf") # save the document 

如果删除书签或超链接引用的页面会发生什么?

  • 书签(目录中的条目)将变为无效,并且将不再导航到任何页面。

  • 超链接将从包含它的页面中删除。该页面上的可见内容不会以任何方式改变。

注意

进一步进行

页面索引是从零开始的,因此要删除文档的第 10 页,您应该执行以下操作 doc.delete_page(9)

类似地,doc.delete_pages(from_page=9, to_page=14) 将删除第 10 页至第 15 页(包括第 10 页)。

API 参考

  • Document.delete_page()

  • Document.delete_pages()

      • 重新排列页面

要更改页面顺序,即重新排列页面,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document
doc.move_page(1,0) # move the 2nd page of the document to the start of the document
doc.save("test-page-moved.pdf") # save the document 

注意

API 参考

  • Document.move_page()
      • 复制页面

要复制页面,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document
doc.copy_page(0) # copy the 1st page and puts it at the end of the document
doc.save("test-page-copied.pdf") # save the document 

注意

API 参考

  • Document.copy_page()
      • 选择页面

要选择页面,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document
doc.select([0, 1]) # select the 1st & 2nd page of the document
doc.save("just-page-one-and-two.pdf") # save the document 

注意

进一步进行

使用 PyMuPDF,您可以复制、移动、删除或重新排列 PDF 页面的所有选项。存在直观的方法,允许您在页面级别上执行此操作,例如Document.copy_page()方法。

或者您可以准备一个完整的新页面布局,形式为 Python 序列,其中包含您想要的页码、您想要的顺序以及每个页面想要的次数。以下可能说明了可以使用Document.select()做什么。

doc.select([1, 1, 1, 5, 4, 9, 9, 9, 0, 2, 2, 2]) 

现在让我们为双面打印准备一个 PDF(在不直接支持此功能的打印机上):

页面数量由len(doc)给出(等同于doc.page_count)。以下列表分别表示偶数页和奇数页的页码:

p_even = [p in range(doc.page_count) if p % 2 == 0]
p_odd  = [p in range(doc.page_count) if p % 2 == 1] 

此代码片段创建相应的子文档,然后可以用于打印文档:

doc.select(p_even) # only the even pages left over
doc.save("even.pdf") # save the "even" PDF
doc.close() # recycle the file
doc = pymupdf.open(doc.name) # re-open
doc.select(p_odd) # and do the same with the odd pages
doc.save("odd.pdf") 

欲了解更多信息,请查看此 Wiki 文章

以下示例将颠倒所有页面的顺序(极快: Adobe PDF 参考手册的 756 页在几秒钟内完成):

lastPage = doc.page_count - 1
for i in range(lastPage):
    doc.move_page(lastPage, i) # move current last page to the front 

此代码片段将 PDF 与其自身复制,以便包含页面0, 1, …, n, 0, 1, …, n (非常快且几乎不增加文件大小!)

page_count = len(doc)
for i in range(page_count):
    doc.copy_page(i) # copy this page to after last page 

API 参考

  • Document.select()
      • 添加空白页

要添加空白页,请执行以下操作:

import pymupdf

doc = pymupdf.open(...) # some new or existing PDF document
page = doc.new_page(-1, # insertion point: end of document
                    width = 595, # page dimension: A4 portrait
                    height = 842)
doc.save("doc-with-new-blank-page.pdf") # save the document 

注意

进一步了解

使用此方法创建具有预定义纸张格式的页面:

w, h = pymupdf.paper_size("letter-l")  # 'Letter' landscape
page = doc.new_page(width = w, height = h) 

便捷函数paper_size()了解超过 40 种行业标准纸张格式供选择。要查看它们,请检查字典paperSizes。将所需的字典键传递给paper_size()以检索纸张尺寸。支持大小写。如果在格式名称后附加“-L”,则返回横向版本。

这里是一个三行代码,创建了一个带有一个空白页的 PDF。文件大小为 460 字节:

doc = pymupdf.open()
doc.new_page()
doc.save("A4.pdf") 

API 参考

  • Document.new_page()

  • paperSizes

      • 插入带文本内容的页面

使用Document.insert_page()方法也会插入新页面,并接受相同的widthheight参数。但它还允许您将任意文本插入新页面,并返回插入的行数。

import pymupdf

doc = pymupdf.open(...)  # some new or existing PDF document
n = doc.insert_page(-1, # default insertion point
                    text = "The quick brown fox jumped over the lazy dog",
                    fontsize = 11,
                    width = 595,
                    height = 842,
                    fontname = "Helvetica", # default font
                    fontfile = None, # any font file name
                    color = (0, 0, 0)) # text color (RGB) 

注意

进一步了解

文本参数可以是(序列的)字符串(假定 UTF-8 编码)。插入将从 Point(50, 72)开始,这是距离页面顶部一英寸下方并距左侧 50 点。返回插入的文本行数。

API 参考

  • Document.insert_page()
      • 分割单页

这涉及将 PDF 页面分割成任意大小的片段。例如,您可能有一个以Letter格式的 PDF 页面,您希望以四倍放大率打印:每个页面分割成 4 个片段,每个片段再放到Letter格式的单独 PDF 页面中。

import pymupdf

src = pymupdf.open("test.pdf")
doc = pymupdf.open()  # empty output PDF

for spage in src:  # for each page in input
    r = spage.rect  # input page rectangle
    d = pymupdf.Rect(spage.cropbox_position,  # CropBox displacement if not
                  spage.cropbox_position)  # starting at (0, 0)
    #--------------------------------------------------------------------------
    # example: cut input page into 2 x 2 parts
    #--------------------------------------------------------------------------
    r1 = r / 2  # top left rect
    r2 = r1 + (r1.width, 0, r1.width, 0)  # top right rect
    r3 = r1 + (0, r1.height, 0, r1.height)  # bottom left rect
    r4 = pymupdf.Rect(r1.br, r.br)  # bottom right rect
    rect_list = [r1, r2, r3, r4]  # put them in a list

    for rx in rect_list:  # run thru rect list
        rx += d  # add the CropBox displacement
        page = doc.new_page(-1,  # new output page with rx dimensions
                           width = rx.width,
                           height = rx.height)
        page.show_pdf_page(
                page.rect,  # fill all new page with the image
                src,  # input document
                spage.number,  # input page number
                clip = rx,  # which part to use of input page
            )

# that's it, save output file
doc.save("poster-" + src.name,
         garbage=3,  # eliminate duplicate objects
         deflate=True,  # compress stuff where possible
) 

示例:

_images/img-posterize.png

注意

API 参考

  • Page.cropbox_position()

  • Page.show_pdf_page()

      • 合并单页

这涉及将 PDF 页面合并以形成一个新的 PDF,其中每个页面组合两个或四个原始页面(也称为“2-up”,“4-up”等)。这可以用来创建小册子或类似缩略图的概览。

import pymupdf

src = pymupdf.open("test.pdf")
doc = pymupdf.open()  # empty output PDF

width, height = pymupdf.paper_size("a4")  # A4 portrait output page format
r = pymupdf.Rect(0, 0, width, height)

# define the 4 rectangles per page
r1 = r / 2  # top left rect
r2 = r1 + (r1.width, 0, r1.width, 0)  # top right
r3 = r1 + (0, r1.height, 0, r1.height)  # bottom left
r4 = pymupdf.Rect(r1.br, r.br)  # bottom right

# put them in a list
r_tab = [r1, r2, r3, r4]

# now copy input pages to output
for spage in src:
    if spage.number % 4 == 0:  # create new output page
        page = doc.new_page(-1,
                      width = width,
                      height = height)
    # insert input page into the correct rectangle
    page.show_pdf_page(r_tab[spage.number % 4],  # select output rect
                     src,  # input document
                     spage.number)  # input page number

# by all means, save new file using garbage collection and compression
doc.save("4up.pdf", garbage=3, deflate=True) 

示例:

_images/img-4up.png

注意

API 参考

  • Page.cropbox_position()

  • Page.show_pdf_page()

      • PDF 加密与解密

从版本 1.16.0 开始,完全支持 PDF 解密和加密(使用密码)。您可以执行以下操作:

  • 检查文档是否受密码保护/(仍然)加密(Document.needs_passDocument.is_encrypted)。

  • 获得对文档的访问授权(Document.authenticate())。

  • 使用 Document.save()Document.write() 设置 PDF 文件的加密详细信息,

    • 解密或加密内容
    • 设置密码(们)
    • 设置加密方法
    • 设置权限详细信息

注意

PDF 文档可能有两个不同的密码:

  • 所有者密码 提供完全的访问权限,包括更改密码、加密方法或权限详细信息。

  • 用户密码 根据建立的权限详细信息提供对文档内容的访问。如果存在,则在查看器中打开 PDF 时需要提供此密码。

方法 Document.authenticate() 将根据使用的密码自动建立访问权限。

下面的片段创建一个新的 PDF,并使用单独的用户和所有者密码加密它。授权允许打印、复制和注释,但对于使用用户密码进行身份验证的用户不允许进行任何更改。

import pymupdf

text = "some secret information" # keep this data secret
perm = int(
    pymupdf.PDF_PERM_ACCESSIBILITY # always use this
    | pymupdf.PDF_PERM_PRINT # permit printing
    | pymupdf.PDF_PERM_COPY # permit copying
    | pymupdf.PDF_PERM_ANNOTATE # permit annotations
)
owner_pass = "owner" # owner password
user_pass = "user" # user password
encrypt_meth = pymupdf.PDF_ENCRYPT_AES_256 # strongest algorithm
doc = pymupdf.open() # empty pdf
page = doc.new_page() # empty page
page.insert_text((50, 72), text) # insert the data
doc.save(
    "secret.pdf",
    encryption=encrypt_meth, # set the encryption method
    owner_pw=owner_pass, # set the owner password
    user_pw=user_pass, # set the user password
    permissions=perm, # set permissions
) 

注意

进一步探索

使用某些查看器(Nitro Reader 5)打开此文档会反映这些设置:

_images/img-encrypting.jpg

解密 将在未提供加密参数的情况下自动保存。

保留 PDF 的加密方法,请使用 encryption=pymupdf.PDF_ENCRYPT_KEEP 进行保存。如果 doc.can_save_incrementally() == True,还可以进行增量保存。

更改加密方法,请指定上述所有选项的完整范围(encryptionowner_pwuser_pwpermissions)。在这种情况下,不可进行增量保存

API 参考

  • Document.save()
      • 从页面提取表格

可以从任何文档 Page 找到并提取表格。

import pymupdf
from pprint import pprint

doc = pymupdf.open("test.pdf") # open document
page = doc[0] # get the 1st page of the document
tabs = page.find_tables() # locate and extract any tables on page
print(f"{len(tabs.tables)} found on {page}") # display number of found tables

if tabs.tables:  # at least one table found?
   pprint(tabs[0].extract())  # print content of first table 

注意

API 参考

  • Page.find_tables()

重要提示

还有 pdf2docx 提取表格方法,如果您愿意,它可以进行表格提取。

      • 获取页面链接

可以从 Page 中提取链接以返回 Link 对象。

import pymupdf

for page in doc: # iterate the document pages
    link = page.first_link  # a `Link` object or `None`

    while link: # iterate over the links on page
        # do something with the link, then:
        link = link.next # get next link, last one has `None` in its `next` 

注意

API 参考

  • Page.first_link()
      • 获取文档中的所有注释

页面上的注释(Annot)可以使用 page.annots() 方法检索。

import pymupdf

for page in doc:
    for annot in page.annots():
        print(f'Annotation on page: {page.number} with type: {annot.type} and rect: {annot.rect}') 

注意

API 参考

  • Page.annots()
      • PDF 中删除内容

删除是一种特殊类型的注释,可以标记在文档页面上,以表示应安全删除的页面上的区域。在用矩形标记区域后,此区域将被标记为删除,一旦应用删除,则内容将被安全地删除。

例如,如果我们想要从文档中删除所有“Jane Doe”名称的实例,我们可以执行以下操作:

import pymupdf

# Open the PDF document
doc = pymupdf.open('test.pdf')

# Iterate over each page of the document
for page in doc:
    # Find all instances of "Jane Doe" on the current page
    instances = page.search_for("Jane Doe")

    # Redact each instance of "Jane Doe" on the current page
    for inst in instances:
        page.add_redact_annot(inst)

    # Apply the redactions to the current page
    page.apply_redactions()

# Save the modified document
doc.save('redacted_document.pdf')

# Close the document
doc.close() 

另一个例子可能是删除页面的一个区域,但不删除定义区域内的任何线条艺术(即矢量图形),方法是设置以下参数标志:

import pymupdf

# Open the PDF document
doc = pymupdf.open('test.pdf')

# Get the first page
page = doc[0]

# Add an area to redact
rect = [0,0,200,200]

# Add a redacction annotation which will have a red fill color
page.add_redact_annot(rect, fill=(1,0,0))

# Apply the redactions to the current page, but ignore vector graphics
page.apply_redactions(graphics=0)

# Save the modified document
doc.save('redactied_document.pdf')

# Close the document
doc.close() 

警告

一旦保存了文档的删除版本,则 PDF 中的删除内容是无法检索的。因此,文档中的删除区域会完全删除文本和图形。

注意

进一步深入

有几种选项可用于创建和应用对页面的删除,要了解控制这些选项的参数的完整 API 详细信息,请参阅 API 参考。

API 参考

  • Page.add_redact_annot()

  • Page.apply_redactions()

      • 转换 PDF 文档

我们推荐使用 pdf2docx 库,该库使用 PyMuPDFpython-docx 库提供了从 PDF 格式转换为 DOCX 格式的简单文档转换。

对此页面有任何反馈吗?


此软件按原样提供,不带任何明示或暗示的担保。此软件在许可下分发,并且除非根据该许可的条款得到明确授权,否则不得复制、修改或分发。有关详细信息,请参阅artifex.com的许可信息或联系美国加利福尼亚州旧金山市 Mesa 街 39 号 108A 套房 Artifex Software Inc。94129,进一步了解。

此文档涵盖了所有版本直至 1.24.4。

Discord logo ## 打开一个文件

要打开文件,请执行以下操作:

import pymupdf

doc = pymupdf.open("a.pdf") # open a document 

注意

深入探讨

查看支持的文件类型列表和打开文件的指南以获取更高级的选项。


从 PDF 中提取文本

要从 PDF 文件提取所有文本,请执行以下操作:

import pymupdf

doc = pymupdf.open("a.pdf") # open a document
out = open("output.txt", "wb") # create a text output
for page in doc: # iterate the document pages
    text = page.get_text().encode("utf8") # get plain text (is in UTF-8)
    out.write(text) # write text of page
    out.write(bytes((12,))) # write page delimiter (form feed 0x0C)
out.close() 

当然,不仅 PDF 可以提取文本 - 所有支持的文档文件格式(例如 MOBI、EPUB、TXT)都可以提取其文本。

注意

深入探讨

如果您的文档包含基于图像的文本内容,则在页面上使用 OCR 进行后续文本提取:

tp = page.get_textpage_ocr()
text = page.get_text(textpage=tp) 

还有许多示例,说明如何从特定区域提取文本或如何从文档中提取表格。请参阅文本指南。

现在您还可以将文本以 Markdown 格式提取出来 提取 Markdown 格式的文本。

API 参考

  • Page.get_text()

从 PDF 中提取图像

要从 PDF 文件提取所有图像,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document

for page_index in range(len(doc)): # iterate over pdf pages
    page = doc[page_index] # get the page
    image_list = page.get_images()

    # print the number of images found on the page
    if image_list:
        print(f"Found {len(image_list)} images on page {page_index}")
    else:
        print("No images found on page", page_index)

    for image_index, img in enumerate(image_list, start=1): # enumerate the image list
        xref = img[0] # get the XREF of the image
        pix = pymupdf.Pixmap(doc, xref) # create a Pixmap

        if pix.n - pix.alpha > 3: # CMYK: convert to RGB first
            pix = pymupdf.Pixmap(pymupdf.csRGB, pix)

        pix.save("page_%s-image_%s.png" % (page_index, image_index)) # save the image as png
        pix = None 

注意

深入探讨

还有许多示例,说明如何从特定区域提取文本或如何从文档中提取表格。请参阅文本指南。

API 参考

  • Page.get_images()

  • Pixmap

提取矢量图形

要从文档页面提取所有矢量图形,请执行以下操作:

doc = pymupdf.open("some.file")
page = doc[0]
paths = page.get_drawings() 

这将返回一个包含页面上找到的所有矢量图形路径的字典。

注意

深入探讨

请参考:如何提取绘图。

API 参考

  • Page.get_drawings()

合并 PDF 文件

要合并 PDF 文件,请执行以下操作:

import pymupdf

doc_a = pymupdf.open("a.pdf") # open the 1st document
doc_b = pymupdf.open("b.pdf") # open the 2nd document

doc_a.insert_pdf(doc_b) # merge the docs
doc_a.save("a+b.pdf") # save the merged document with a new filename 

将 PDF 文件与其他类型文件合并

使用 Document.insert_file() 您可以调用方法与 PDF 合并 支持的文件。例如:

import pymupdf

doc_a = pymupdf.open("a.pdf") # open the 1st document
doc_b = pymupdf.open("b.svg") # open the 2nd document

doc_a.insert_file(doc_b) # merge the docs
doc_a.save("a+b.pdf") # save the merged document with a new filename 

注意

深入探讨

使用Document.insert_pdf()Document.insert_file()轻松合并 PDF 文件。在打开的 PDF 文档中,您可以从一个文档复制页面范围到另一个文档中。您可以选择复制页面应放置的位置,可以反转页面顺序,还可以更改页面旋转。这篇维基文章包含了详细说明。

GUI 脚本join.py使用此方法来连接文件列表,同时连接相应的目录段。它看起来像这样:

_images/img-pdfjoiner.jpg

API 参考

  • Document.insert_pdf()

  • Document.insert_file()

将 PDF 文件与其他类型的文件合并

使用Document.insert_file()您可以调用此方法与 PDF 合并支持的文件。例如:

import pymupdf

doc_a = pymupdf.open("a.pdf") # open the 1st document
doc_b = pymupdf.open("b.svg") # open the 2nd document

doc_a.insert_file(doc_b) # merge the docs
doc_a.save("a+b.pdf") # save the merged document with a new filename 

注意

进一步探索

使用Document.insert_pdf()Document.insert_file()轻松合并 PDF 文件。在打开的 PDF 文档中,您可以从一个文档复制页面范围到另一个文档中。您可以选择复制页面应放置的位置,可以反转页面顺序,还可以更改页面旋转。这篇维基文章包含了详细说明。

GUI 脚本join.py使用此方法来连接文件列表,同时连接相应的目录段。它看起来像这样:

_images/img-pdfjoiner.jpg

API 参考

  • Document.insert_pdf()

  • Document.insert_file()

使用坐标

当使用PyMuPDF时,有一个数学术语你应该对其感到舒适 - “coordinates(坐标)”。请快速查看 Coordinates(坐标)部分,以理解坐标系统,帮助您定位对象并理解文档空间。


添加水印到 PDF

要向 PDF 文件添加水印,请执行以下操作:

import pymupdf

doc = pymupdf.open("document.pdf") # open a document

for page_index in range(len(doc)): # iterate over pdf pages
    page = doc[page_index] # get the page

    # insert an image watermark from a file name to fit the page bounds
    page.insert_image(page.bound(),filename="watermark.png", overlay=False)

doc.save("watermarked-document.pdf") # save the document with a new filename 

注意

进一步探索

添加水印实质上就像在每个 PDF 页面的底部添加图像一样简单。确保图像具有所需的不透明度和长宽比以使其看起来符合您的需求。

在上面的示例中,从每个文件引用创建了一个新图像,但为了提高性能(节省内存和文件大小),应该只引用一次图像数据 - 请参阅代码示例和Page.insert_image()的实现说明。

API 参考

  • Page.bound()

  • Page.insert_image()


向 PDF 添加图像

要向 PDF 文件添加图像(例如徽标),请执行以下操作:

import pymupdf

doc = pymupdf.open("document.pdf") # open a document

for page_index in range(len(doc)): # iterate over pdf pages
    page = doc[page_index] # get the page

    # insert an image logo from a file name at the top left of the document
    page.insert_image(pymupdf.Rect(0,0,50,50),filename="my-logo.png")

doc.save("logo-document.pdf") # save the document with a new filename 

进一步探讨

与水印示例类似,如果可能的话,确保只引用图像一次以提高性能 - 请参阅代码示例和Page.insert_image()上的说明。

API 参考

  • 矩形

  • Page.insert_image()


旋转 PDF

要向页面添加旋转,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open document
page = doc[0] # get the 1st page of the document
page.set_rotation(90) # rotate the page
doc.save("rotated-page-1.pdf") 

API 参考

  • Page.set_rotation()

裁剪 PDF

要将页面裁剪到指定的矩形,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open document
page = doc[0] # get the 1st page of the document
page.set_cropbox(pymupdf.Rect(100, 100, 400, 400)) # set a cropbox for the page
doc.save("cropped-page-1.pdf") 

API 参考

  • Page.set_cropbox()

附加文件

要向页面附加另一个文件,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open main document
attachment = pymupdf.open("my-attachment.pdf") # open document you want to attach

page = doc[0] # get the 1st page of the document
point = pymupdf.Point(100, 100) # create the point where you want to add the attachment
attachment_data = attachment.tobytes() # get the document byte data as a buffer

# add the file annotation with the point, data and the file name
file_annotation = page.add_file_annot(point, attachment_data, "attachment.pdf")

doc.save("document-with-attachment.pdf") # save the document 

进一步探讨

使用Page.add_file_annot()添加文件时,请注意filename的第三个参数应包括实际的文件扩展名。如果没有这样做,附件可能无法被识别为可以打开的内容。例如,如果filename只是“attachment”,在查看生成的 PDF 并尝试打开附件时可能会出错。但是,使用“attachment.pdf”可以被 PDF 查看器识别并打开为有效的文件类型。

附件的默认图标默认是“图钉”,但是您可以通过设置icon参数进行更改。

API 参考

  • Document.tobytes()

  • Page.add_file_annot()


嵌入文件

要将文件嵌入文档中,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open main document
embedded_doc = pymupdf.open("my-embed.pdf") # open document you want to embed

embedded_data = embedded_doc.tobytes() # get the document byte data as a buffer

# embed with the file name and the data
doc.embfile_add("my-embedded_file.pdf", embedded_data)

doc.save("document-with-embed.pdf") # save the document 

进一步探讨

与附加文件类似,使用Document.embfile_add()添加文件时,请注意filename的第一个参数应包括实际的文件扩展名。

API 参考

  • Document.tobytes()

  • Document.embfile_add()


删除页面

要从文档中删除页面,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document
doc.delete_page(0) # delete the 1st page of the document
doc.save("test-deleted-page-one.pdf") # save the document 

要从文档中删除多个页面,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document
doc.delete_pages(from_page=9, to_page=14) # delete a page range from the document
doc.save("test-deleted-pages.pdf") # save the document 

如果删除书签或超链接引用的页面会发生什么?

  • 目录中的书签(目录条目)将变为不活跃状态,并且将不再导航到任何页面。

  • 页面上的超链接将被删除。该页面上的可见内容不会以任何方式改变。

注意

深入了解

页面索引从零开始,因此要删除文档的第 10 页,您需要执行以下操作:doc.delete_page(9)

类似地,doc.delete_pages(from_page=9, to_page=14) 将删除第 10 至第 15 页(包括)。

API 参考

  • Document.delete_page()

  • Document.delete_pages()


如果删除书签或超链接引用的页面会发生什么?

  • 目录中的书签(目录条目)将变为不活跃状态,并且将不再导航到任何页面。

  • 页面上的超链接将被删除。该页面上的可见内容不会以任何方式改变。

注意

深入了解

页面索引从零开始,因此要删除文档的第 10 页,您需要执行以下操作:doc.delete_page(9)

类似地,doc.delete_pages(from_page=9, to_page=14) 将删除第 10 至第 15 页(包括)。

API 参考

  • Document.delete_page()

  • Document.delete_pages()


重新排列页面

要更改页面顺序,即重新排列页面,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document
doc.move_page(1,0) # move the 2nd page of the document to the start of the document
doc.save("test-page-moved.pdf") # save the document 

注意

API 参考

  • Document.move_page()

复制页面

要复制页面,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document
doc.copy_page(0) # copy the 1st page and puts it at the end of the document
doc.save("test-page-copied.pdf") # save the document 

注意

API 参考

  • Document.copy_page()

选择页面

要选择页面,请执行以下操作:

import pymupdf

doc = pymupdf.open("test.pdf") # open a document
doc.select([0, 1]) # select the 1st & 2nd page of the document
doc.save("just-page-one-and-two.pdf") # save the document 

注意

深入了解

使用 PyMuPDF,您可以选择复制、移动、删除或重新排列 PDF 页面的所有选项。存在直观的方法,允许您按页面进行此操作,例如 Document.copy_page() 方法。

或者您可以准备一个完整的新页面布局,以 Python 序列的形式包含您想要的页面编号,按您想要的顺序,并且每个页面可以包含多次。以下内容可能说明可以通过 Document.select() 完成的操作。

doc.select([1, 1, 1, 5, 4, 9, 9, 9, 0, 2, 2, 2]) 

现在让我们为双面打印准备一个 PDF(在不直接支持此功能的打印机上):

页面数由 len(doc)(等同于 doc.page_count)给出。以下列表分别表示偶数和奇数页码:

p_even = [p in range(doc.page_count) if p % 2 == 0]
p_odd  = [p in range(doc.page_count) if p % 2 == 1] 

此代码段创建相应的子文档,然后可以用于打印文档:

doc.select(p_even) # only the even pages left over
doc.save("even.pdf") # save the "even" PDF
doc.close() # recycle the file
doc = pymupdf.open(doc.name) # re-open
doc.select(p_odd) # and do the same with the odd pages
doc.save("odd.pdf") 

欲了解更多信息,请查看此 Wiki 文章

以下示例将反转所有页面的顺序(极快:在 Adobe PDF 参考手册的 756 页中仅需几秒钟):

lastPage = doc.page_count - 1
for i in range(lastPage):
    doc.move_page(lastPage, i) # move current last page to the front 

此代码段将 PDF 与其自身复制,以便其包含页面 0, 1, …, n, 0, 1, …, n (非常快速且几乎不增加文件大小!)

page_count = len(doc)
for i in range(page_count):
    doc.copy_page(i) # copy this page to after last page 

API 参考

  • Document.select()

添加空白页

要添加空白页面,请执行以下操作:

import pymupdf

doc = pymupdf.open(...) # some new or existing PDF document
page = doc.new_page(-1, # insertion point: end of document
                    width = 595, # page dimension: A4 portrait
                    height = 842)
doc.save("doc-with-new-blank-page.pdf") # save the document 

注意

进一步探索

使用此方法创建带有另一预定义纸张格式的页面:

w, h = pymupdf.paper_size("letter-l")  # 'Letter' landscape
page = doc.new_page(width = w, height = h) 

方便函数 paper_size() 知道超过 40 种行业标准纸张格式可供选择。要查看它们,请检查字典 paperSizes。将所需的字典键传递给 paper_size() 以检索纸张尺寸。支持大小写。如果将格式名称追加“-L”,则返回横向版本。

这里是一个三行代码,创建一个带有一个空白页面的 PDF,文件大小为 460 字节:

doc = pymupdf.open()
doc.new_page()
doc.save("A4.pdf") 

API 参考

  • Document.new_page()

  • paperSizes


插入具有文本内容的页面

使用 Document.insert_page() 方法还可以插入新页面,并接受相同的 widthheight 参数。但它还允许您在新页面中插入任意文本,并返回插入的行数。

import pymupdf

doc = pymupdf.open(...)  # some new or existing PDF document
n = doc.insert_page(-1, # default insertion point
                    text = "The quick brown fox jumped over the lazy dog",
                    fontsize = 11,
                    width = 595,
                    height = 842,
                    fontname = "Helvetica", # default font
                    fontfile = None, # any font file name
                    color = (0, 0, 0)) # text color (RGB) 

注意

进一步探索

文本参数可以是字符串或字符串序列(假设使用 UTF-8 编码)。插入将从点(50, 72)开始,这是页面顶部下方一英寸处并距离左侧 50 点。返回插入的文本行数。

API 参考

  • Document.insert_page()

分割单页

这处理将 PDF 页面分割为任意片段。例如,您可能有一个带有 Letter 格式页面的 PDF,您希望将其以 4 倍放大比例打印:每个页面被分割成 4 个部分,每个部分分别成为 Letter 格式的单独 PDF 页面。

import pymupdf

src = pymupdf.open("test.pdf")
doc = pymupdf.open()  # empty output PDF

for spage in src:  # for each page in input
    r = spage.rect  # input page rectangle
    d = pymupdf.Rect(spage.cropbox_position,  # CropBox displacement if not
                  spage.cropbox_position)  # starting at (0, 0)
    #--------------------------------------------------------------------------
    # example: cut input page into 2 x 2 parts
    #--------------------------------------------------------------------------
    r1 = r / 2  # top left rect
    r2 = r1 + (r1.width, 0, r1.width, 0)  # top right rect
    r3 = r1 + (0, r1.height, 0, r1.height)  # bottom left rect
    r4 = pymupdf.Rect(r1.br, r.br)  # bottom right rect
    rect_list = [r1, r2, r3, r4]  # put them in a list

    for rx in rect_list:  # run thru rect list
        rx += d  # add the CropBox displacement
        page = doc.new_page(-1,  # new output page with rx dimensions
                           width = rx.width,
                           height = rx.height)
        page.show_pdf_page(
                page.rect,  # fill all new page with the image
                src,  # input document
                spage.number,  # input page number
                clip = rx,  # which part to use of input page
            )

# that's it, save output file
doc.save("poster-" + src.name,
         garbage=3,  # eliminate duplicate objects
         deflate=True,  # compress stuff where possible
) 

示例:

_images/img-posterize.png

注意

API 参考

  • Page.cropbox_position()

  • Page.show_pdf_page()


合并单页

这涉及将 PDF 页面连接起来形成一个新的 PDF,其中每个页面组合两个或四个原始页面(也称为“2-up”,“4-up”等)。这可以用于创建小册子或类似缩略图的概览。

import pymupdf

src = pymupdf.open("test.pdf")
doc = pymupdf.open()  # empty output PDF

width, height = pymupdf.paper_size("a4")  # A4 portrait output page format
r = pymupdf.Rect(0, 0, width, height)

# define the 4 rectangles per page
r1 = r / 2  # top left rect
r2 = r1 + (r1.width, 0, r1.width, 0)  # top right
r3 = r1 + (0, r1.height, 0, r1.height)  # bottom left
r4 = pymupdf.Rect(r1.br, r.br)  # bottom right

# put them in a list
r_tab = [r1, r2, r3, r4]

# now copy input pages to output
for spage in src:
    if spage.number % 4 == 0:  # create new output page
        page = doc.new_page(-1,
                      width = width,
                      height = height)
    # insert input page into the correct rectangle
    page.show_pdf_page(r_tab[spage.number % 4],  # select output rect
                     src,  # input document
                     spage.number)  # input page number

# by all means, save new file using garbage collection and compression
doc.save("4up.pdf", garbage=3, deflate=True) 

示例:

_images/img-4up.png

注意

API 参考

  • Page.cropbox_position()

  • Page.show_pdf_page()


PDF 加密与解密

从版本 1.16.0 开始,完全支持 PDF 解密和加密(使用密码)。您可以执行以下操作:

  • 检查文档是否受密码保护/(仍然)加密(Document.needs_passDocument.is_encrypted)。

  • 获取对文档的访问授权(Document.authenticate())。

  • 使用Document.save()Document.write()设置 PDF 文件的加密详细信息,以及

    • 解密或加密内容
    • 设置密码
    • 设置加密方法
    • 设置权限详细信息

注意

一个 PDF 文档可能有两个不同的密码:

  • 所有者密码提供完全的访问权限,包括更改密码、加密方法或权限详细信息。

  • 用户密码根据已建立的权限详细信息提供对文档内容的访问。如果存在,使用查看器打开 PDF 将需要提供它。

方法Document.authenticate()将根据使用的密码自动建立访问权限。

以下代码片段创建了一个新的 PDF 并使用单独的用户密码和所有者密码加密它。授予打印、复制和注释的权限,但不允许对使用用户密码进行身份验证的人进行更改。

import pymupdf

text = "some secret information" # keep this data secret
perm = int(
    pymupdf.PDF_PERM_ACCESSIBILITY # always use this
    | pymupdf.PDF_PERM_PRINT # permit printing
    | pymupdf.PDF_PERM_COPY # permit copying
    | pymupdf.PDF_PERM_ANNOTATE # permit annotations
)
owner_pass = "owner" # owner password
user_pass = "user" # user password
encrypt_meth = pymupdf.PDF_ENCRYPT_AES_256 # strongest algorithm
doc = pymupdf.open() # empty pdf
page = doc.new_page() # empty page
page.insert_text((50, 72), text) # insert the data
doc.save(
    "secret.pdf",
    encryption=encrypt_meth, # set the encryption method
    owner_pw=owner_pass, # set the owner password
    user_pw=user_pass, # set the user password
    permissions=perm, # set permissions
) 

注意

进一步探索

使用某些查看器(Nitro Reader 5)打开此文档会反映这些设置:

_images/img-encrypting.jpg

解密将像以前一样在保存时自动进行,当未提供加密参数时。

保持 PDF 的加密方法,请使用encryption=pymupdf.PDF_ENCRYPT_KEEP进行保存。如果doc.can_save_incrementally() == True,也可以进行增量保存。

更改加密方法,请指定上述所有选项的完整范围(encryptionowner_pwuser_pwpermissions)。在这种情况下不能进行增量保存。

API 参考

  • Document.save()

从页面提取表格

可以从任何文档中找到并提取表格 Page。

import pymupdf
from pprint import pprint

doc = pymupdf.open("test.pdf") # open document
page = doc[0] # get the 1st page of the document
tabs = page.find_tables() # locate and extract any tables on page
print(f"{len(tabs.tables)} found on {page}") # display number of found tables

if tabs.tables:  # at least one table found?
   pprint(tabs[0].extract())  # print content of first table 

注意

API 参考

  • Page.find_tables()

重要

你也可以选择使用 pdf2docx 提取表格方法


获取页面链接

可以从 Page 中提取链接以返回 Link 对象。

import pymupdf

for page in doc: # iterate the document pages
    link = page.first_link  # a `Link` object or `None`

    while link: # iterate over the links on page
        # do something with the link, then:
        link = link.next # get next link, last one has `None` in its `next` 

注意

API 参考

  • Page.first_link()

从文档获取所有注释

页面上的注释 (Annot) 可以使用 page.annots() 方法检索。

import pymupdf

for page in doc:
    for annot in page.annots():
        print(f'Annotation on page: {page.number} with type: {annot.type} and rect: {annot.rect}') 

注意

API 参考

  • Page.annots()

PDF中编辑内容

删除是一种特殊类型的注释,可以标记在文档页面上,以示应安全删除页面上的某个区域。标记了矩形区域后,此区域将被标记为删除,一旦应用删除,则内容将被安全地删除。

例如,如果我们想从文档中删除所有“Jane Doe”姓名的实例,可以按以下步骤操作:

import pymupdf

# Open the PDF document
doc = pymupdf.open('test.pdf')

# Iterate over each page of the document
for page in doc:
    # Find all instances of "Jane Doe" on the current page
    instances = page.search_for("Jane Doe")

    # Redact each instance of "Jane Doe" on the current page
    for inst in instances:
        page.add_redact_annot(inst)

    # Apply the redactions to the current page
    page.apply_redactions()

# Save the modified document
doc.save('redacted_document.pdf')

# Close the document
doc.close() 

另一个例子是编辑页面的一个区域,但不编辑定义区域内的任何线条艺术(即矢量图形),方法是设置参数标志如下:

import pymupdf

# Open the PDF document
doc = pymupdf.open('test.pdf')

# Get the first page
page = doc[0]

# Add an area to redact
rect = [0,0,200,200]

# Add a redacction annotation which will have a red fill color
page.add_redact_annot(rect, fill=(1,0,0))

# Apply the redactions to the current page, but ignore vector graphics
page.apply_redactions(graphics=0)

# Save the modified document
doc.save('redactied_document.pdf')

# Close the document
doc.close() 

警告

一旦保存了文档的已编辑版本,则 PDF 中的已编辑内容是无法检索的。因此,文档中的删除区域会彻底删除文本和图形内容。

注意

进一步操作

有几种选项可用于创建和应用页面的删除操作,有关这些选项的详细 API 信息,请参阅 API 参考。

API 参考

  • Page.add_redact_annot()

  • Page.apply_redactions()


转换 PDF 文档

我们推荐使用 pdf2docx 库,该库使用 PyMuPDFpython-docx 库提供从 PDFDOCX 格式的简单文档转换。

对本页有任何反馈吗?


此软件按原样提供,不附带任何明示或暗示的保证。此软件根据许可证分发,未经授权不得复制、修改或分发。请参阅 artifex.com 上的许可信息或联系位于美国加利福尼亚州旧金山 Mesa 街 39 号 108A 室的 Artifex Software Inc. 获取更多信息。

此文档涵盖所有版本直至 1.24.4。

Discord logo

posted @ 2024-06-17 15:45  绝不原创的飞龙  阅读(99)  评论(0编辑  收藏  举报