Freitag, 25. Mai 2012


Artikel

März 2005 | Artikel

Registrierung adé

(Link zum Artikel: http://www.entwickler.de/php//000677)

FDF ohne das Adobe SDK erstellen

Text: von Christian Wenz
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share
FDF ist ein bis dato noch sehr unterschätztes und eher selten eingesetztes Datenformat. Um es zu stellen, benötigen Sie auf vielen Systemen ein SDK von Adobe, das eine Registrierung unter [1] erfordert. Doch es geht auch ohne!

Seit der Verbreitung des Internets besteht großes Interesse, PDF-Dokumente online zu erstellen. Unter anderem hat [2] gezeigt, wie das geht. Doch auch dort hat es sich gezeigt, dass gerade das exakte Layout sehr mühsam ist. Einfacher ist es da schon, für das Design ein Programm zu nehmen, dass das auch kann: Entweder eine Satz-Software oder eine Textverarbeitung. Doch dann ist es nicht mehr möglich, eigene Informationen und Daten zu integrieren.

Mit ein wenig Aufwand lässt sich das natürlich per Makro ein wenig automatisieren, wie das beispielsweise OpenOffice.org oder auch Microsoft Office vormachen. Doch das Gelbe vom Ei ist das nicht. Es gibt mittlerweile zahlreiche Softwareprodukte, die hier eine Lösung versprechen, die Arbeitsersparnis aber in harten Euro gerne bezahlt hätten.

Die PDFlib bietet in manchen Versionen noch PDI-Funktionalitäten an. Damit ist es möglich, bestehende PDF-Dokumente zu öffnen und Elemente hinzuzufügen. Doch diese Funktionalität ist kostenpflichtig und deswegen im Rahmen dieser Serie auch nicht qualifiziert.Zum Datenaustausch von FDF hat Adobe das Forms Data Format (FDF) geschaffen. Dabei handelt es sich um ein Dateiformat, mit dem Formulardaten innerhalb von FDF-Dokumenten verarbeitet werden können. Das geht in zwei Richtungen: Zum einen können Daten, die aus einem Formular kommen, im FDF-Format abgespeichert werden. Zum anderen ist es auch möglich, FDF-Daten in ein Dokument zu laden.Leider hat Adobe ein paar Hürden zwischen die Entwickler und die Verwendung von FDF gesetzt. Denn nur Mitglieder im ASN Developer Program [3] erhalten vollen Zugriff auf die Dokumentation und die dazugehörigen SDKs, mit denen FDF-Daten erstellt werden können. Es gibt mehrere Varianten der Mitgliedschaft im Programm. Die günstige Variante belastet das Budget mit jährlich rund 200 US-Dollar, die Premium-Ausgabe kostet etwa 1.000 US-Dollar. Wer nur am SDK interessiert ist: Für Kunden aus den USA und Kanada schlägt das mit etwa 100 Euro zu Buche, doch ausländische Kunden können so und so nur per Telefon bestellen (möglicherweise zu einem anderen Preis).Mittlerweile gibt es jedoch auch ein FDF-Toolkit [4], ein API, um serverseitig auf FDF-Daten zuzugreifen. Eben dieses Toolkit wird auch von den FDF-Funktionen von PHP [5] als Voraussetzung angegeben (siehe Kasten Die FDF-Funktionen von PHP).

Die FDF-Funktionen von PHP
Unter [5] gibt es im Online-Handbuch von PHP den Abschnitt zum Thema FDF-Funktionen. Zur Installation der Erweiterung verwenden Sie den Schalter --with-fdftk und geben dort das Verzeichnis an, in das das SDK von Adobe installiert wurde. Windows-Nutzer haben es einfacher und brauchen nicht einmal das SDK, denn die Bibliotheken sind bei PHP mit dabei:

Im Erweiterungsverzeichnis (ext bei PHP 5, extensions bei PHP 4) liegt die Datei php_fdf.dll, die Sie per extension=php_fdf.dll in die Konfigurationsdatei php.ini einbinden können (oder zur Not setzen Sie auf dl()).Im Installationsverzeichnis von PHP (bei PHP 5; unter PHP 4 im Unterverzeichnis dlls) liegt die Datei fdftk.dll (die das Client-API zur Verfügung stellt), die ins Systemverzeichnis von Windows kopiert werden muss.

Dann haben Sie vollen Zugriff auf die FDF-Funktionen und können FDF-Dateien erstellen. Das geht in vier Schritten: Datei erzeugen, Feldwerte besetzen, Namen des Basis-PDF-Dokuments angeben und FDF-Datei abspeichern. Achten Sie darauf, dass Sie hier unter Windows den kompletten Pfad beim Abspeichern angeben, denn die FDF-Datei wird sonst relativ zum Speicherort der Datei fdftk.dll abgelegt.
  1. $fdf = fdf_create();
  2. fdf_set_value($fdf, 'Name', $_POST['Name']);
  3. fdf_set_value($fdf, 'Einnahmen', $_POST['Ein']);
  4. fdf_set_value($fdf, 'Ausgaben', '-' . $_POST['Aus']);
  5. fdf_set_file($fdf, 'steuer.pdf');
  6. $zufall = mt_rand(100000, 999999) . mt_rand(100000, 999999);
  7. fdf_save($fdf, dirname(__FILE__) . "/$zufall.fdf");
  8. fdf_close($fdf);
Ein komplettes Listing finden Sie unter dem Dateinamen fdf-php.php auf der Heft-CD.

Wer es ganz luxuriös will: Der Adobe LifeCycle Designer [6] ist eine Art besserer XML-Editor, der daraus PDF- oder HTML-Dateien generieren kann.Doch all dieser Aufwand soll nicht nötig sein. Justin Koivisto hat schon vor einiger Zeit das FDF-Format genauer analysiert und die Erstellung in ein paar unter GPL gestellten Funktionen gekapselt; neuerdings gibt es auch noch ein Tutorial auf seiner Website [7]. Damit können Sie sich die Anmeldung sparen. Ein Tool zum Erstellen von PDFs mit Formularfeldern benötigen Sie aber trotzdem noch.
PDF erstellen
Erstellen Sie zunächst ein PDF mit dem Rahmen-Layout. Hier bietet sich etwa eine Textverarbeitung an. Im Beispiel soll eine sehr vereinfachte Steuererklärung erstellt werden, die fast noch auf einen Bierdeckel passen könnte. Den Textrahmen geben Sie vor, doch interessant wird es erst, wenn Sie Felder hinzufügen. Die Steuererklärung erwartet nur drei Angaben: Den Namen, die Einnahmen und die (abzugsfähigen) Ausgaben. Den Rest weiß das Finanzamt sowieso schon.Außerdem fügen Sie in Acrobat noch ein Feld für die Differenz aus Einnahmen und Ausgaben ein. Acrobat bietet dazu keine vorgefertigte Rechenregel, wohl aber eine für die Addition. Da Sie das Feld später selbst mit Werten füllen, können Sie festlegen, dass die Ausgaben immer als negativer Wert eingetragen werden. Deswegen können Sie angeben, dass sich das Differenz-Feld als Summe der Einnahmen und Ausgaben berechnet. Gleichzeitig können Sie es mit einem Schreibschutz versehen, der Benutzer sieht dann nur noch die Ausgabe. Prinzipiell ist es natürlich eine gute Idee, die anderen Felder auch mit einem Schreibschutz zu belegen, außer Sie wollen es den Benutzern ermöglichen, die Angaben noch direkt im Adobe Reader (ehemals: Acrobat Reader) zu bearbeiten.
FDF erstellen
Sobald die Datei gespeichert ist, geht es auch direkt an das Einfügen der Daten via FDF. Ein kleines Formular fragt die steuerlich relevanten Daten ab:
  1. <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
  2. Steuerpflichtiger: <input type="text" name="Name" /><br />
  3. Einnahmen: <input type="text" name="Ein" /><br />
  4. Ausgaben: <input type="text" name="Aus" /><br />
  5. <input type="submit" value="Steuererkl&auml;rung erzeugen" />
  6. </form>
Sobald das Formular verschickt worden ist, tritt der Code von Justin Koivisto in Aktion. Werfen wir zunächst einen Blick darauf. Die Funktion ist erfreulich kurz, der darüber eingefügte GPL-Lizenzhinweis ist länger. Für jedes Feld werden die folgenden Daten in die FDF-Datei hinzugefügt:
  1. << /T (<Feldname>) /V ('<Feldwert>')>>
Dabei sind natürlich und durch die zugehörigen Daten zu ersetzen. Sie sehen also, keine Hexerei, sondern eigentlich wirklich simpel; vor Justin Koivisto hat sich wohl nur keiner hingesetzt, um das herauszufinden und zu veröffentlichen.

Listing 1
  1. <?php
  2. /*
  3. KOIVI HTML Form to FDF Parser for PHP (C) 2004 Justin Koivisto
  4. Version 2.0
  5. Last Modified: 12/21/2004 4:44PM
  6. This library is free software; you can redistribute it and/or modify it
  7. under the terms of the GNU Lesser General Public License as published by
  8. the Free Software Foundation; either version 2.1 of the License, or (at
  9. your option) any later version.
  10. This library is distributed in the hope that it will be useful, but
  11. WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  12. or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
  13. License for more details.
  14. You should have received a copy of the GNU Lesser General Public License
  15. along with this library; if not, write to the Free Software Foundation,
  16. Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. Full license agreement notice can be found in the LICENSE file contained
  18. within this distribution package.
  19. Justin Koivisto
  20. justin.koivisto@gmail.com
  21. http://www.koivi.com
  22. */
  23. /*
  24. * createFDF v2 - Justin Koivisto 12/21/2004 4:44PM
  25. *
  26. * Takes values submitted via an HTML form and fills in the corresponding
  27. * fields into an FDF file for use with a PDF file with form fields.
  28. *
  29. * @param $file The pdf file that this form is meant for. Can be either
  30. * a url or a file path.
  31. * @param $info The submitted values in key/value pairs. (eg. $_POST)
  32. * @result Returns the FDF file contents for further processing.
  33. */
  34. function createFDF($file,$info){
  35. $data="%FDF-1.2\n%âãÏÓ\n1 0 obj\n<< \n/FDF << /Fields [ ";
  36. while(list($field,$val)=@each($info))
  37. $data.='<< /T ('.$field.') /V ('.trim($val).')>> ';
  38. $data.="] \n/F (".$file.") /ID [ <".md5(time()).">\n] >>".
  39. " \n>> \nendobj\ntrailer\n".
  40. "<<\n/Root 1 0 R \n\n>>\n%%EOF\n";
  41. return $data;
  42. }
  43. ?>
Doch zurück zum Skript: Das bindet die PHP-Datei mit der FDF-Hilfsfunktion ein (Listing 1) und übergibt die Formulardaten sowie den Namen des ursprünglichen Dokuments (als Dateipfad oder als URL):
  1. require 'fdf.inc.php';
  2. $fdf = createFDF(
  3. 'steuer.pdf',
  4. array(
  5. 'Name' => $_POST['Name'],
  6. 'Einnahmen' => $_POST['Ein'],
  7. 'Ausgaben' => '-' . $_POST['Aus']
  8. )
  9. );
Als Schlüssel im assoziativen Array verwenden Sie exakt die Feldnamen, wie sie im PDF-Dokument definiert worden sind.Das war es auch schon im Wesentlichen. Sie speichern den Rückgabewert in einer Datei mit einem möglichst zufälligen Dateinamen und bieten ihn zum Download an (und sorgen, beispielsweise per Cronjob, dafür, dass Dateien mit der Endung .fdf in regelmäßigem Abstand von dem Server gelöscht werden.
  1. $zufall = mt_rand(100000, 999999) . mt_rand(100000, 999999);
  2. file_put_contents("$zufall.fdf", $fdf);
  3. echo "<p>Steuererklärung erzeugt!</p>";
  4. echo "<p><a href=\"$zufall.fdf\">Download</a></p>";
Die Funktion file_put_contents() gibt es erst ab PHP 5; Anwender älterer Versionen müssen also auf eine Kombination aus fopen(), fwrite() und fclose() setzen. Die erzeugte Datei sieht dann in etwa wie folgt aus:
  1. %FDF-1.2
  2. %âãÏÓ
  3. 1 0 obj
  4. <<
  5. /FDF << /Fields [ << /T (Name) /V (Christian Wenz)>> << /T (Einnahmen) /V (1000)>> << /T (Ausgaben) /V (-750)>> ]
  6. /F (steuer.pdf) /ID [ <6aa279633f28f98325ade722885338da>
  7. ] >>
  8. >>
  9. endobj
  10. trailer
  11. <<
  12. /Root 1 0 R
  13. >>
  14. %%EOF
Den kompletten Code finden Sie in Listing 2. Einen kleinen Nachteil gibt es jedoch noch: Der Adobe Reader registriert sich zwar als Anzeigeprogramm für Dateien mit der Endung .fdf, jedoch zusammen mit einem bestimmten MIME-Typ, sonst kann es passieren, dass die Daten als Text im Browser angezeigt werden. Assoziieren Sie also in der Konfiguration des verwendeten Webservers die Dateiendung .fdf mit dem MIME-Typ application/vnd.fdf.

Listing 2
  1. <!DOCTYPE html
  2. PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  3. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4. <html>
  5. <head>
  6. <title>Online-Steuererklärung</title>
  7. </head>
  8. <body>
  9. <h1>Online-Steuererklärung</h1>
  10. <?php
  11. if (isset($_POST['Name']) && isset($_POST['Ein']) && isset($_POST['Aus'])) {
  12. require 'fdf.inc.php';
  13. $fdf = createFDF(
  14. 'steuer.pdf',
  15. array(
  16. 'Name' => $_POST['Name'],
  17. 'Einnahmen' => $_POST['Ein'],
  18. 'Ausgaben' => '-' . $_POST['Aus']
  19. )
  20. );
  21. $zufall = mt_rand(100000, 999999) . mt_rand(100000, 999999);
  22. file_put_contents("$zufall.fdf", $fdf);
  23. echo "<p>Steuererklärung erzeugt!</p>";
  24. echo "<p><a href=\"$zufall.fdf\">Download</a></p>";
  25. } else {
  26. ?>
  27. <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
  28. Steuerpflichtiger: <input type="text" name="Name" /><br />
  29. Einnahmen: <input type="text" name="Ein" /><br />
  30. Ausgaben: <input type="text" name="Aus" /><br />
  31. <input type="submit" value="Steuererkl&auml;rung erzeugen" />
  32. </form>
  33. <?php
  34. }
  35. ?>
  36. </body>
  37. </html>
Der Adobe Reader öffnet die FDF-Datei und findet in ihr den Dateipfad oder die URL zur eigentlichen PDF-Datei. Diese wird nachgeladen und mit den Formularwerten vorausgefüllt. Ganz fälschungssicher ist das leider nicht, da die FDF-Datei nur aus Textinformationen besteht. Für vertrauliche Informationen, die nicht modifiziert werden dürfen, müssen Sie dann doch auf eine kostenpflichtige Lösung setzen. Ansonsten aber haben Sie so wieder einmal mit wenig Aufwand und vor allem (fast) ohne Kosten erreicht, wofür Sie sonst eigentlich tief in die Tasche greifen müssten. Bis zur nächsten Ausgabe!
Christian Wenz ist als Autor, Trainer und Berater mit Schwerpunkt Webtechnologien tätig und spricht auf Konferenzen im In- und Ausland. In seiner Serie x ohne x zeigt er in jeder Ausgabe des PHP Magazins, wie PHP ungeahnte Fähigkeiten entwickeln kann. Seine Steuererklärung lässt noch auf sich warten.

Links und Literatur

Kommentare