添加PDF文档链接

Hen*_*ter 9 python pdf pdf-generation pypdf

我需要以编程方式分析和组合几个(数百个)PDF文档,并以专门的方式将页面链接在一起.每个PDF都包含链接所属的每个位置的文本,指示它应链接到的位置.我正在使用pdfminer提取链接所在的位置和文本; 现在我只需要实际创建这些链接.

我做了一些研究并得出结论认为PyPDF2可以做到这一点.无论如何,有一种看似简单的addLink方法可以宣称完成工作.我无法让它发挥作用.

from PyPDF2 import PdfFileWriter
from PyPDF2.pdf import RectangleObject

out = PdfFileWriter()

out.insertBlankPage(800, 1000)
out.insertBlankPage(800, 1000)

# rect = [400, 400, 600, 600] # This doesn't seem to work either
rect = RectangleObject([400, 400, 600, 600])
out.addLink(0, 1, rect) # link from first to second page

with open(r'C:\temp\test.pdf', 'wb') as outf:
    out.write(outf)
Run Code Online (Sandbox Code Playgroud)

上面的代码生成了一个漂亮的两页PDF,其中没有任何内容,至少据我所知.有没有人知道如何实现这一目标?或者至少表明我哪里出错了?

只要库是免费许可的,解决方案就不必使用PyPDF2.严格地说,Python甚至不是一个要求,但是将它放入我当前的结构并且不用另一种语言来攻击它会很好.

Hen*_*ter 5

这似乎是实现中的错误addLink,或者可能该方法仅用于较旧或不同的链接语法.无论如何,从问题中的示例代码检查输出PDF的结构揭示了这个小宝石:

6 0 obj
<<
/Dest [ 4 0 R /FitV 826 ]
/Type /Annot
/Rect RectangleObject([400, 400, 600, 600])
/Border [ 0 0 0 ]
/P IndirectObject(5, 0)
/Subtype /Link
>>
Run Code Online (Sandbox Code Playgroud)

这有几个问题.最明显的是RectangleObjectIndirectObject是Python库,构建体不是有效的PDF结构./Dest似乎还有一个我没有要求的神秘魔法参数.此外,/P它将是冗余的(对包含此链接的页面的引用),即使它是以不将Python对象强制转换为PDF结构的方式实现的.简而言之,难怪这个链接被打破了.

乱搞与源位,以消除崩溃的错误,事实证明,需要两个变化*获得的链接进入工作顺序:改变的内部表示/RectNameObjectArrayObject,并改变/P参考页面指向数字,而不是实际的对象.这些更改让示例代码生成有效输出:

6 0 obj
<<
/Dest [ 4 0 R /FitV ]
/Type /Annot
/Rect [ 400 400 600 600 ]
/Border [ 0 0 0 ]
/P 0
/Subtype /Link
>>
Run Code Online (Sandbox Code Playgroud)

Etvoilà,链接在输出中完全按预期工作!我也826/Rect值中删除了魔法,因为根据缩放级别它可能不是合法参数,并且它实际上不应该是硬编码的.


*在得出结论这个修复程序按预期工作后,我确实认为离开/Rect作为一个NameObject并传递一个看起来像输出的字符串应该(例如'[ 400 400 600 600 ]')也可以工作.这可能是为了获得最大的灵活性,但肯定是出乎意料的.


更新:我整理并提交了一个更完整的修补程序(链接到后代的补丁),因此上述问题都应该修复,从版本1.22开始.