我正在使用 pyPdf 将多个 PDF 文件合并为一个。这很好用,但我还需要向生成的 PDF 文件添加目录/大纲/书签。
pyPdf 似乎只支持读取大纲。 Reportlab 允许我创建它们,但开源版本不支持加载 PDF 文件,因此无法向现有文件添加轮廓。
有什么方法可以使用 Python 或任何允许这样做的库向现有 PDF 添加轮廓?
https://github.com/yutayamamoto/pdfoutline 我制作了一个 python 库,只是为了向现有 PDF 文件添加大纲。
我们在 WeasyPrint 中遇到了类似的问题:cairo 生成 PDF 文件,但不支持书签/大纲或超链接。最后我们硬着头皮阅读了PDF规范,然后自己做了。
WeasyPrint 的 pdf.py 有一个简单的 PDF 解析器和编写器,可以将 PDF“对象”添加/覆盖现有文档。它使用 PDF“更新”机制,仅附加在文件末尾。
该模块仅供内部使用,但我愿意重构它以使其更容易在其他项目中使用。
但是解析器采用了一些快捷方式,无法解析所有有效的 PDF 文件。如果 PyPDF 的输出不如 cairo 的那么好,则可能需要进行调整。来自模块的文档字符串:
我们不是尝试解析任何有效的 PDF,而是做出一些假设 为了简化代码,适用于开罗:
- 所有换行符都是 ' ', 不是 ' ' 或者 ' '
- 除了数字 0(始终是免费的)之外,没有“免费”对象。
- 大多数空白分隔符由单个 0x20 空格组成。
- 间接字典对象在行首不包含“>>”,除非标记对象的结尾,后跟“endobj”。 (在 换句话说,子词典的“>>”标记是缩进的。)
- 页面树是扁平的:根页面节点的所有子节点都是页面对象,而不是页面树节点。
pikepdf 似乎正是您所需要的。我自己没有使用过它,但我在研究类似用例时遇到了它!
自动为合并文档中的每个文件添加条目:
In [1]: from pikepdf import Pdf, OutlineItem # (In [2-4] showcase a related use case) In [5]: from glob import glob In [6]: pdf = Pdf.new() In [7]: page_count = 0 In [8]: with pdf.open_outline() as outline: ...: for file in glob('*.pdf'): ...: src = Pdf.open(file) ...: oi = OutlineItem(file, page_count) ...: outline.root.append(oi) ...: page_count += len(src.pages) ...: pdf.pages.extend(src.pages) ...: In [9]: pdf.save('merged.pdf')