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:
sudo apt-get install pdftk
To check if it works, we can run the following command:
pdftk --version
The output should be similar to:
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
%FDF-1.2 1 0 obj<</FDF<< /Fields[
Content section
// Define all elments that you want to show in PDF
<< /T (employee_name) /V (Shikha) << /T (designation) /V (Content Writer)
Footer section
// Mention end process of PDF
] >> >> endobj trailer <</Root 1 0 R>> %%EOF
Next your element’s value is prefixed with /V that signifies a value shown below:
<< /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:
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:
-- FieldType: Text FieldName: employee_name FieldFlags: 0 FieldJustification: Left --- FieldType: Text FieldName: designation FieldFlags: 0 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:
<?php // Form data: $ename = 'Shikha'; $desg = 'Content Writer; // FDF header section $fdf_header = <<<FDF %FDF-1.2 // define form %,,oe" 1 0 obj << /FDF << /Fields [ // define form fields FDF; // FDF footer section $fdf_footer = <<<FDF // define end of file process "] >> >> endobj trailer <</Root 1 0 R>> %%EOF; FDF; // define content that will be show in PDF $fdf_content = "<</T(employee_name)/V({$ename})>>"; $fdf_content .= "<</T(designation)/V({$desg})>>"; // Combine header, content and footer section $content = $fdf_header . $fdf_content , $fdf_footer; // Develop a temporary file that will be use for FDF file. $FDFfile = tempnam(sys_get_temp_dir(), gethostname()); file_put_contents($FDFfile, $content); // Combine FDF file with the PDF form exec("pdftk form.pdf fill_form $FDFfile output.pdf"); // blank the FDF file 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.
<?php 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:
<?php // ... exec("pdftk select_exist_location/form.pdf fill_form $FDFfile output output.pdf flatten"); // Download result file in forcefully header('Content-Description: Move Files'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename=' . 'select_target_location/output.pdf' ); header('Expires: 0'); //define cache features header('Cache-Control: must-revalidate'); header('Pragma: public'); //define filesize header('Content-Length: ' . filesize('output.pdf')); //open pdf in read mode readfile('output.pdf'); exit;
By running the above script in the browser, you can easily download the output file to our machine.
Create a Wrapper class
<?php // Write in PDF form $data = [ 'employee_name' => 'Shikha', 'designation' => 'Content writer', ]; $pdf = new PdfConfig('form.pdf', $data); $pdf->flatten() ->save('select_tartget_location/form-filled.pdf') ->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
<?php class PdfConfig { /* * define location to PDF form as an @var string */ private $pdfurl; /* * define Form data as an @var array */ private $data; /* * define target location as an @var string */ private $output; /* * define flag for flattening as an @var string */ private $flatten; // ... }
The constructor
<?php // ... public function __construct($pdfurl, $data) { $this->pdfurl = $pdfurl; $this->data = $data; }
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:
<?php // ... private function tmpfile() { return tempnam(sys_get_temp_dir(), gethostname()); }
Extract the form section
So, now let’s write the code to extract the form:
<?php // ... public function fields($pretty = false) { $tmp = $this->tmpfile(); exec("pdftk {$this->pdfurl} dump_data_fields > {$tmp}"); $con = file_get_contents($tmp); unlink($tmp); return $pretty == true ? nl2br($con) : $con; }
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
<?php // ... public function makeFdf($data) { //define pdf version and fields $fdf = '%FDF-1.2 1 0 obj<</FDF<< /Fields['; foreach ($data as $key => $value) { //add fields value $fdf .= '<</T(' . $key . ')/V(' . $value . ')>>'; } $fdf .= "] >> >> endobj trailer <</Root 1 0 R>> %%EOF"; $fdf_file = $this->tmpfile(); //push all content in target file file_put_contents($fdf_file, $fdf); return $fdf_file; }
Working with the file
Set the $flatten to straighten the document that can easily be accessed by the generate() method
<?php // ... public function flatten() { // define flatten function with arguments $this->flatten = ' flatten'; return $this; }
Fill out the form
// ... private function generate() { $fdf = $this->makeFdf($this->data); //add a temporary file in obj $this->output = $this->tmpfile(); //execute the form process exec("pdftk {$this->pdfurl} fill_form {$fdf} output {$this->output}{$this->flatten}"); unlink($fdf); }
Save the file
Creating save method to save the file:
// ... public function save($path = null) { if (is_null($path)) { // check path is existing or not return $this; } if (!$this->output) { $this->generate(); } $dest = pathinfo($path, Directory_location_info); if (!file_exists($dest)) { // create a directory with permission mkdir($dest, 0775, true); } copy($this->output, $path); // unlink the output obj unlink($this->output); $this->output = $path; return $this; }
Force download the file
// ... public function download() { if (!$this->output) { $this->generate(); } $filepath = $this->output; if (file_exists($filepath)) { header('Content-Description: File Transfer'); header('Content-Type: application/pdf'); header('Content-Disposition: attachment; filename=' . uniqid(gethostname()) . '.pdf'); header('Expires: 0'); header('Cache-Control: must-revalidate'); header('Pragma: public'); header('Content-Length: ' . filesize($filepath)); readfile($filepath); exit; } }
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
<?php require 'PdfConfig.php'; $data = [ 'employee_name' => 'Shikha', 'designation' => 'Content writer', ]; $pdf = new PdfConfig('form.pdf', $data); // Save output pdf file $pdf->flatten() ->save('output.pdf') ->download();
Create FDF file
<?php require 'PdfConfig.php'; $data = [ 'employee_name' => 'Shikha', 'designation' => 'Content writer', ]; $pdf = new PdfConfig('form.pdf', $data); $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:
<?php require 'PdfConfig.php'; $data_fields = new PdfConfig('form.pdf')->fields(); echo $data_fields;
We can pass this with the fields() technique, to empower a comprehensible yield structure:
<?php require 'PdfConfig.php'; $pdf = new PdfConfig('pdf-test.pdf')->fields(true); echo $pdf;