There is already code like this implemented on a website that I’m working on, however the way the server renders it requires an extremely long time to actually render PDF data retreived from a web form. So I heard about what is known as an FDF file, which is for PDFs to pull the information straight from the fdf. So my goal is now to get a PDF to display the information located on the FDF file. I found a bit of code designed back in 2004 and apparently it works. but there are some things I’m concerned with.
[php]
require_once(‘forge_fdf.php’);
// leave this blank if we’re associating the FDF w/ the PDF via URL
$pdf_form_url= “”;
// default data; these two arrays must ultimately list all of the fields
// you desire to alter, even if you just want to set the ‘hidden’ flag;
//
//
$fdf_data_names= array(); // none of these in this example
$fdf_data_strings= array(); // none of these in this example
$fdf_data_strings[‘DATE’]=$row_delivreur[‘DATE’];
$fdf_data_strings[‘INVOICE’]=$row_delivreur[‘INVOICE’];
$fdf_data_strings[‘TERMS’]=$row_delivreur[‘TERMS’];
$fdf_data_strings[‘DUE DATE’]=$row_delivreur[‘DUE DATE’];
$fdf_data_strings[‘BILL TO’]=$row_delivreur[‘BILL TO’];
$fdf_data_strings[‘SHIP TO’]=$row_delivreur[‘SHIP TO’];
$fdf_data_strings[‘AMOUNT DUE’]=$row_delivreur[‘AMOUNT DUE’];
$fdf_data_strings[‘ENCLOSED’]=$row_delivreur[‘ENCLOSED’];
$fdf_data_strings[‘SHIP VIA’]=$row_delivreur[‘SHIP VIA’];
$fdf_data_strings[‘TRACKING’]=$row_delivreur[‘TRACKING’];
$fdf_data_strings[‘SVC DATES’]=$row_delivreur[‘SVC DATES’];
$fdf_data_strings[‘TEL’]=$row_delivreur[‘TEL’];
$fdf_data_strings[‘DATE1’]=$row_delivreur[‘DATE1’];
$fdf_data_strings[‘ACTIVITY1’]=$row_delivreur[‘ACTIVITY1’];
$fdf_data_strings[‘QUANTITY1’]=$row_delivreur[‘QUANTITY1’];
$fdf_data_strings[‘RATE1’]=$row_delivreur[‘RATE1’];
$fdf_data_strings[‘AMOUNT1’]=$row_delivreur[‘AMOUNT1’];
$fdf_data_strings[‘DATE2’]=$row_delivreur[‘DATE2’];
$fdf_data_strings[‘ACTIVITY2’]=$row_delivreur[‘ACTIVITY2’];
$fdf_data_strings[‘QUANTITY2’]=$row_delivreur[‘QUANTITY2’];
$fdf_data_strings[‘RATE2’]=$row_delivreur[‘RATE2’];
$fdf_data_strings[‘AMOUNT2’]=$row_delivreur[‘AMOUNT2’];
$fdf_data_strings[‘DATE3’]=$row_delivreur[‘DATE3’];
$fdf_data_strings[‘ACTIVITY3’]=$row_delivreur[‘ACTIVITY3’];
$fdf_data_strings[‘QUANTITY3’]=$row_delivreur[‘QUANTITY3’];
$fdf_data_strings[‘RATE3’]=$row_delivreur[‘RATE3’];
$fdf_data_strings[‘AMOUNT3’]=$row_delivreur[‘AMOUNT3’];
$fdf_data_strings[‘DATE4’]=$row_delivreur[‘DATE4’];
$fdf_data_strings[‘ACTIVITY4’]=$row_delivreur[‘ACTIVITY4’];
$fdf_data_strings[‘QUANTITY4’]=$row_delivreur[‘QUANTITY4’];
$fdf_data_strings[‘RATE4’]=$row_delivreur[‘RATE4’];
$fdf_data_strings[‘AMOUNT4’]=$row_delivreur[‘AMOUNT4’];
$fdf_data_strings[‘DATE5’]=$row_delivreur[‘DATE5’];
$fdf_data_strings[‘ACTIVITY5’]=$row_delivreur[‘ACTIVITY5’];
$fdf_data_strings[‘QUANTITY5’]=$row_delivreur[‘QUANTITY5’];
$fdf_data_strings[‘RATE5’]=$row_delivreur[‘RATE5’];
$fdf_data_strings[‘AMOUNT5’]=$row_delivreur[‘AMOUNT5’];
$fdf_data_strings[‘DATE6’]=$row_delivreur[‘DATE6’];
$fdf_data_strings[‘ACTIVITY6’]=$row_delivreur[‘ACTIVITY6’];
$fdf_data_strings[‘QUANTITY6’]=$row_delivreur[‘QUANTITY6’];
$fdf_data_strings[‘RATE6’]=$row_delivreur[‘RATE6’];
$fdf_data_strings[‘AMOUNT6’]=$row_delivreur[‘AMOUNT6’];
$fdf_data_strings[‘DATE7’]=$row_delivreur[‘DATE7’];
$fdf_data_strings[‘ACTIVITY7’]=$row_delivreur[‘ACTIVITY7’];
$fdf_data_strings[‘QUANTITY7’]=$row_delivreur[‘QUANTITY7’];
$fdf_data_strings[‘RATE7’]=$row_delivreur[‘RATE7’];
$fdf_data_strings[‘AMOUNT7’]=$row_delivreur[‘AMOUNT7’];
$fdf_data_strings[‘DATE8’]=$row_delivreur[‘DATE8’];
$fdf_data_strings[‘ACTIVITY8’]=$row_delivreur[‘ACTIVITY8’];
$fdf_data_strings[‘QUANTITY8’]=$row_delivreur[‘QUANTITY8’];
$fdf_data_strings[‘RATE8’]=$row_delivreur[‘RATE8’];
$fdf_data_strings[‘AMOUNT8’]=$row_delivreur[‘AMOUNT8’];
$fdf_data_strings[‘DATE9’]=$row_delivreur[‘DATE9’];
$fdf_data_strings[‘ACTIVITY9’]=$row_delivreur[‘ACTIVITY9’];
$fdf_data_strings[‘QUANTITY9’]=$row_delivreur[‘QUANTITY9’];
$fdf_data_strings[‘RATE9’]=$row_delivreur[‘RATE9’];
$fdf_data_strings[‘AMOUNT9’]=$row_delivreur[‘AMOUNT9’];
$fdf_data_strings[‘DATE10’]=$row_delivreur[‘DATE10’];
$fdf_data_strings[‘ACTIVITY10’]=$row_delivreur[‘ACTIVITY10’];
$fdf_data_strings[‘QUANTITY10’]=$row_delivreur[‘QUANTITY10’];
$fdf_data_strings[‘RATE10’]=$row_delivreur[‘RATE10’];
$fdf_data_strings[‘AMOUNT10’]=$row_delivreur[‘AMOUNT10’];
$fdf_data_strings[‘DATE11’]=$row_delivreur[‘DATE11’];
$fdf_data_strings[‘ACTIVITY11’]=$row_delivreur[‘ACTIVITY11’];
$fdf_data_strings[‘QUANTITY11’]=$row_delivreur[‘QUANTITY11’];
$fdf_data_strings[‘RATE11’]=$row_delivreur[‘RATE11’];
$fdf_data_strings[‘AMOUNT11’]=$row_delivreur[‘AMOUNT11’];
$fdf_data_strings[‘DATE12’]=$row_delivreur[‘DATE12’];
$fdf_data_strings[‘ACTIVITY12’]=$row_delivreur[‘ACTIVITY12’];
$fdf_data_strings[‘QUANTITY12’]=$row_delivreur[‘QUANTITY12’];
$fdf_data_strings[‘RATE12’]=$row_delivreur[‘RATE12’];
$fdf_data_strings[‘AMOUNT12’]=$row_delivreur[‘AMOUNT12’];
$fdf_data_strings[‘DATE13’]=$row_delivreur[‘DATE13’];
$fdf_data_strings[‘ACTIVITY13’]=$row_delivreur[‘ACTIVITY13’];
$fdf_data_strings[‘QUANTITY13’]=$row_delivreur[‘QUANTITY13’];
$fdf_data_strings[‘RATE13’]=$row_delivreur[‘RATE13’];
$fdf_data_strings[‘AMOUNT13’]=$row_delivreur[‘AMOUNT13’];
$fdf_data_strings[‘DATE14’]=$row_delivreur[‘DATE14’];
$fdf_data_strings[‘ACTIVITY14’]=$row_delivreur[‘ACTIVITY14’];
$fdf_data_strings[‘QUANTITY14’]=$row_delivreur[‘QUANTITY14’];
$fdf_data_strings[‘RATE14’]=$row_delivreur[‘RATE14’];
$fdf_data_strings[‘SUBTOTAL’]=$row_delivreur[‘SUBTOTAL’];
$fdf_data_strings[‘TAX’]=$row_delivreur[‘TAX’];
$fdf_data_strings[‘TOTAL’]=$row_delivreur[‘TOTAL’];
$fields_hidden= array();
$fields_readonly= array();
// set this to retry the previous state
$retry_b= false;
header( ‘content-type: application/vnd.fdf’ );
echo forge_fdf( $pdf_form_url,
$fdf_data_strings,
$fdf_data_names,
$fields_hidden,
$fields_readonly );
[/php]
I have it calling from a separate php file.
[php]
function
escape_pdf_string( $ss )
{
$backslash= chr(0x5c);
$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.= $backslash.$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;
}
// In PDF, partial form field names are combined using periods to
// yield the full form field name; we’ll take these dot-delimited
// names and then expand them into nested arrays, here; takes
// an array that uses dot-delimited names and returns a tree of arrays;
//
function
burst_dots_into_arrays( &$fdf_data_old )
{
$fdf_data_new= array();
foreach( $fdf_data_old as $key => $value ) {
$key_split= explode( ‘.’, (string)$key, 2 );
if( count($key_split)== 2 ) { // handle dot
if( !array_key_exists( (string)($key_split[0]), $fdf_data_new ) ) {
$fdf_data_new[ (string)($key_split[0]) ]= array();
}
if( gettype( $fdf_data_new[ (string)($key_split[0]) ] )!= 'array' ) {
// this new key collides with an existing name; this shouldn't happen;
// associate string value with the special empty key in array, anyhow;
$fdf_data_new[ (string)($key_split[0]) ]=
array( '' => $fdf_data_new[ (string)($key_split[0]) ] );
}
$fdf_data_new[ (string)($key_split[0]) ][ (string)($key_split[1]) ]= $value;
}
else { // no dot
if( array_key_exists( (string)($key_split[0]), $fdf_data_new ) &&
gettype( $fdf_data_new[ (string)($key_split[0]) ] )== 'array' )
{ // this key collides with an existing array; this shouldn't happen;
// associate string value with the special empty key in array, anyhow;
$fdf_data_new[ (string)$key ]['']= $value;
}
else { // simply copy
$fdf_data_new[ (string)$key ]= $value;
}
}
}
foreach( $fdf_data_new as $key => $value ) {
if( gettype($value)== ‘array’ ) {
$fdf_data_new[ (string)$key ]= burst_dots_into_arrays( $value ); // recurse
}
}
return $fdf_data_new;
}
function
forge_fdf_fields_flags( &$fdf,
$field_name,
&$fields_hidden,
&$fields_readonly )
{
if( in_array( $field_name, $fields_hidden ) )
$fdf.= "/SetF 2 "; // set
else
$fdf.= "/ClrF 2 "; // clear
if( in_array( $field_name, $fields_readonly ) )
$fdf.= "/SetFf 1 "; // set
else
$fdf.= "/ClrFf 1 "; // clear
}
function
forge_fdf_fields( &$fdf,
&$fdf_data,
&$fields_hidden,
&$fields_readonly,
$accumulated_name,
$strings_b ) // true <==> $fdf_data contains string data
//
// string data is used for text fields, combo boxes and list boxes;
// name data is used for checkboxes and radio buttons, and
// /Yes and /Off are commonly used for true and false
{
if( 0< strlen( $accumulated_name ) ) {
$accumulated_name.= ‘.’; // append period seperator
}
foreach( $fdf_data as $key => $value ) {
// we use string casts to prevent numeric strings from being silently converted to numbers
$fdf.= "<< "; // open dictionary
if( gettype($value)== 'array' ) { // parent; recurse
$fdf.= "/T (".escape_pdf_string( (string)$key ).") "; // partial field name
$fdf.= "/Kids [ "; // open Kids array
// recurse
forge_fdf_fields( $fdf,
$value,
$fields_hidden,
$fields_readonly,
$accumulated_name. (string)$key,
$strings_b );
$fdf.= "] "; // close Kids array
}
else {
// field name
$fdf.= "/T (".escape_pdf_string( (string)$key ).") ";
// field value
if( $strings_b ) { // string
$fdf.= "/V (".escape_pdf_string( (string)$value ).") ";
}
else { // name
$fdf.= "/V /".escape_pdf_name( (string)$value ). " ";
}
// field flags
forge_fdf_fields_flags( $fdf,
$accumulated_name. (string)$key,
$fields_hidden,
$fields_readonly );
}
$fdf.= ">> \x0d"; // close dictionary
}
}
function
forge_fdf_fields_strings( &$fdf,
&$fdf_data_strings,
&$fields_hidden,
&$fields_readonly )
{
return
forge_fdf_fields( $fdf,
$fdf_data_strings,
$fields_hidden,
$fields_readonly,
‘’,
true ); // true => strings data
}
function
forge_fdf_fields_names( &$fdf,
&$fdf_data_names,
&$fields_hidden,
&$fields_readonly )
{
return
forge_fdf_fields( $fdf,
$fdf_data_names,
$fields_hidden,
$fields_readonly,
‘’,
false ); // false => names data
}
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
$fdf_data_strings= burst_dots_into_arrays( $fdf_data_strings );
forge_fdf_fields_strings( $fdf,
$fdf_data_strings,
$fields_hidden,
$fields_readonly );
$fdf_data_names= burst_dots_into_arrays( $fdf_data_names );
forge_fdf_fields_names( $fdf,
$fdf_data_names,
$fields_hidden,
$fields_readonly );
$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;
}
[/php]
Here is the error I recieve when I try to get it to work on a server.
Adobe Acrobat:
A file I/O error has occurred.
I’m a total newbie when it comes to php and could use some help.