March 15, 2010

Using Fpdf library with Codeigniter

I am back with codeigniter! Now I have to use pdf generation for reporting purpose. Previously I have used Dom Pdf library with Codeigniter. For paper size and some other issues I got help form Sajjad Vai's blog. It worked nicely and my primary purpose was solved. But unfortunately it was not working for large amount of data which is being pulled from multiple table. Say for example, if I try with sample populated data with 180 rows it works fine, but for 35 rows fetched with my reporting query it messes things up! May be my query needs  some scaling. But as we are on verge of delivery, the team decides to complete the task first and then think on the scaling issue as we have separate planning for that. So My manager did some R&D and found Fpdf runs well with larger dataset. Now as out project is on Caodeigniter framework, I am trying to implement this on Codeignter. I am tracking down the steps as this is new to me and this may help for future cases.


1) Download the latest stable version of Fpdf library from here. We are using fpdf1.6 here.

2) Extract the zip file and put it folder named fpdf and Copy that to "system/plugins" folder.

3) Copy the file "tutorial/tut5.php" [as we are talking about huge amount of data and data may exceed single page, this may vary from requirement to requirement] to plugins folder and rename it to "fpdf_pi.php".

4) Open the file and change the line
require('../fpdf.php');
to
require('fpdf/fpdf.php');

5) There are many examples in the "tutorial" folder depicting many features like tables, fancy tables, paginations, etc. So you can cutomize the class and the functions as your application requires. Like in our application, we have modified the header and footer functions and customized the pagination by putting the table header into every page front. The basic principle on which FPDF works is they consider every element into cells. And the properties of the cells has to be fixed to get a visually better output.

6) Now at the end of the class there are some codes to call and manipulate the class and gets output. pdf. Just copy the class and put in the required controller function where the data will be fed to it.

7) Now in the controller replace the "include" line before
$pdf = new PDF();
with the following
$this->load->plugin('fpdf');


8) Here we are trying to printing an tour pan of a tourism company. We will change the header in the controller now where the header() is called as

          $header = array('start','Name','end','stay','Id','where');

9) There is a way of loading data in to system is
$data=$pdf->LoadData('countries.txt');
as mentioned in the tutorial. We are overloading this line with sample data reading the format of the 'countries.txt'.

So our code becomes --
$data = array(
                   array('Austria','Vienna','83859','8075'),
                   array('Belgium','Brussels','30518','10192'),
                   array('Denmark','Copenhagen','43094','5295'),
                   array('Finland','Helsinki','304529','5147'),
                   array('France','Paris','543965','58728'),
                   array('Germany','Berlin','357022','82057')
     );

10) We have customized two functions called "SetReportFirstPageHead" and "SetReportGeneralPageHead". The first one is for setting the first page because while printing there will be letterhead and then the data table. but in the other pages there will be only datatable header.

the skeletons of the functions to be resided in the fpdf_pi.php are as follows :

function SetReportFirstPageHead($report_name, $print_date, $optional_text = '')
{
      $this->Image('logo.png',20,13,60,0,''); 
      $this->SetFont('Arial','',15);
      $this->Cell(170,10,'abc tourism,','',0,'R');
      $this->Ln(7);
      $this->SetFont('Arial','',12);
      $this->Cell(170,10,'address 1,','',0,'R');
      $this->Ln(5);
      $this->Cell(170,10,'address 2,','',0,'R');
      $this->Ln(5);
      $this->Cell(170,10,'address 3 ','',0,'R');
      $this->Ln(7);
      $this->SetFont('Arial','',10);
      $this->Cell(170,10,'phone','',0,'R');
      $this->Ln(5);
      $this->Cell(170,10,'mail','',0,'R');
      $this->Line(20, 48, 190, 48);
      $this->Ln(9);

      $this->SetFont('Arial','',12);
      $this->Cell(140,8,$report_name,'',0,'L');
      $this->SetFont('Arial','',10);
      $this->Cell(30,9, "Printed On: ".$print_date,'',0,'R');

      $this->Line(20, 55, 190, 55);

      if ($optional_text != '')
      {
        $this->Ln(10);
        $this->WriteHTML($optional_text);
        $this->Ln(15);
      }
      else 
      {
        $this->Ln(15);
      }
}


