Monday 23 January 2012

Generate PDF files in CakePHP using TCPDF

What is TCPDF?
TCPDF is an Open Source PHP class for generating PDF documents.

Its a best way to generate PDF in CakePHP, comparatively any other available  helper i ever used.

How to use ?
Below are the steps.

Step: 1 Download and Configure

  1. Go to http://www.tcpdf.org and download the latest version of TCPDF.
  2. Extract to one of your vendors folders, such as app/vendors. It will create a directory tcpdf there with tcpdf.php and more in it. You need at least the folders tcpdf/config and tcpdf/fonts in your application.
  3. Configure TCPDF, see its documentation. You want at least to have a look at tcpdf/config/tcpdf_config.php
Step 2: Extend TCPDF to customize your header and footer

There is a default header and footer in TCPDF, defined in a header() and a footer() method, which is supposed to be overwritten by you, if needed. This can be done by extending TCPDF and then calling this extended TCPDF class from your application.

In app/vendors create the file xtcpdf.php with this content:

  <?php

App::import('Vendor', 'tcpdf/tcpdf');

class XTCPDF extends TCPDF {

    var $xheadertext = 'Heading';
    var $xheadercolor = array(0, 0, 200);
    var $xfootertext = 'Footer';
    var $xfooterfont = 'times';
    var $xfooterfontsize = 12;

    /**
     * Overwrites the default header
     * set the text in the view using
     *    $fpdf->xheadertext = 'YOUR ORGANIZATION';
     * set the fill color in the view using
     *    $fpdf->xheadercolor = array(0,0,100); (r, g, b)
     * set the font in the view using
     *    $fpdf->setHeaderFont(array('YourFont','',fontsize));
     */
    function Header() {

        list($r, $b, $g) = $this->xheadercolor;
        $this->SetY(-290);
        $this->SetFillColor($r, $b, $g);
        $this->SetTextColor(0, 0, 0);
       $this->SetFont('times', '', 14);
       $this->writeHTMLCell(-250, '', '', '', $this->xheadertext, 0, 0, false, true, 'C');
       $this->SetY(-280);
       $this->Cell(0,8, '','T',1,'C');
    }

    /**
     * Overwrites the default footer
     * set the text in the view using
     * $fpdf->xfootertext = 'Copyright © %d YOUR ORGANIZATION. All rights reserved.';
     */
    function Footer() {
        $footertext = sprintf($this->xfootertext, $year);
        $this->SetY(-20);
        $this->SetTextColor(0, 0, 0);
        $this->SetFont($this->xfooterfont,'',$this->xfooterfontsize);
        $this->Cell(0,8, '','T',1,'C');
         $this->SetY(-18);
        // write the second column
        $this->writeHTMLCell(180, '', '', '', $this->xfootertext, 0, 0, false, true, 'C');
      }

}

?>  

   
Step 3: Create your layout for PDF

You cannot use your default layout, as it would wrap the PDF file in your HTML page code. You need a layout such as this one, save it as app/views/layouts/pdf.ctp :

<?php
header("Content-type: application/pdf");
echo $content_for_layout;
?>

