Search code examples
phppdffpdfpdf-form

PDF form population with FPDM


what I'm trying to accomplish is population of PDF form with PHP.
I tried many ways, I found that FPDM (FPDF) is working well when I create a new form, or use the form from source file they provided.
My problem is when I'm using already created PDF form, the form has restrictions such as Owner password, document is signed and certified. I used the app to remove those restrictions, some of them are left. In picture below you can see how my current PDF looks like.

enter image description here

That PDF also was compressed, and because FPDM was throwing the error that 'Object Stream' is not supported I decompressed it through PDFTK, so file went from 1.48 Mb to 6.78 Mb.

To get all form field names I used also PDFTK, so I have them in txt file.

There are two ways I can do by the instructions of FPDM:

First way is only to send an array field_name => value along with PDF I want to change and that's it. So when I use PDF described above I get error:

'FPDF-Merge Error: field form1[0].#subform[0].Line1_GivenName[0] not found'

Just to remind that I have all names and this name exists.

<?php
require('fpdm.php');

$fields = array(
        'form1[0].#subform[0].Line1_GivenName[0]' => 'my name'
    );
$pdf = new FPDM('test.pdf');
$pdf->Load($fields, false); // second parameter: false if field values are in ISO-8859-     1, true if UTF-8
$pdf->Merge();
$pdf->Output('new_pdf.pdf', 'F');
?>

The other way is that I create FDF file with createXFDF function and then use FPDM to merge FDF to PDF. This solution creates 'new_file.pdf' like I want but empty :)

function createXFDF($file, $info, $enc = 'UTF-8') {
$data = '<?xml version="1.0" encoding="'.$enc.'"?>' . "\n" .
    '<xfdf xmlns="http://ns.adobe.com/xfdf/" xml:space="preserve">' . "\n" .
    '<fields>' . "\n";
foreach($info as $field => $val) {
    $data .= '<field name="' . $field . '">' . "\n";
    if(is_array($val)) {
        foreach( $val as $opt )
            $data .= '<value>' .
                htmlentities( $opt, ENT_COMPAT, $enc ) .
                '</value>' . "\n";
    } else {
        $data .= '<value>' .
            htmlentities( $val, ENT_COMPAT, $enc ) .
            '</value>' . "\n";
    }
    $data .= '</field>' . "\n";
}
$data .= '</fields>' . "\n" .
    '<ids original="' . md5( $file ) . '" modified="' .
        time() . '" />' . "\n" .
    '<f href="' . $file . '" />' . "\n" .
    '</xfdf>' . "\n";

return $data;
}


require('fpdm.php');

$pdf = new FPDM('test.pdf', 'posted-0.fdf');
$pdf->Merge();
$pdf->Output('new_file.pdf', 'F');

One more thing, if I try to open FDF file in Acrobat I get a message

'The file you are attempting to open contains comments or form data that are supposed to be placed on test.pdf. This document cannot be found. It may have been moved, or deleted. Would you like to browse to attempt to locate this document?'

but the file is there, not moved or deleted. When I find it manually the form populates.

If anyone has experience with this, any help or advice would help a lot.

Thank you in advance, Vukasin

EDIT: More info about the PDF file enter image description here


Solution

  • After revealing the creator/producer info the problem is clear.

    You do not have a real PDF form, but you have a XFA form (created by LiveCycle Designer), wrapped in a PDF wrapper so that Adobe Reader can display it.

    XFA forms do not support (X)FDF. You have to import data using XML. You can try to export the data from a filled version, and then use this as a sample for creating the import XML.

    Note that the XML export/import format XFA forms use is not the same as XFDF (which is simply an XML representation of FDF, the PDF-native forms data format).