An einem konkreten Beispiel soll gezeigt werden, wie man mit Hilfe von XFDF-Dateien, dem Kommandozeilenwerkzeug pdftk sowie Bash-/Python-Skripten PDF-Formulare automatisiert ausfüllen kann. Die Skripte und sonstigen Dateien sind unter SKRIPTE zu finden.
Ein möglicher, aber weniger empfehlenswerter Ansatz besteht in der Nutzung von Text-Annotationen, z.B. mit
convert -annotate ...
Siehe annotate.sh für das Formular formular.pdf.
Die wesentlichen Nachteile gegenüber der empfohlenen XFDF-Variante sind in den Kommentaren des Skripts genannt.
FDF (Forms Data Format) und XFDF (XML Forms Data Format) ermöglichen die textuelle Repräsentation von Formulardaten durch Angabe der Feldnamen und ihrer Werte. Mit Adobe Professional kann man Formulardaten in FDF/XFDF-Dateien exportieren und diese auch wieder in ein PDF importieren. pdftk gestattet den FDF-Export sowie den Import von FDF und XFDF, wobei XFDF für eine Behandlung durch Skripte komfortabler erscheint, weswegen nachfolgend nur darauf genauer eingegangen wird. Durch den (X)FDF-Import kann man pdftk sehr gut zum skriptgesteuerten Ausfüllen von PDF-Formularen nutzen.
Hier einige Links mit genaueren Informationen zu den Formaten FDF/XFDF:
Wikipedia nennt einige weitere Werkzeuge, die mit (X)FDF umgehen können.
Adobe bietet umfangreiche offizielle Spezifikationen zum Thema an, von denen man für unsere Praxisbeispiele maximal kleinere Auszüge aus der XFDF-Spezifikation benötigt:
Konkret mit der für die Experimente verwendeten deutschen Version 9 von Adobe Professional gestaltete sich der (X)FDF-Export wie folgt:
Hinweis: Über den Menüpunkt "Felder hinzufügen oder bearbeiten..." kann man die Formular-Struktur bearbeiten. Dort sieht man auch die internen Feldnamen, die dann wiederum im (X)FDF auftauchen und für das maschinelle Ausfüllen von Formularen relevant sind.
Bevor wir zum praktischen Ablauf des Ausfüllens von Formularen kommen, hier noch einige Anmerkungen zu (X)FDF-Dateien und pdftk, die bei den Experimenten gewonnen wurden:
FDF kann auch normaler Text sein, wie ihn Adobe exportiert, also ohne die NUL-Bytes, die pdftk beim FDF-Export mit generate_fdf generiert.
Es genügt, im (X)FDF nur die Felder anzugeben, die man wirklich füllen will. Auch das ids-Tag von XFDF kann man daher weglassen, z.B.
<ids original="CF8F383DBAD62DD2857BDAD22F2274C7" modified="D1DC2BEEE083E34F858DC4DBA7D3ED28"/>Diese IDs lassen sich mit
pdftk file.pdf dump_data_utf8ermitteln:
PdfID0: 81eb259ff9e62fc71caf96644344e4 PdfID1: 81eb259ff9e62fc71caf96644344e4
Taucht ein Feldname an verschiedenen Stellen im PDF auf, so werden all diese Stellen via XFDF mit demselben Wert ausgefüllt.
Feldeigenschaften (sichtbar/unsichtbar) können verhindern, dass ausgefüllte Felder angezeigt werden. Das ist aber in manchen Formularen so gewollt.
Beim Export wurde der Dezimalpunkt als Trenner verwendet, obwohl im Text das Komma stand. Man muss die Punkte dann ggf. im XFDF durch Kommas ersetzen, um sie im ausgefüllten PDF wieder zu bekommen.
Man kann die XFDFs auch "schön" formatieren, also eingerückt, z.B. so:
xmllint --format formular_Daten.xfdfAdobe Pro exportiert sie etwas seltsam, da vor der schließenden spitzen Klammer ein Newline eingefügt wird, z.B.
/><fields ><field name="Kontrollkästchen1" ><value
Nachfolgend soll an einem konkreten Beispiel ein möglicher Ablauf beim automatisierten Ausfüllen von PDF-Formularen unter Nutzung der Dateien aus dem Ordner SKRIPTE gezeigt werden:
Als Rahmenskript fungiert ausfuellen.sh. Im ersten Schritt formatiert es die von Adobe exportierte XFDF-Datei etwas "schöner" mit xmllint und extrahiert daraus die Feldnamen. Diese werden zusammen mit einem Platzhalter für den Feldinhalt in die Datei feldliste.txt eingetragen. Jede Feldbeschreibung steht auf einer eigenen Zeile, als Trenner zwischen Feldname und Platzhalter fungiert der Pipe-Strich |.
Aus dieser Feldliste wird nachfolgend ein XFDF-Template generiert, das später vom Python-Skript fill_in_xfdf.py ausgefüllt wird, so dass es als Grundlage des Ausfüllens von formular.pdf mittels pdftk dienen kann.
Man könnte das XFDF-Template natürlich auch manuell aus dem Adobe-Export formular_Daten.xfdf erstellen und so die Generierung über die feldliste.txt einsparen. Die Generierung erleichtert aber ggf. die Arbeit etwas, da sich die Feldliste wegen ihrer simplen Struktur leicht editieren lässt.
Die Platzhalter %(var)s der Feldliste sind manuell (z.B. mit dem Editor Vi) so anzupassen, dass in den runden Klammern die jeweiligen Schlüssel des Python-Dictionarys von fill_in_xfdf.py stehen, über die dann die gewünschten Werte einzutragen sind, also z.B. %(firma)s.
Die Datei feldliste_komplett.txt enthält eine bereits komplette Feldliste und wird von ausfuellen.sh auch generell genutzt, sofern sie existiert.
Ausgehend von der komplett ausgefüllten Feldliste feldliste.txt wird mit Hilfe des Skripts gen_xfdf_template.py das oben erwähnte XFDF-Template formular.xfdf erstellt und gesichert, so dass es für mehrere Ausfüll-Operationen zur Verfügung steht, auch wenn im vorherigen Lauf das Template bereits ausgefüllt wurde und so statt der Platzhalter dort nun echte Werte stehen.
Die beiden PDF-IDs ermittelt gen_xfdf_template.py durch den Aufruf des Kommandos
pdftk formular.pdf dump_data_utf8
Sie fließen in das XFDF-Template ein.
In einer Schleife werden nur der Reihe nach die ausgefüllten PDF-Formulare erstellt:
formular_filled0.pdf formular_filled1.pdf ...
Dazu füllt das Skript fill_in_xfdf.py die Platzhalter der jeweils neu aus der o.g. Sicherung bereitgestellten Template-Datei formular.xfdf mit echten Werten aus. Diese werden anschließend von pdftk für das Ausfüllen des Formulars verwendet:
pdftk formular.pdf fill_form formular.xfdf output formular_filled0.pdf
fill_in_xfdf.py könnte die jeweiligen Feldinhalte des Formulars berechnen bzw. aus einer externen Datenbasis beziehen. Im konkreten Fall sind zwei Datensätze im Skript-Code enthalten, die beim Aufruf über eine Zahl 0 der 1 ausgewählt werden.
Abschließende Anmerkung: Das Skript get_fdf.sh zeigt die Nutzung von pdftk für den FDF-Export sowie zur Ausgabe von für den Menschen leicht lesbaren Text-Informationen über die Formularfelder. Mit purge kann man die von ausfuellen.sh generierten Dateien wieder beseitigen.