Creating PDF documents with ZF2 and DomPdf
Introduction
Creating documents in PDF format has long been a requirement for business management systems. Common documents are invoices, certificates and reports which are exchanged between users due to their compatibility with other operating systems. If you happen to be building a ZF2 application for an organisation, chances are they will want some form PDF document generation. In this post, we will be creating PDF documents that can be saved by the user. To follow this guide, I assume you will be using ZendSkeletonApplication which is hosted here.
ZendPdf or DomPdf?
While briefly researching this topic, I came across two libraries that we could use; ZendPdf and DomPdf. ZendPdf is a library from the first Zend Framework. PDFs are made by creating a blank page canvas and using numerous methods such as “drawCircle” and “drawText” with the aid of coordinate values to draw content onto it. In my opinion, using coordinates to draw onto a canvas is quite cumbersome and time consuming to get right, especially if you’re creating an invoice with dynamic content.
The beauty of DomPdf on the other hand is in its name. With its (mostly) CSS 2.1 compliant and HTML layout PHP rendering engine, DomPdf is the perfect solution for creating the initial PDF in HTML and CSS before being saved to PDF. Documents are rendered using PHP’s DOM and GD extensions.
Installing DomPdf for ZF2
DomPdf is free to download as it’s open source. In its current form, it can be added to projects that don’t use a framework by simply placing includes in your code. For ZF2 implementation, a developer called Raymond Kolbe has kindly developed a Zend “friendly” module for it. Here is the Github for the project.
For this demonstration, we will be installing the DomPdf module using Composer. You will have most likely started your ZF2 project using Composer to download the ZF2 source code. Simply open your “composer.json” file located at the root of your application and add the following line:
"require": { "php": ">=5.3.3", "zendframework/zendframework": "2.3.*", "dino/dompdf-module": "dev-master" }
Next, open a terminal or command prompt window (depending on your system) and browse to the root of the application. Enter this command:
php composer.phar update
This will download the libraries you have listed under the “required” key in composer.json. You can confirm if DomPdf downloaded successfully by checking if its folders are under the “vendor” folder like so:
To use the DomPdf module, we need to add it to our modules configuration which can be found here:
config/application.config.php
Add the “DOMPDFModule” to the array list under the “modules” key like this:
'modules' => array( 'Application', 'DOMPDFModule' ),
Creating our files
Our application can now locate and instantiate the DOMPDFModule module via namespace. To see our Pdf generator in action, we will create a new route, a new controller and view. Add this route to the Application module config/module.config.php file:
'pdf' => array( 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => array( 'route' => '/pdf', 'defaults' => array( 'controller' => 'Application\Controller\Pdf', 'action' => 'index', ), ), ),
In the same file, we need to define our new controller called “PdfController” like so:
'controllers' => array( 'invokables' => array( 'Application\Controller\Index' => 'Application\Controller\IndexController', 'Application\Controller\Pdf' => 'Application\Controller\PdfController' ), ),
With our configuration now done, we need to create the files and paths for our controller and its view. Create the following directories and files:
module/Application/src/Application/Controller/PdfController.php
module/Application/view/application/pdf/index.phtml
Use this code for the PdfController.php file:
namespace Application\Controller; use Zend\Mvc\Controller\AbstractActionController; use DOMPDFModule\View\Model\PdfModel; class PdfController extends AbstractActionController { public function indexAction() { // Instantiate new PDF Model $pdf = new PdfModel(); // set filename $pdf->setOption('filename', 'hello.pdf'); // Defaults to "8x11" $pdf->setOption('paperSize', 'a4'); // paper orientation $pdf->setOption('paperOrientation', 'portrait'); $pdf->setVariables(array( 'var1' => 'Liverpool FC', 'var2' => 'Atletico Madrid', 'var3' => 'Borussia Dortmund' )); return $pdf; } }
And this for the view:
<style> body { font-family: Arial, sans-serif; } .container { width:573px; margin: auto; padding: 10px; border:1px solid #000; } </style> <div class="container"> <h1>I am a PDF!</h1> <p><?php echo $this->var1 ?></p> <p><?php echo $this->var2 ?></p> <p><?php echo $this->var3 ?></p> </div>
Now that everything is in place, we can test our code by simply calling the URL: http://localhost/pdf. Loading this address in your browser will trigger the following processes:
- The /pdf url will get matched against our “pdf” route defined in the config.
- The matched route will then instruct the ZF2 app to instantiate our PdfController and call the indexAction method.
- The action will create an instance of the PdfModel (which actually extends the ZF2 ViewModel class) and set some options such as variables and page orientation.
- The PdfModel is then returned which triggers the rendering process of matching our controller and action names to our view/application/pdf/index.phtml file.
If everything went well, you should have received a prompt from your browser asking if you would like to save the PDF file.
Further consideration
I have only shown the basics of what this module has to offer. You can find a whole lot more by just having a look at the code within the DOMPDFModule. I highly recommend taking a look at the module’s config file in vendor/dino/dompdf-module/config/module.config.php. You can overwrite the values within this array by simply copying the structure and adding your edits to the Application module config.