function SetReportGeneralPageHead($report_name, $print_date)
{
       $this->SetFont('Arial','',11);
       $this->Cell(140,8,$report_name,'',0,'L');
       $this->SetFont('Arial','',9);
       $this->Cell(30,9,$print_date,'',0,'R');
       $this->Line(20, 20, 190, 20);

       $this->Ln(15);
}

11) Now at the controller, we are calling the pdf output like as follows:

function pdfTest()
{
      $this->load->plugin('fpdf');
      $pdf = new PDF();

      $header = array('start','Name','end','stay','Id','where');
      
      $data = array(
                     array('Austria','Vienna','83859','8075'),
                     array('Belgium','Brussels','30518','10192'),
                     array('Denmark','Copenhagen','43094','5295'),
                     array('Finland','Helsinki','304529','5147'),
                     array('France','Paris','543965','58728'),
                     array('Germany','Berlin','357022','82057')
                    );

      //First page
      $pdf->AddPage();
      $pdf->SetLeftMargin(20);
      $pdf->SetReportFirstPageHead('Tour Plan', date('F j, Y'), 'Start Date : 03-01-2010 End Date : 04-30-2010');
        $pdf->FancyTable($header, $pdf->SplitInPages($data, 0, 30));

      //other pages
      $len = count($data);
      for ($k=30; $k <= $len; $k+=40)         
{             
$pdf->AddPage();
         $pdf->SetReportGeneralPageHead('Tour Plan', date('F j, Y'));
         $pdf->FancyTable($header,$pdf->SplitInPages($data, $k, 40));
      }

      $pdf->Output();
}


So the final out put is here after running the function. The pdf looks like the following screenshot----







Bye for now.
stay tuned :)

25 comments:

  1. nice article. i was used ezpdf class in php a long days ago. if i use Codeigniter and do pdf generator related work,obviously i will follow this article.

    ReplyDelete
  2. thanks a lot! please share what you have done with ezPDF

    ReplyDelete
  3. can you explain detail start in step no 7??

    ReplyDelete
  4. @anonymous,
    yes of course. in the downloaded project file there is a line to include the fpdf file just before the line
    $pdf = new PDF();
    in CI include is not standard or supported from controller. As we have place fpdf as a plugin we called it by loading. so the rest of the code where object of fpdf is called can be of use.

    I think this is detail enough.
    thanks.

    ReplyDelete
  5. Hi!,
    I'm trying your code but I have the following errors:
    - SplitInPages is not defined.
    - WriteHTML is not defined.

    And its true. I cant find those methods anywhere.
    What can I do?

    ReplyDelete
  6. Message: file(countries.txt) [function.file]: failed to open stream: No such file or directory

    Filename: plugins/fpdf_pi.php

    ReplyDelete
  7. @Anonymous (September 3, 2010 12:33 PM),
    Have you configured to use the library as plugin rightly? I have stated in steps (1), (2), (3) and (4) how to do that. By the way I have used CodeIgniter 1.7.2. So there can be change in the way how to configure that. In that case you can see the changelog!

    happy coding!

    ReplyDelete
  8. Hi!,
    I'm trying your code but I have the following errors:
    - SplitInPages is not defined.
    - WriteHTML is not defined.

    And its true. I cant find those methods anywhere.
    What can I do?

    ReplyDelete
  9. @Deva Rizal Y,
    Sorry for replying you late. This methods are custom defined. And the names are self explanatory. Now if you concentrate on the rest and just define the methods blank and use my codes the code will still work .... they are for presentation purpose actually. I will edit my code ASAP to remove confusion but for the meantime ... without them the code will work fine.

    ReplyDelete
  10. Hi, I'm lixchan.

    I've been looking around for scripts like this to create an application that I developed. and finally I get this script

    but I'm still confused with FancyTable function. in the original script (tutorial/tut5.php), this function is placed in one page (or files) with other functions and its output FPDF.

    in the script that you created, where you put the function FancyTable? whether in helpers, library or plugin?

    Thanx...

    ReplyDelete
  11. hi lixchan,
    Actually i have put the "FancyTable' method in the same file i.e. tut5.php file so that I can call it with single calling to the fpdf object!

    Hopt this tiny info help you!

    ReplyDelete
  12. thanks for the explanation,,

    so,, you put the "FancyTable" function together with "SetReportFirstPage Head" function in the plugin "fpdf_pi.php", right?

    if I use the method "table with multicell" (author by Oliver, in the example script FPDF), then the functions to create tables (i.e.SetWidths, SetAligns, Row, CheckPageBreak, NbLines), must be placed in the file "fpdf_pi.php", right?

    sorry if I ask too many questions ... ^^'
    I often use PHP and FPDF, but I'm not familiar with codeiginiter. This makes me really confused. ~_~


    Regards
    lixchan

    ReplyDelete
  13. Hi, just want to ask where to put the image file, is it in the same directory as the fpdf_pi.php file?
    Because I got an error :
    FPDF error: Missing or incorrect image file: serba.jpg
    thanks
    - ana

    ReplyDelete
  14. Hi ana,
    I think yes the image should be in the same directory!


    thanks,
    Himel Nag Rana.

    ReplyDelete
  15. Yes, I already put the image in the same directory, but still there's php error like below :
    -------------------------------------------------------------------
    A PHP Error was encountered

    Severity: Warning

    Message: getimagesize(serba.jpg) [function.getimagesize]: failed to open stream: No such file or directory

    Filename: fpdf/fpdf.php

    Line Number: 1202
    ---------------------------------------

    Do you have any idea what's the problem? It's like php can't find the image :(

    thanks a bunch ^_^
    -ana

    ReplyDelete
  16. Hi ana,
    I am little bit confused about the problem -- I will inform you after checking my codes --- hope that may help you!

    let's see.

    regards,
    Himel Nag Rana

    ReplyDelete
  17. Hi ana,,
    I'm lixchan. I had I had a problem like that too.The trouble is in the image file size that you wear.
    when I use the image file size 10 KB, error messages appear :
    Message: getimagesize(image.jpg) [function.getimagesize]: failed to open stream: No such file or directory
    But when I use a picture with a file size 100 KB, the error message is not displayed and the application can run.
    In FPDF, you must use images that are larger than 25 KB.
    I hope my suggestions can help you.


    Good luck ^_^

    ReplyDelete
  18. ( ! ) Fatal error: Call to undefined method CI_Loader::plugin() in D:\wamp\www\SIinsur\application\controllers\pdf\pdf.php on line 62
    Call Stack
    # Time Memory Function Location
    1 0.0005 385880 {main}( ) ..\index.php:0
    2 0.0012 454440 require_once( 'D:\wamp\www\SIinsur\system\core\CodeIgniter.php' ) ..\index.php:201
    3 0.0232 2658200 call_user_func_array ( ) ..\CodeIgniter.php:339
    4 0.0232 2658248 pdf->pdfTest( ) ..\CodeIgniter.php:0

    ReplyDelete
  19. Call to undefined method CI_Loader::plugin()

    ReplyDelete
  20. I think this is your configuration error!
    you are calling plugin from a wrong place - please search e little but in the manual and in the CI forum.

    ReplyDelete
  21. i am getting this error, please help me to get rid of this error.
    FPDF error: Undefined font: B

    thanks

    ReplyDelete
  22. Great info, thanks for posting. If you’re looking for netsuite los angeles info then these might be the guys to help you out.

    ReplyDelete