For some applications, generating PDF file is crucial. Let’s imagine invoicing applications, created with CakePHP, generating PDF is a must. But how to do this? How to generate the file without using CLI? We will be using dompdf for this task. You can get it free and licensed under LGPL.

Make sure your meet the requirements:

  1. Using latest version of CakePHP 2.2.x
  2. Running server with PHP 5.3.x (never tested with PHP 5.2)
  3. Latest version of dompdf 0.6.0 Beta 3

Let’s get started!

Step 1

Download dompdf, extract and move the folder to our /app/Vendor. Make sure the folder name is dompdf.

dompdf folder location

Step 2

Open our /app/Config/routes.php and add the following code:

Router::parseExtensions('pdf');

Step 3

On our controller, we have to load RequestHandler component so CakePHP can parse .pdf extension.

class PostsController extends AppController {
    public $components = array('RequestHandler');

    // the rest of the codes
}

We can load it in our AppController so it will be available to other controllers as well, but it’s not recommended.

Step 4

Create new folder, pdf, in /app/View/Layouts, then create a file, default.ctp and add the following codes:

<?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();

Step 5

For better control on the output for PDF file, we will create new action in our controller.

public function view_pdf($id = null) {
    $this->Post->id = $id;
    if (!$this->Post->exists()) {
        throw new NotFoundException(__('Invalid post'));
    }
    // increase memory limit in PHP 
    ini_set('memory_limit', '512M');
    $this->set('post', $this->Post->read(null, $id));
}

By doing this, we can performs additional task for the output, for example increasing PHP memory limit, generating invoice numbers and so on.

Step 6

Duplicate our view.ctp and rename it to view_pdf.ctp to reflect our action name. You can add CSS codes inside this files since linking to external CSS files is not working for me at the moment.

Step 7

Now we can create a link to generate the PDF file using these code:

echo $this->Html->link(__('PDF'), array('action' => 'view_pdf', 'ext' => 'pdf', $post['Post']['id']));

Done!

Now you can easily generate PDF file in your CakePHP application.

Credit:

  1. http://www.dereuromark.de/2011/11/21/serving-views-as-files-in-cake2/
  2. http://stackoverflow.com/questions/8158129/loading-vendor-files-in-cakephp-2-0

  • AbdoullahTJ

    Thank you, that was very helpful ! Here, have a warm hug !

  • Jacob

    Very cool, but 1 question about a weird situation I’m seeing.

    I have to have both app/view/Posts/view_pdf.ctp AND app/view/Posts/pdf/view_pdf.ctp, with the same content in each, or I get an internal server error. Any idea what’s going on with that?

  • lahbabi imane

    very helpful thanks

  • Pingback: max()

  • Murugan Vellaisamy

    Thank u.. Very clear Tutorial….

  • David Fox

    Thanks for a brilliant tutorial!

    I managed to get external CSS includes to work. My css file is: /app/webroot/css/pdf.css

    I have a pdf-head.ctp Element with the following in it:

    <link rel="stylesheet" type="text/css" href="” media=”all” />

    I could NOT get the CakePHP way of doing it to work:

    Html->css(‘pdf’);
    echo $this->fetch(‘css’);

  • Pingback: Integrating dompdf with CakePHP | stylus()

  • Zuraidi Ismail

    salam tuan, macanama nak setting landscape

    set_paper(‘A4′,’landscape’);
    $dompdf->load_html(utf8_decode($content_for_layout), Configure::read(‘App.encoding’));
    $dompdf->render();
    echo $dompdf->output();

    ini code di default.ctp
    setakat ni masih tak jadi

    • cuba call set_paper() sebelum render()

      $dompdf->load_html(utf8_decode($content_for_layout), Configure::read(‘App.encoding’));
      $dompdf->set_paper(‘A4′,’landscape’);
      $dompdf->render();
      echo $dompdf->output();