Categories
CakePHP

Integrating dompdf with CakePHP

I was under a lot of pressure to quickly implement PDF reports in my CakePHP application. Luckily I came across this excellent tutorial.

dompdf is an HTML to PDF converter written in PHP. It is a style-driven renderer: it will download and read external stylesheets, inline style tags, and the style attributes of individual HTML elements. It also supports most presentational HTML attributes.

I am going to add some flesh to the original and give some additional information based on my implementation.

  1. Starting point:
    1. I am working on a WAMP stack
    2. I have a standard CakePHP applications set-up
    3. I have a Customer in my app (you can naturally adapt to suit)
  2. Download dompdf and place the extracted files in /app/Vendor
  3. Add the following code to /app/Config/routes.php

    Router::parseExtensions('pdf');
  4. In your controller, we have to load RequestHandler component so CakePHP can parse the .pdf extension. The post mentions adding it to AppController which makes sense but states that this is not recommended. It did not work for me, so I ended up adding it to the relevant Controllers
    class CustomersController extends AppController {
        // you may already have components in the array - just add 'RequestHandler'
        public $components = array('RequestHandler');
     
        // the rest of your code
    }
  5. Create a new folder in /app/View/Layouts called pdf
  6. Add your new Layout, default.ctp:
    <?php  
    require_once(APP . 'Vendor' . DS . 'dompdf' . DS . 'dompdf_config.inc.php'); 
    spl_autoload_register('DOMPDF_autoload'); 
    $dompdf = new DOMPDF(); 
    $dompdf->set_paper = 'A4';
    $dompdf->load_html(utf8_decode($content_for_layout), Configure::read('App.encoding'));
    $dompdf->render();
    echo $dompdf->output();
  7. Create a new action in our Customer controller. You actually don’t need to do this: if you call the methods that already exist you will get the data you want to proceed, but it does provide for better control on the output for PDF file, eg. the ability to increase the memory allocation.
    public function view_pdf() {
        // increase memory limit in PHP 
        ini_set('memory_limit', '512M');
        $this->set(compact('customers', $this->Customer->find('all')));
    }
  8. Duplicate our Customer view.ctp, rename it to view_pdf.ctp to reflect the action name, and place it in a new pdf folder in app/View/Customer.
    <?php
    echo $this->element('pdf-head');
    // NB: footer must be at the beginning of the file...
    echo $this->element('pdf-foot');
    
    // here is the body of your content as such
    echo $this->Html->tag('h2', $customer['Customer']['name']);
    
    // get all you HTML goodness in here - just make certain it is well-formed!
    // tables, in-line css - it all works
    
    echo '</body>';
    echo '</html>';
  9. Here he mentions battling with css files — I managed to get that working — more later!
  10. Create a link to your PDF:
    <?php
    // I am a big fan of opening things like this in a new tab, hence the target attribute
    echo $this->Html->link('PDF Export', array('controller' => 'customers', 'action' => 'view_pdf', 'ext' => 'pdf'), array( "class"=>"pdf_report", "target"=>"_blank" ));
    ?>
  11. To get my View code a bit more organised, I created two Elements:
    1. pdf-head.ctp
      <!DOCTYPE html>
      <html>
      <head>
      <?php
      define("APPLICATIONTIMEFORMAT", "Y-m-d");
      
      // this standard CakePHP does NOT work
      echo $this->Html->meta('icon');
      echo $this->Html->css('pdf');
      echo $this->fetch('meta');
      echo $this->fetch('css');
      ?>
      <title>stylus PDF</title>
      // but this does...
      <link rel="stylesheet" type="text/css" href="<?php echo APP.'webroot'.DS.'css'.DS.'pdf.css'; ?>" media="all" />
      </head>
      <body id="pdf">
      // your logo is in the standard CakePHP location: /app/webroot/img
      <?php echo $this->Html->image("logo.gif", array('fullBase' => true, "id"=>"logo")); ?>
    2. pdf-foot.ctp
      <div id="pdf_footer" style="A_CSS_ATTRIBUTE:all;">
          <table>
              <tr>
                  <td id="copyright">Copyright &copy; <?php echo date("Y"); ?> stylus</td>
                  <td id="printdate">Printed: <?php echo date(APPLICATIONTIMEFORMAT); ?></td>
              </tr>
          </table>
      </div>
  12. One of the issues I had was getting images into my PDF — I wanted a logo at the top right of each page. Note the fullBase attribute in my pdf-head.ctp Element! (This answer on StackOverflow nailed it for me: http://stackoverflow.com/a/29224050/4779449)
  13. Please also note the footer funkiness: the odd order of the include is required to repeat the footer content at the bottom of each page (if that is what you are after).

Thanks again to the author of the original post: http://www.syahzul.com/cakephp/how-to-generate-pdf-in-cakephp-2-x-with-dompdf/

Please note that I have already hit a short-coming of dompdf: it’s inability to handle large file sizes.

By foxbeefly

PHP / MySQL Developer

7 replies on “Integrating dompdf with CakePHP”

Hello, I am new to cakephp. in my trying to implement cakepdf am have this error:

wkhtmltopdf binary is not found or not executable: C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe

please can you help.

Take a look at https://github.com/friendsofcake/cakepdf for output pdf files. Supports multiple pdf engines (Including DomPDF), and isn’t “hacky” in the way that it outputs the pdf data. Also supports cakephp 2.x and 3.x.

Solution for your problem with DomPDF and large files is to not use DomPDF 🙂 If you use the CakePDF plugin, you can use a fantastic tool called WkHTMLToPdf (http://wkhtmltopdf.org/) which is a fantastic command line tool that uses the native webkit rendering engine to render your html into a pdf file. It is lightning quick and supports massive files (I’ve made a +100MB pdf with it before)

Hi, do you know if it’s already possible to integrate the dompdf 0.6.2 or 0.7 on cakephp 3.1 ??? Thanks.

I’m facing problems with images extensions like png. When I switched to JPG, everything seems fine.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.