Motivation
Interaction on the WWW often means filling out forms, hitting the submit
button and getting a certain result. HTML and HTTP provide a mechanism to perform
this quite easily through forms. PHP has support for this
mechanism in a very convenient way. The
values of each input field are stored in PHP variables, with the same
name as the input field.
A mechanism quite similar has been developed by
Adobe, but for PDF documents. They simply
call it Acrobat Forms. From the users point of view, the only difference in HTML
forms and Acrobat forms is their appearance. The first one
uses HTML documents, while the second one uses PDF documents to present
the form.
For developers of web interfaces, Acrobat Forms can be handled
like HTML forms, if the form provides its input data as HTML forms. However, Adobe
has introduced a new format for form data called FDF (Form Data Format).
PHP already includes support for this format.
The possibility to
populate a PDF document with data, e.g. to customize it, is an additional feature of Acrobat Forms. .
Using PDF documents as forms and populating PDF documents with
data using PHP will be described in this article. Two examples demonstrate
how easy it is.
Before you start trying the online examples in this article
you should install the
Acrobat Reader Plug-in or use Acrobat 4. If you want to test the PHP scripts
on your own web server you will also need to install the
FDF Toolkit and
enable FDF support in PHP. Finally, if you want to develop your own PDF forms
you will need Acrobat Exchange 3.x or Acrobat 4.
How it works
Adobe has developed the portable document format
(PDF) and extended it over the last years. One of these extensions are Acrobat
Forms which allow a user to input data and send it to the
server where it is evaluated, just as HTML forms. Such a PDF document is
very similar to a static PDF document, but when you look at it with
the Acrobat Reader, you will find areas which can be edited.
There are many input fields available just like in HTML, e.g. a submit and reset
button, text input fields, check boxes etc.. Creating such a PDF form
requires Acrobat Exchange 3.x or the
new Acrobat 4 software, which unfortunately only runs on Windows and MacOS.
Both provide a mode to place the different input fields into an existing
PDF document. The submit button carries an attribute which specifies the
URL to call when it is pressed. This is very similar to HTML, but can differ
in the format when the entered data is transfered to the server.
Data from HTML forms is transfered using a certain syntax which can be
observed in the URL after hitting the submit button.
Acrobat Forms support this format, but also FDF (Form Data Format).
FDF is a new format which requires the
FDF Toolkit
(current version is 4.0)
to parse. If PHP has FDF support compiled, it can parse FDF data and
access any field by its name. FDF data is currently stored by PHP in
the variable HTTP_RAW_POST_DATA (just as HTML data is stored in HTTP_POST_DATA).
The actual evaluation of the data has to be done in the PHP script, as opposed
to the HTML post data which is evaluated by the PHP engine.
To get an impression of what the FDF data looks like, here is an example:
%FDF-1.2 %âãÏÓ 1 0 obj << /FDF << /Fields [ << /V (This is just some text for testing)/T (comment)>> ....
It is just the first portion of a complete record, but one should be able to
clearly identify
the input field comment and its value. Here is text for testing.
In order to make this clearer, a simple example is provided. First, assume we have a
PDF
form containing the fields
volume, publisher, preparer, date, comment
show_publisher, show_preparer.
The first five fields are text input fields; the last two are check boxes.
Our PHP script shall always display the values of the fields
volume, date,
comment, but display the value of the fields
publisher and preparer
only if the corresponding check boxes are checked. If the boxes are checked, their
value is "On" since it was preset when the form was created. And of course the
form also has a submit button, in our case it even has a reset button.
Hitting the submit button runs the following script. This script evaluates the
field data as described above.
<?php
$fdffp = fopen("test.fdf", "w");
fwrite($fdffp, $HTTP_RAW_POST_DATA, strlen($HTTP_RAW_POST_DATA));
fclose($fdffp);
$fdf = fdf_open("test.fdf");
$volume = fdf_get_value($fdf, "volume");
echo "The volume field has the value '<B>$volume</B>'<BR>";
$date = fdf_get_value($fdf, "date");
echo "The date field has the value '<B>$date</B>'<BR>";
$comment = fdf_get_value($fdf, "comment");
echo "The comment field has the value '<B>$comment</B>'<BR>";
if(fdf_get_value($fdf, "show_publisher") == "On") {
$publisher = fdf_get_value($fdf, "publisher");
echo "The publisher field has the value '<B>$publisher</B>'<BR>";
} else
echo "Publisher shall not be shown.<BR>";
if(fdf_get_value($fdf, "show_preparer") == "On") {
$preparer = fdf_get_value($fdf, "preparer");
echo "The preparer field has the value '<B>$preparer</B>'<BR>";
} else
echo "Preparer shall not be shown.<BR>";
fdf_close($fdf);
?>
Beside the fact that PDF forms have a nicer appearance than HTML forms, there
seems to be no real advantage of this technology.
However, there is another usage of FDF. You can turn the above process around
and populate a PDF document with data. This is quite useful if you
need to customize only certain parts in a PDF document, e.g. a address,
date etc..
One could also create the complete PDF document, with PHP's PDF creation
functions, but this is a lot of work for complex documents. In general, it
is also desirable to use prepared documents created
by a designer, for example. Creating PDF forms with the PDF functions in PHP is not
possible.
Populating a PDF document with data is quite simple with FDF.
You will have to create a PDF document and add input fields to it, e.g.
with Acrobat 4. Put in on your web server.
Then, you need to create the FDF document with PHP, which contains each
field, its value and a reference to the document where the data
is to be inserted. (The PDF document you have just created). This will
be done on the fly with PHP. The reference is a URL pointing to the PDF
document.
Taking the first example as a basis, the following script shows how easy
this is with PHP. The second part of the script has been added.
<?php
$fdffp = fopen("test.fdf", "w");
fwrite($fdffp, $HTTP_RAW_POST_DATA, strlen($HTTP_RAW_POST_DATA));
fclose($fdffp);
$fdf = fdf_open("test.fdf");
$volume = fdf_get_value($fdf, "volume");
$date = fdf_get_value($fdf, "date");
$comment = fdf_get_value($fdf, "comment");
if(fdf_get_value($fdf, "show_publisher") == "On") {
$publisher = fdf_get_value($fdf, "publisher");
} else
$publisher = "";
if(fdf_get_value($fdf, "show_preparer") == "On") {
$preparer = fdf_get_value($fdf, "preparer");
} else
$preparer = "";
fdf_close($fdf);
$outfdf = fdf_create();
fdf_set_value($outfdf, "f_volume", $volume, 0);
fdf_set_value($outfdf, "b_volume", $volume, 0);
fdf_set_value($outfdf, "f_comment", $comment, 0);
fdf_set_value($outfdf, "b_comment", $comment, 0);
fdf_set_value($outfdf, "f_date", $date, 0);
fdf_set_value($outfdf, "b_date", $date, 0);
fdf_set_value($outfdf, "f_preparer", $preparer, 0);
fdf_set_value($outfdf, "b_preparer", $preparer, 0);
fdf_set_value($outfdf, "f_publisher", $publisher, 0);
fdf_set_value($outfdf, "b_publisher", $publisher, 0);
fdf_set_file($outfdf, "http:/testfdf/resultlabel.pdf");
fdf_save($outfdf, "outtest.fdf");
fdf_close($outfdf);
Header("Content-type: application/vnd.fdf");
$fp = fopen("outtest.fdf", "r");
fpassthru($fp);
unlink("outtest.fdf");
?>
In this example several steps are performed:
- The user fills out the PDF form example2.pdf
- After hitting the submit button, the URL associated with the submit
button is called. In this case, it has to be the PHP script.
- The PHP script retrieves the data from the FDF data stream and
creates a new FDF document, which contains the data for the resulting
PDF document.
- The FDF document is sent back with the MimeType application/vnd.fdf.
- The Acrobat Plug-In reads the data and displays the refereed
PDF document. In this case resultlabel.pdf.
This is still not everything FDF has to offer, but there is too much left
to be discussed in this tutorial. You should check out the
documentation
at Adobe's web site.
-- Uwe