pypdf 如何写入 PDF 文件¶
pypdf 使用 PdfWriter
来写入 PDF 文件。pypdf 提供 PdfObject
及其多个子类,这些类实现了 write_to_stream
方法。PdfWriter.write
方法通过调用引用对象的 write_to_stream
方法实现文件写入。
PdfWriter.write_stream
方法包括以下核心步骤:
_sweep_indirect_references
:此步骤确保正确处理对象的循环引用。它将所有循环引用对象的引用编号添加到外部引用映射中,以便自引用页面树可以正确引用新对象位置,而不是复制页面对象的新副本。使用
_write_pdf_structure
写入文件头和主体:此步骤将 PDF 头部和对象写入输出流。这包括 PDF 版本信息(例如%PDF-1.7
)以及组成 PDF 内容的对象,如页面、注释和表单字段。同时记录这些对象的位置(字节偏移量),以便后续生成交叉引用表(xref table)。使用
_write_xref_table
写入交叉引用表:根据存储的对象位置,此步骤生成并写入交叉引用表。交叉引用表包含 PDF 文件中每个对象的字节偏移量,从而实现对对象的快速随机访问。使用
_write_trailer
写入文件尾部:此步骤将文件尾部信息写入输出流。文件尾部包含重要信息,例如 PDF 中对象的数量、根对象(Catalog)的位置以及包含元数据的 Info 对象。尾部还指定交叉引用表的位置。
其他库的实现方式¶
分析其他软件的设计和实现方式,有助于我们改进自身的设计决策。
fpdf2¶
fpdf2 提供了一个 PDFObject
类,其中的 serialize
方法大致对应于 pypdf.PdfObject.write_to_stream
。其他相似之处包括:
pdfrw¶
pdfrw 的设计与 pypdf 不同,它更倾向于使用标准的 Python 对象(如 bool
、float
、string
),尽量避免将其包装成自定义对象。但 pdfrw 仍提供了以下类:
pdfrw 的核心类包括: