2014-05-23 28 views
9

Ich muss mehrere (hunderte) PDF-Dokumente programmatisch analysieren und kombinieren und die Seiten auf spezielle Weise miteinander verknüpfen. Jede PDF enthält Text an jedem Ort, zu dem ein Link gehört, und gibt an, wozu er verlinken soll. Ich verwende pdfminer, um den Ort und den Text zu extrahieren, wo die Links sein sollten; Jetzt muss ich nur diese Links erstellen.Fügen Sie einen Dokumentverweis zu PDF hinzu

Ich habe einige Nachforschungen gemacht und festgestellt, dass PyPDF2 dies angeblich tun kann. Auf jeden Fall gibt es eine scheinbar unkomplizierte Methode, die behauptet, den Job zu erledigen. Ich kann es einfach nicht zur Arbeit bringen.

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) 

Der obige Code erzeugt eine schöne Zwei-Seiten-PDF mit nichts drin, zumindest soweit ich das beurteilen kann. Weiß jemand da draußen, wie dies erreicht werden könnte? Oder zumindest ein Hinweis darauf, wo ich falsch liege?

Eine Lösung muss PyPDF2 nicht verwenden, solange die Bibliothek frei lizenziert ist. Streng genommen ist Python nicht einmal eine Voraussetzung, aber es wäre schön, dies in meine aktuelle Struktur zu integrieren, ohne eine andere Sprache zu hacken.

Antwort

5

Dies scheint ein Fehler in der Implementierung von addLink, oder möglicherweise diese Methode ist einfach für eine ältere oder andere Link-Syntax gemeint. Auf jeden Fall in der Frage der Struktur des PDF-Ausgabe aus dem Beispielcode Inspektion zeigt dieses kleine Juwel:

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 
>> 

Es gibt mehrere Probleme mit diesem. Am offensichtlichsten ist, dass RectangleObject und IndirectObject Konstrukte der Python-Bibliothek sind, nicht gültige PDF-Strukturen. /Dest scheint auch einen geheimnisvollen magischen Parameter darauf zu haben, den ich nicht gefragt habe. Außerdem wäre /P redundant (ein Verweis auf die Seite, die diesen Link enthält), selbst wenn es so implementiert wäre, dass es Python-Objekte nicht in die PDF-Struktur fallen ließ. Kurz gesagt, es ist kein Wunder, dass diese Verbindung unterbrochen ist.

Herumspielen mit der Quelle ein wenig die Krachen Fehler zu beseitigen, stellt sich heraus, dass zwei Änderungen erforderlich sind * den Link in Ordnung zu bekommen: die interne Darstellung des /Rect von einem NameObject zu einem ArrayObject Ändern und Ändern Die /P Referenz verweist auf die Seitenzahl und nicht auf das tatsächliche Objekt. Diese Veränderungen lassen den Beispielcode erzeugt gültige Ausgabe:

6 0 obj 
<< 
/Dest [ 4 0 R /FitV ] 
/Type /Annot 
/Rect [ 400 400 600 600 ] 
/Border [ 0 0 0 ] 
/P 0 
/Subtype /Link 
>> 

Et voilà, funktioniert der Link genau wie in dem Ausgang zu erwarten! Ich habe auch die magische 826 aus dem /Rect Wert entfernt, da es möglicherweise kein gesetzlicher Parameter abhängig von der Zoomstufe ist, und es sollte sowieso nicht fest codiert werden.


* Nach dem Schluss, dass dieses Update funktioniert wie beabsichtigt, habe ich herausgefunden habe, dass /Rect als NameObject verlassen und eine Zeichenfolge vorbei, die (zum Beispiel '[ 400 400 600 600 ]') sollte auch funktionieren wird wie die Ausgabe aussieht. Dies soll vermutlich maximale Flexibilität ermöglichen, ist aber sicher unerwartet.


aktualisieren: Ich habe zusammen und legte eine vollständigere fix (link to the patch für die Nachwelt), so dass die oben genannten Probleme sollten alle festgelegt werden, wie der Version 1.22.

Verwandte Themen