Hack 76 Drive PDF Forms with Your Data

 < Day Day Up > 

figs/expert.gif figs/hack76.gif

Convert your data into FDF so that Acrobat or Reader can merge it with a PDF form .

As discussed in [Hack #75] , you can deliver filled-out PDF forms on the Web by serving FDF data. FDF data contains the URL for your PDF form and the data with which to fill the form. Upon receiving FDF data, Acrobat (or Reader) will open the referenced PDF form and then populate it with the given information. The next problem is how to easily create FDF data on your web server.

The PDF Reference [Hack #98] describes FDF in dizzying detail, and Adobe offers a free-of-charge FDF Toolkit with a dizzying license (http:// partners .adobe.com/asn/acrobat/forms.jsp). But what you need is usually easy to create from the comfort of your favorite web programming language. We provide such a script written in PHP. It converts form data into an FDF file suitable for filling our basic PDF form [Hack #74] .

In Java, try the FdfWriter and FdfReader classes in iText (http://www.lowagie.com/iText/) for creating or parsing FDF data.


Elaborate forms might require the high-caliber Adobe FDF Toolkit to create suitable FDF. Most forms merely require their field data cast into the FDF syntax. We offer the forge_fdf script for this purpose. The FDF example from [Hack #75] shows the pattern evident in simple FDF files.

Instead of using a general-purpose FDF function or library, you can also consider exporting an FDF file from your form and then converting it into a template. Replace the form values with variables or other placeholders. Serve this template back to your form after filling the variables with user data. forge_fdf includes functions for encoding PDF strings and names [Hack #80] , which you might find useful when filling in your template.

6.4.1 Create FDF with forge_fdf

Pass form data and a PDF's URL into forge_fdf, and it returns the corresponding FDF as a string. Create an FDF file with this string or serve it directly to the client browser with Content-type : application/vnd.fdf . We offer an example a little later.

You must remember some FDF peculiarities when passing arguments to forge_fdf.


$pdf_form_url

Provide the PDF form's URL (or filename) unless you plan to pass this FDF data as part of a larger URL that already references the PDF form. For example, if the FDF data will be served to the user like so:

 http://localhost/fine_form.pdf#FDF=http://localhost/fine_data.fdf 

pass an empty string as $pdf_form_url .

To exit a PDF form and replace it with an HTML page in the user's browser, serve the PDF an FDF with $pdf_form_url set to your HTML page's URL.


$fdf_data_strings

Load text, combo box, and listbox data into this array. It should be an array of string field names mapped to string field values. If you want a form field to be hidden or read-only, you must also add its name to $fields_hidden or $fields_readonly .


$fdf_data_names

Load checkbox and radio button data into this array. It should be an array of string field names mapped to string field values. Often, true and false correspond to the case-sensitive strings Yes and Off . If you want a form field to be hidden or read-only, you must also add its name to $fields_hidden or $fields_readonly .


$fields_hidden

If you want a field to disappear from view, add its name to this array. Any field listed here also must be in $fdf_data_strings or $fdf_data_names .


$fields_readonly

If you don't want the user tinkering with a field's data, add its name to this array. Any field listed here also must be in $fdf_data_strings or $fdf_data_names .

For example, the following script uses forge_fdf to serve FDF data that should cause the user's browser to open http://localhost/form.pdf and set its fields to match our values:

 <?php require_once('forge_fdf.php'); $pdf_form_url= "http://localhost/form.pdf"; $fdf_data_strings= array( 'text1' => $_GET['t'], 'text2' => 'Egads!' ); $fdf_data_names= array( 'check1' => 'Off', 'check2' => 'Yes' ); $fields_hidden= array( 'text2', 'check1' ); $fields_readonly= array( 'text1' ); header( 'content-type: application/vnd.fdf' ); echo forge_fdf( $pdf_form_url,                 $fdf_data_strings,                  $fdf_data_names,                 $fields_hidden,                 $fields_readonly ); ?> 

To see a more elaborate example of forge_fdf in action, visit http://www.pdfhacks.com/form_session/. Tinker with the online example or download PHP source code from this web page.

If forge_fdf isn't filling your form properly, export the FDF from your form to see exactly how the form expects its data. Try testing your larger program with these pristine example FDF files.


6.4.2 The Code

Copy this code into a file named forge_fdf.php and include it in your PHP scripts. Or, adapt this algorithm to your favorite language. Visit http://www.pdfhacks.com/forge_fdf/ to download the latest version.

 <?php /* forge_fdf, by Sid Steward    version 1.0    visit: http://www.pdfhacks.com/forge_fdf/   For text fields, combo boxes, and list boxes, add   field values as a name => value pair to $fdf_data_strings.   For checkboxes and radio buttons, add field values   as a name => value pair to $fdf_data_names.  Typically,   true and false correspond to the (case-sensitive)   names "Yes" and "Off".   Any field added to the $fields_hidden or $fields_readonly   array also must be a key in $fdf_data_strings or   $fdf_data_names; this might be changed in the future   Any field listed in $fdf_data_strings or $fdf_data_names   that you want hidden or read-only must have its field   name added to $fields_hidden or $fields_readonly; do this   even if your form has these bits set already   PDF can be particular about CR and LF characters, so I   spelled them out in hex: CR == \x0d : LF == \x0a  */ function escape_pdf_string( $ss ) {   $ss_esc= '';   $ss_len= strlen( $ss );   for( $ii= 0; $ii< $ss_len; ++$ii ) {     if( ord($ss{$ii})== 0x28   // open paren         ord($ss{$ii})== 0x29   // close paren         ord($ss{$ii})== 0x5c )   // backslash       {         $ss_esc.= chr(0x5c).$ss{$ii}; // escape the character w/ backslash       }     else if( ord($ss{$ii}) < 32  126 < ord($ss{$ii}) ) {       $ss_esc.= sprintf( "\%03o", ord($ss{$ii}) ); // use an octal code     }     else {       $ss_esc.= $ss{$ii};     }   }   return $ss_esc; } function escape_pdf_name( $ss ) {   $ss_esc= '';   $ss_len= strlen( $ss );   for( $ii= 0; $ii< $ss_len; ++$ii ) {     if( ord($ss{$ii}) < 33  126 < ord($ss{$ii})           ord($ss{$ii})== 0x23 ) // hash mark       {         $ss_esc.= sprintf( "#%02x", ord($ss{$ii}) ); // use a hex code       }     else {       $ss_esc.= $ss{$ii};     }   }   return $ss_esc; } function forge_fdf( $pdf_form_url,                      $fdf_data_strings,                     $fdf_data_names,                     $fields_hidden,                     $fields_readonly ) {   $fdf = "%FDF-1.2\x0d%\xe2\xe3\xcf\xd3\x0d\x0a"; // header   $fdf.= "1 0 obj\x0d<< "; // open the Root dictionary   $fdf.= "\x0d/FDF << "; // open the FDF dictionary   $fdf.= "/Fields [ "; // open the form Fields array   // string data, used for text fields, combo boxes, and list boxes   foreach( $fdf_data_strings as $key => $value ) {     $fdf.= "<< /V (".escape_pdf_string($value).")".       "/T (".escape_pdf_string($key).") ";     if( in_array( $key, $fields_hidden ) )       $fdf.= "/SetF 2 ";     else       $fdf.= "/ClrF 2 ";     if( in_array( $key, $fields_readonly ) )       $fdf.= "/SetFf 1 ";     else       $fdf.= "/ClrFf 1 ";     $fdf.= ">> \x0d";   }   // name data, used for checkboxes and radio buttons   // (e.g., /Yes and /Off for true and false)   foreach( $fdf_data_names as $key => $value ) {     $fdf.= "<< /V /".escape_pdf_name($value).       " /T (".escape_pdf_string($key).") ";     if( in_array( $key, $fields_hidden ) )       $fdf.= "/SetF 2 ";     else       $fdf.= "/ClrF 2 ";     if( in_array( $key, $fields_readonly ) )       $fdf.= "/SetFf 1 ";     else       $fdf.= "/ClrFf 1 ";     $fdf.= ">> \x0d";   }      $fdf.= "] \x0d"; // close the Fields array   // the PDF form filename or URL, if given   if( $pdf_form_url ) {     $fdf.= "/F (".escape_pdf_string($pdf_form_url).") \x0d";   }      $fdf.= ">> \x0d"; // close the FDF dictionary   $fdf.= ">> \x0dendobj\x0d"; // close the Root dictionary   // trailer; note the "1 0 R" reference to "1 0 obj" above   $fdf.= "trailer\x0d<<\x0d/Root 1 0 R \x0d\x0d>>\x0d";   $fdf.= "%%EOF\x0d\x0a";   return $fdf; } ?> 

 < Day Day Up > 


PDF Hacks.
PDF Hacks: 100 Industrial-Strength Tips & Tools
ISBN: 0596006551
EAN: 2147483647
Year: N/A
Pages: 158
Authors: Sid Steward

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net