Step 4: For your Controller

    function downloadPdf() {
        $this->layout = 'pdf';
       
        Configure::write('debug', 0);
        $tcpdf = new XTCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
        $some_filed = $_REQUEST['some_filed'];
        $some_filed = $_REQUEST['some_filed'];
        $some_filed = $_REQUEST['some_filed'];
        $obj = new SomeHelper();
        $Somefiled = ucwords($obj->getSomefiled($brand));
        $rowsArray = $obj->SomeFunction($some_filed, $some_filed, $some_filed);
        $this->set('tcpdf', $tcpdf);
        $this->set('some_filed', $some_filed);
        $this->set('rowsArray', $rowsArray[);
        $this->render('/reports/procurement/download_pdf');
    }
Step 5: For your View

View Template:
 

<?php
$html='';
$slno=1;
$textfont = 'times'; // looks better, finer, and more condensed than 'dejavusans'
//set margins
$tcpdf->SetMargins(PDF_MARGIN_LEFT, PDF_MARGIN_TOP, PDF_MARGIN_RIGHT);
$tcpdf->SetHeaderMargin(PDF_MARGIN_HEADER);
$tcpdf->SetFooterMargin(PDF_MARGIN_FOOTER);
//set auto page breaks
$tcpdf->SetAutoPageBreak(TRUE, PDF_MARGIN_BOTTOM);
$tcpdf->setHeaderFont(array($textfont, '', 18));
$tcpdf->xheadercolor = array(255, 255, 255);
$tcpdf->xheadertext = "<p style='text-align: center;'> <b> Header of the page </b> </p>";
$tcpdf->xfootertext = "<b><i>Copy Right Message</i></b></p>";

// add a page (required with recent versions of tcpdf)
$tcpdf->AddPage(); // Front Page

$html_1 = "<p style='text-align: center;'> $supplier </p>";

$tcpdf->SetY(-270);
$tcpdf->SetTextColor(0, 0, 0);
$tcpdf->SetFont('times', '', 12);
$tcpdf->writeHTMLCell(-250, '', '', '', $html_1, 0, 0, false, true, 'C');

$curNtDateTime = explode(' ', Date('d-m-Y H:i:s'));
$curDate = $curNtDateTime[0];
$curTime = $curNtDateTime[1];



$lefthtml = "<b>Date: </b>$curDate";

$tcpdf->SetY(-260);
$tcpdf->SetTextColor(0, 0, 0);
$tcpdf->SetFont('times', '', 12);
$tcpdf->writeHTMLCell(-250, '', '', '', $lefthtml, 0, 0, false, true, 'L');


$righthtml = "<b>Time: </b>$curTime";

$tcpdf->SetY(-260);
$tcpdf->SetTextColor(0, 0, 0);
$tcpdf->SetFont('times', '', 12);
$tcpdf->writeHTMLCell(-250, '', '', '', $righthtml, 0, 0, false, true, 'R');

$html = "<style>
    table
    {
        border-collapse:collapse;
    }
    table,th, td
    {
        border: 1px solid black;
    }
   </style>

    <table  cellspacing='0' cellpadding='20'>
        <tr>
            <td >S. No</td>
            <td >some_filed</td>
            <td >some_filed</td>
            <td >some_filed</td>
            <td >some_filed</td>
            <td >some_filed</td>
        </tr>";
foreach ($rowsArray as $row) {

    $html.= '<tr>';
    $html.= '<td>' . $slno++ . '</td><td>' . $row['some_filed'] . '</td>';
    $html.= '<td>' . $row['some_filed'] . '</td><td>' . (int) $row['some_filed'] . '</td>';
    $html.= '<td>' . $row['some_filed'] . '</td>';
    $html.= '<td>' . $row['mrp'] . '</td>';
    $html.= '</tr>';
}

$html.="</table>";


$tcpdf->setY(-240);
$tcpdf->SetTextColor(0, 0, 0);
$tcpdf->SetFont($textfont, '', 12);

// output the HTML content
$tcpdf->writeHTML($html, true, false, true, false, '');

// reset pointer to the last page
$tcpdf->lastPage();

echo $tcpdf->Output('File_Name.pdf', 'D');
?>


So is it done? 
Yeah.. Now you are done ;)
  Enjoy!!
References:
http://bakery.cakephp.org/articles/kalileo/2010/06/08/creating-pdf-files-with-cakephp-and-tcpdf

14 comments:

  1. very nice...
    I want to ask how to use background image in template without using <img src..... tag.

    ReplyDelete
  2. Rahul,

    In the above example i wrote some css in view template . So you can also write css to set the background image without using <img src....

    Example:

    body
    {
    background-image:url('gradient2.png');
    }

    For css please refer: http://www.w3schools.com/css/css_background.asp

    Regards,
    Ajit

    ReplyDelete
  3. FYI:
    Please see the very good examples placed under folder "tcpdf/examples/example_062.php".

    It will help.

    ReplyDelete
  4. Hi i am getting error , Class 'XTCPDF' not found

    ReplyDelete
  5. U have to manually create xtcpdf.php file under folder app/vendors. Follow the step: 2

    ReplyDelete
    Replies
    1. Hi, I have created it. but still same error.

      Delete
  6. i want multiple pdf files

    ReplyDelete
    Replies
    1. Will you please elaborate more.. what is the scenario you have

      Delete
  7. really helpful............ aint it supports DIV based html content???????????///

    ReplyDelete
    Replies
    1. Thanks Ashan, I haven't tried with DIV but it should.. u can also try this out and updated us here..

      Delete
    2. yeah it does support DIV but it doesn't support float and other css properties
      :(

      Delete
  8. Ajit, Can we use background image in div style of html to generate it in a pdf? I tried a lots but no luck.
    Thanks,

    ReplyDelete
    Replies
    1. Try to use like this.

      $tcpdf->Image('bg/background.jpg', 0, 0, 210, 297, '', '', '', false, 0, '', false, false, 0);
      $tcpdf->setImageScale(PDF_IMAGE_SCALE_RATIO);

      You can extend the TCPDF . There is an example on how to do this within the TCPDF examples: http://www.tcpdf.org/examples/example_051.phps

      Delete
    2. Thanks, for reply
      It sets background image for generated pdf but I need bg image as per div tag like below.
      .<div class="voucher-wrap" style="background:url(voucher-bg.jpg) repeat;"
      could it possible, I am using TCPDF class.

      Thanks

      Delete