Fill Out PDF forms with PDFtk and PHP

PDF forms with PDFtk & PHP. As we know that PDF files comes to be one of the most common options for people to share various documents online, whether the question comes about passing our client’s material to a third-party service providers such as banks, insurance companies and many other such firms or whether we send a CV to any employer with the help of PDF document, is frequently considered as the first option to work with. Well, working with PDF files lets you transfer plain as well as formatted text, images, hyperlinks, and even various forms that you need to be filled out.

Once your virtual machine is ready, and you have efficiently managed to login by ssh into your system, we can easily proceed with installing PDFtk by using apt-get:

1 sudo apt-get install pdftk

To check if it works, we can run the following command:

1 pdftk --version

The output should be similar to:

1 Copyright (c) 2003-16 Steward and Lee, LLC - Please Visit:www.pdftk.com. This is free software; see the source code for copying conditions. There is NO warranty, not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Workflow

1) PDFtk comes with a broad range of manipulating features to work with PDF documents, by merging and splitting several pages to fill efficiently out your PDF forms.
2) This tool lets you apply watermarks. PDFtk viably makes utilization of FDF documents to control PDF shapes rapidly. FDF is regularly alluded to as the Form Data.
3) File that comprises of a plain-text file to help store data that is included in the form.
4) Next, you can quickly generate a FDF file from user submitted data and merge them with your original PDF files with the help of using PDFtk’s commands.

What includes inside the FDF file?

Header section

// Mention about PDF

1 %FDF-1.2
2 1 0 obj<</FDF<< /Fields[

Content section

// Define all elments that you want to show in PDF

1 << /T (employee_name) /V (Shikha)
2 << /T (designation) /V (Content Writer)

Footer section

// Mention end process of PDF

1 ] >> >>
2 endobj
3 trailer
4 <</Root 1 0 R>>
5 %%EOF

Next your element’s value is prefixed with /V that signifies a value shown below:

1 << /T(FIELD_NAME)/V(FIELD_VALUE) >>

Alternatively, we can prefer to use PDFtk’s dump_data_fields command to extract easily numerous of field information from your file. Let’s see the code below:

1 pdftk path/to/the/form.pdf dump_data_fields > field_names.txt

PDFtk will save the outcome in the field_names.txt record. Allude to beneath case:

01 --
02 FieldType: Text
03 FieldName: employee_name
04 FieldFlags: 0
05 FieldJustification: Left
06 ---
07 FieldType: Text
08 FieldName: designation
09 FieldFlags: 0
10 FieldJustification: Left

PDFtk and PHP

PHP’s execss() function transforms a PDFtk format into PHP form. Let’s say for example: we hold a straightforward PDF structure with four content boxes by including a gathering of two radio catches. Let’s have a look below:

01 <?php
02 // Form data:
03 $ename   'Shikha';
04 $desg    = 'Content Writer;
05 // FDF header section
06 $fdf_header = <<<FDF
07 %FDF-1.2 // define form
08 %,,oe"
09 1 0 obj
10 <<
11 /FDF << /Fields [ // define form fields
12 FDF;
13 // FDF footer section
14 $fdf_footer = <<<FDF // define end of file process
15 "] >> >>
16 endobj
17 trailer
18 <</Root 1 0 R>>
19 %%EOF;
20 FDF;
21 // define content that will be show in PDF
22 $fdf_content "<</T(employee_name)/V({$ename})>>";
23 $fdf_content .= "<</T(designation)/V({$desg})>>";
24 // Combine header, content and footer section
25 $content $fdf_header $fdf_content $fdf_footer;
26 // Develop a temporary file that will be use for FDF file.
27 $FDFfile = tempnam(sys_get_temp_dir(), gethostname());
28 file_put_contents($FDFfile$content);
29 // Combine FDF file with the PDF form
30 exec("pdftk form.pdf fill_form $FDFfile output.pdf");
31 // blank the FDF file
32 unlink($FDFfile);

Next we will break the script in parts.
Define values to be written in the form.
Fetch all the values from the database table.
Outline a FDF record. Make a document by creating PHP’s tempnam capacity to store the FDF content.
Then access your PDFtk’s fill_form command with the help of PHP’s exec functionality. fill_form will merge your FDF file with raw PDF form.
Save the PHP file in your web root directory as pdftk.php name.

Working with Output File

It will further prevent future modifications by passing flatten message as a parameter to the fill_form command.

1 <?php
2 exec("pdftk select_exist_location/form.pdf fill_form $FDFfile output select_target_location/output.pdf flatten");

Download your Output File

Instead of storing them on the disk, it’s better to download your output file:

01 <?php
02 // ...
03 exec("pdftk select_exist_location/form.pdf fill_form $FDFfile output output.pdf flatten");
04 // Download result file in forcefully
05 header('Content-Description: Move Files');
06 header('Content-Type: application/octet-stream');
07 header('Content-Disposition: attachment; filename=' 'select_target_location/output.pdf' );
08 header('Expires: 0');
09 //define cache features
10 header('Cache-Control: must-revalidate');
11 header('Pragma: public');
12 //define filesize
13 header('Content-Length: ' filesize('output.pdf'));
14 //open pdf in read mode
15 readfile('output.pdf');
16 exit;

By running the above script in the browser, you can easily download the output file to our machine.

Create a Wrapper class

01 <?php
02 // Write in PDF form
03 $data = [
04   'employee_name' => 'Shikha',
05   'designation'  => 'Content writer',
06  ];
07 $pdf new PdfConfig('form.pdf'$data);
08 $pdf->flatten()
09   ->save('select_tartget_location/form-filled.pdf')
10   ->download();

We’ll make another record in the web root index and name it PdfConfig.php. Let’s name the class PdfConfig as well.

Class properties

01 <?php
02 class PdfConfig {
03     /*
04     * define location to PDF form as an @var string
05     */
06     private $pdfurl;
07     /*
08     * define Form data as an @var array
09     */
10     private $data;
11     /*
12     * define target location as an @var string
13     */
14     private $output;
15     /*
16     * define flag for flattening as an @var string
17     */
18     private $flatten;
19     // ...
20 }

The constructor

1 <?php
2 // ...
3 public function __construct($pdfurl$data) {
4   $this->pdfurl = $pdfurl;
5   $this->data   = $data;
6 }

The constructor will appoint the PDF path and the structure information into their properties.

How to handle various temporary files

We know that PDFtk utilizes physical records to go well with its execution process. So, there is a need to generate temporary files during this process. Below here, we will write a method to develop various temporary files:

1 <?php
2 // ...
3 private function tmpfile() {
4   return tempnam(sys_get_temp_dir(), gethostname());
5 }

Extract the form section

So, now let’s write the code to extract the form:

1 <?php
2 // ...
3 public function fields($pretty = false) {
4   $tmp $this->tmpfile();
5   exec("pdftk {$this->pdfurl} dump_data_fields > {$tmp}");
6   $con file_get_contents($tmp);
7   unlink($tmp);
8   return $pretty == true ? nl2br($con) : $con;
9 }

Create the FDF file

Let’s come to the phase where we will learn how to generate a FDF file. Let’s look at the coding part below

01 <?php
02 // ...
03 public function makeFdf($data) {
04     //define pdf version and fields
05     $fdf = '%FDF-1.2
06     1 0 obj<</FDF<< /Fields[';
07     foreach ($data as $key => $value) {
08       //add fields value
09       $fdf .= '<</T(' $key ')/V(' $value ')>>';
10     }
11     $fdf .= "] >> >>
12     endobj
13     trailer
14     <</Root 1 0 R>>
15     %%EOF";
16     $fdf_file $this->tmpfile();
17     //push all content in target file
18     file_put_contents($fdf_file$fdf);
19     return $fdf_file;
20 }

Working with the file

Set the $flatten to straighten the document that can easily be accessed by the generate() method

1 <?php
2 // ...
3 public function flatten() {
4   // define flatten function with arguments
5   $this->flatten = ' flatten';
6   return $this;
7 }

Fill out the form

1 // ...
2 private function generate() {
3   $fdf $this->makeFdf($this->data);
4   //add a temporary file in obj
5   $this->output = $this->tmpfile();
6   //execute the form process
7   exec("pdftk {$this->pdfurl} fill_form {$fdf} output {$this->output}{$this->flatten}");
8   unlink($fdf);
9 }

Save the file

Creating save method to save the file:

01 // ...
02 public function save($path = null) {
03   if (is_null($path)) {
04     // check path is existing or not
05     return $this;
06   }
07   if (!$this->output) {
08     $this->generate();
09   }
10   $dest pathinfo($path, Directory_location_info);
11   if (!file_exists($dest)) {
12     // create a directory with permission
13     mkdir($dest, 0775, true);
14   }
15   copy($this->output, $path);
16   // unlink the output obj
17   unlink($this->output);
18   $this->output = $path;
19   return $this;
20 }

Force download the file

01 // ...
02 public function download() {
03   if (!$this->output) {
04       $this->generate();
05   }
06   $filepath $this->output;
07   if (file_exists($filepath)) {
08       header('Content-Description: File Transfer');
09       header('Content-Type: application/pdf');
10       header('Content-Disposition: attachment; filename=' . uniqid(gethostname()) . '.pdf');
11       header('Expires: 0');
12       header('Cache-Control: must-revalidate');
13       header('Pragma: public');
14       header('Content-Length: ' filesize($filepath));
15       readfile($filepath);
16       exit;
17   }
18 }

Check if you have generated the file for download purpose. Send the content of the file to the output buffer by using PHP’s readfile() function.
You will now see that PdfConfig class is ready to use.

Putting the class into action

01 <?php
02 require 'PdfConfig.php';
03 $data = [
04   'employee_name' => 'Shikha',
05   'designation'  => 'Content writer',
06  ];
07 $pdf new PdfConfig('form.pdf'$data);
08 // Save output pdf file
09 $pdf->flatten()
10   ->save('output.pdf')
11   ->download();

Create FDF file

1 <?php
2 require 'PdfConfig.php';
3 $data = [
4   'employee_name' => 'Shikha',
5   'designation'  => 'Content writer',
6 ];
7 $pdf new PdfConfig('form.pdf'$data);
8 $fdf $pdf->makeFdf();

Extract PDF field information

You need to access the following code at the time of extracting your PDF field information. Let’s have a look on them:

1 <?php
2 require 'PdfConfig.php';
3 $data_fields new PdfConfig('form.pdf')->fields();
4 echo $data_fields;

We can pass this with the fields() technique, to empower a comprehensible yield structure:

1 <?php
2 require 'PdfConfig.php';
3 $pdf new PdfConfig('pdf-test.pdf')->fields(true);
4 echo $pdf;