Aug 01 2008

Generating PDF files using CodeIgniter

by Chris

PDF files rock! Some of the programs used to view them could use some work, but the file format itself is real handy. As a programmer I have found PDF’s to be most helpful when generating reports that need to be printable. I know we are all supposed to be doing our part to make our offices “greener” and use less resources like paper. But some things just need to be printed (especially when your talking about the financial and legal industries).

When generating reports in PDF format you suddenly have a lot more control over layout and design than  you do with plain old HTML and CSS (although much progress is being made with print style sheets). You can create some really nice reports on the fly that your users can view, save for later or e-mail to their co-workers for review. In this post I will show you how I generate PDF reports using CodeIgniter.

Quick Note

There are a number of PHP libraries out there for generating PDF files (like FPDF, Panda and dompdf) but the best one I have come across is the R&OS pdf class. I was first introduced to it from the PHP Anthology first edition by Harry Fuecks. I have tried other PDF libraries (some PHP 5 specific and some not) and none of them have been able to provide me with the same control or ease of use that the R&OS class has which is why I’m using it for this tutorial.

Getting Started

Before we start, lets get everyone to the same place so you can follow along as we go. I’ve prepared a .zip file containing everything you’ll need to follow along. The archive includes CI 1.6.3 along with all the code and libraries we will discuss in this tutorial. Simply download the archive, unzip it on your web server and follow along.

I have done all the work of downloading the code library and putting the files in their right place for you, but I wanted to mention where things were for the detail oriented among you. There are 2 files that are necessary in order to use the R&OS library: class.ezpdf.php and class.pdf.php. Those two files have been placed in the application/library folder. R&OS also requires some font files in order to function and they have been placed at the root of the .zip file in a folder called fonts.

You do have to make a minor modification to the class.ezpdf.php file so that it will work properly within CI. First I renamed the file to cezpdf.php, which makes it easier to load using the CI loader. Then you have to modify the include statement on line 3 to:


include_once(APPPATH . 'libraries/class.pdf.php');

This will keep PHP from saying that it can’t find included file. Once those modifications are made the R&OS class is ready to use with CI.

In the archive, I have also made a controller called tutorial.php and a helper called pdf_helper.php both in their respective directories. With the background info. out of the way, lets get our hands dirty with a real simple example.

Hello World


function hello_world()
{
$this->load->library('cezpdf');

$this->cezpdf->ezText('Hello World', 12, array('justification' => 'center'));
$this->cezpdf->ezSetDy(-10);

$content = 'The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog.
Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs.';

$this->cezpdf->ezText($content, 10);

$this->cezpdf->ezStream();
}

The above code produces a PDF file like this.

In the above, first thing we do is load the R&OS library for use. Next we use the ezText() function to create a title for our document. This function takes the text it will display as the first argument, the size of that text and an optional array of additional configuration options. In this instance we pass along a justification option of center. That will center our title at the top of our document.

After the title we insert some extra white space using the ezSetDy() function. After the whites pace we put the rest of the content for the document in a variable called $content and add it to our document using the ezText() function again. Finally, we create our document using the ezStream() function which actually creates the document and sends it to the users which prompts them to view/download the generated PDF document.

Handling Tabular Data

When your dealing with business reports the odds are good that you will need to generate reports with tables to display tabular data. From my experience with other PDF libraries, this is not an easy task. But with the R&OS library it’s about as hard as creating an array.


function tables()
{
$this->load->library('cezpdf');

$db_data[] = array('name' => 'Jon Doe', 'phone' => '111-222-3333', 'email' => '[email protected]');
$db_data[] = array('name' => 'Jane Doe', 'phone' => '222-333-4444', 'email' => '[email protected]');
$db_data[] = array('name' => 'Jon Smith', 'phone' => '333-444-5555', 'email' => '[email protected]');

$col_names = array(
'name' => 'Name',
'phone' => 'Phone Number',
'email' => 'E-mail Address'
);

$this->cezpdf->ezTable($table_data, $col_names, 'Contact List', array('width'=>550));
$this->cezpdf->ezStream();
}

The above code should produce a PDF file like this.

In the above code I create an array of data called $db_data. I put this together so that it imitates a typical database result set because that’s usually where you will be getting your data from. Below my data array I have created a $col_names array that associates the data elements in the $db_data array with a column title for the table. This is where the R&OS gets the title to display at the top of each table column. Once I have the data and column titles I create the table by calling the ezTable() function. This function takes the data array, an associative array for column names, the title for the table and an optional array of configuration options. There are a number of options that can be configured through that last optional array, but I’m not going to go into them in this tutorial.

Headers and Footers

Most reports in a corporate setting come with some kind of standard header and/or footer. They can include anything from the date/time generated, the user who generated them, to page numbers and the like. Headers and footers are handy to have, but unfortunately there isn’t a real good way to add them to printable reports generated in HTML and CSS. There’s one more reason to use the portable document format when creating printable reports.

The process of adding headers and footers to a PDF using the R&OS library is the slightest bit complicated. There are a lot of lines of code just to accomplish it, that’s why I have created a helper file. Since the code is in a helper function, you just need load the helper and call the function whenever you need to add headers/footers to a PDF.


function prep_pdf($orientation = 'portrait')
{
$CI = & get_instance();

$CI->cezpdf->selectFont(base_url() . '/fonts');

$all = $CI->cezpdf->openObject();
$CI->cezpdf->saveState();
$CI->cezpdf->setStrokeColor(0,0,0,1);
if($orientation == 'portrait') {
$CI->cezpdf->ezSetMargins(50,70,50,50);
$CI->cezpdf->ezStartPageNumbers(500,28,8,'','{PAGENUM}',1);
$CI->cezpdf->line(20,40,578,40);
$CI->cezpdf->addText(50,32,8,'Printed on ' . date('m/d/Y h:i:s a'));
$CI->cezpdf->addText(50,22,8,'CI PDF Tutorial - http://www.christophermonnat.com');
}
else {
$CI->cezpdf->ezStartPageNumbers(750,28,8,'','{PAGENUM}',1);
$CI->cezpdf->line(20,40,800,40);
$CI->cezpdf->addText(50,32,8,'Printed on '.date('m/d/Y h:i:s a'));
$CI->cezpdf->addText(50,22,8,'CI PDF Tutorial - http://www.christophermonnat.com');
}
$CI->cezpdf->restoreState();
$CI->cezpdf->closeObject();
$CI->cezpdf->addObject($all,'all');
}

An example of how I use this helper is provided in the headers() function of the tutorial.php controller. That code produces a PDF file like this.

The above code is the prep_pdf() function located in the pdf_helper.php file. This function does all the hard work of creating a footer for my PDF reports for me. All I have to do is load the helper in my controller and call the function. Since the reports could be portrait or landscape I have also included the ability to pass the orientation to the function and the code will modify the document margins accordingly.

I’m not going to go into a lot of detail about the above code because this tutorial could become very long. But the general idea is that I’m using the R&OS library to modify the margins of the document I’m creating, add page numbers and text to the very bottom of the document. R&OS has some functions that makes this easy like ezStartPageNumbers() and line(). Once all that is done I can add any kind of content to the document back in my controller and then just call ezStream() to generate the final document.

Wrap Up

I barely scratched the surface of what you can do with the R&OS PDF library in this tutorial. I encourage you to spend some quality time with the readme.pdf documentation file that comes with the library when you download it. That file goes over all the functions and their options in great detail.

So there you have it, generating PDF files with CodeIgniter and the R&OS library. If this method doesn’t quite do it for you, there are a few helpful articles on the CodeIgniter wiki, like this one and this one, which walk you through some additional options. Whatever solution you choose I hope this tutorial has helped to introduce you to some of the options you have at your disposale for creating PDF reports with CodeIgniter.


63 Responses to Generating PDF files using CodeIgniter

  1. denDay September 9, 2008 at 1:01 am

    Hi. thanks for tutorial.
    I need Code Igniter to generate pdf invoice.

  2. donnie October 27, 2008 at 3:54 am

    in function “function tables()” there is a variable $table_data.

    Where was it come from? was it you who make mistake?

    I am using your tutorial and found nothing in pdf file when using tables(), than i change it with $db_data.

    but anyway, thx a lot for the tutorial.

  3. Chris October 27, 2008 at 9:39 am

    Donnie, your right… I should be passing $db_data instead of $table_data. I will update my code.

    Thanks!

  4. Joe November 21, 2008 at 2:18 am

    Have you had any problems with ezNewPage()? I get an error as I scroll down to the new page. Just says “An error exists on the page”. If I click OK button, I can continue and not get that error again until I regenerate the PDF.
    Great tutorial! It’s helped me tremendously.

  5. Chris November 21, 2008 at 11:35 am

    Joe: No, I haven’t experienced this problem before… and I use the ezNewPage() function extensively. That’s strange!

    The only thing I can guess is that somehow the PDF file is getting corrupted or somehow screwed up during generation. I hesitate to point the finger at your web server, but I’m not sure what else it could be. Are you using Adobe reader to view the file? If so, you might want to try a different reader and see if you get the same error message.

    Sorry I can’t be of more help… let me know if you find a resolution.

  6. Joe November 24, 2008 at 1:03 am

    Found the resolution: UPGRADE the reader!
    I upgraded to the latest Adobe and no more error.
    Thanks!

  7. 4F5 December 2, 2008 at 4:05 am

    is that posible in cezpdf if i need to insert an image?
    could you tell how? thanks before.

  8. Pingback: Tipd.com moderator discussion continues.. | Barnabas Nagy

  9. LDG January 17, 2009 at 7:57 pm

    I am using cezpdf with CI (with pdf_helper) to generate reports and works great! However I am stumped as to how to change the paper orientation to landscape. The constructor is where the orientation is set except I am not able to make any of my reports print in landscape. They always come out in portrait mode. Any help is appreciated!

  10. Chris January 18, 2009 at 12:42 pm

    LDG: If you are using my helper function that I provided above then that is where the paper orientation is being set. By Default it will be set to portrait unless you pass a different orientation to the prep_pdf() helper function.

    I have had problems with the libraries built in orientations in the past which is why I set my own margins in the helper function using the $CI->cezpdf->ezSetMargins(); function. You might be better off just setting your own margins and going on from there.

  11. LDG January 20, 2009 at 2:48 am

    Chris: Thanks for your response. I am using your helper function and am passing “landscape” for the orientation. The output prints using my landscape format but the paper orientation is still 8.5 x 11. I can’t get the paper to orient to 11 x 8.5. But if I change the default parameter in the cezpdf class to “landscape” from “portrait” then the papersize changes to 11 x 8.5. But then my “portrait” reports will not work.

    I can’t figure out how you pass the orientation parameter to the cezpdf class. I tried $CI->cezpdf(‘LETTER’,'landscape’) but this does not work. Let me know if you want me to send you my code.

  12. LDG January 21, 2009 at 2:15 am

    I got it! I knew it was a just a simple thing I was missing!

    after getting the CI instance,

    $CI->cezpdf->cezpdf($paper,$orientation);

    I changed your pdf helper to also pass the paper-size so I can control both parameters.

  13. ashok March 3, 2009 at 7:15 am

    Hi,

    I need one help, My requirement to to create PDF file with lots of images. I read the document of R&OS PDF, and found that it only add the image with the type jpeg and png to the document.

    Is there any work around to include gif images in the pdfs.
    Advise me is there any good pdf class available apart from R&OS PDF.

    Thanks in advance

  14. Chris March 3, 2009 at 10:41 am

    Hi ashok, there are plenty of alternatives to the R&OS class and I mentioned some of them in the post under Quick Note near the beginning. Please refer there for more information.

  15. daniel March 25, 2009 at 12:01 pm

    Looks nice, but your archive doesn’t contain the aformentioned readme.pdf and I can’t find it anywhere on your site…

  16. Chris March 25, 2009 at 1:36 pm

    Hi daniel, the readme.pdf file comes with the R&OS PDF class. When you download and extract the code library there should be a readme.pdf file along with them. That’s the file I’m referring to.

  17. Html 2 pdf converter September 28, 2009 at 1:08 pm

    Thank you for sharing these services

  18. Strony internetowe November 11, 2009 at 6:13 pm

    Very usefull tutorial. Thanks.

  19. Jan Cornelissen November 23, 2009 at 6:39 pm

    For some strange reason I keep getting a lot of errors like these:
    A PHP Error was encountered

    Severity: Notice

    Message: Undefined index:

    Filename: libraries/class.pdf.php

    Line Number: 1935

    At the bottom some strange characters show op (the beginning of a pdf-file): %PDF-1.3 %âãÏÓ…
    But only with hello_world() and headers().
    When I render the tables() function, it only shows a blank PDF.

    What could this be?
    Thanks in advance.

  20. Chris November 25, 2009 at 11:13 am

    Hi Jan, that’s pretty odd. If I were you I would be checking versions of PHP and such to make sure the PDF library can run in your environment. I find that server incompatibility can cause odd results like the one you are seeing.

  21. zeally7 January 3, 2010 at 9:27 am

    Thank you for a nice post, I’ve tried it and I think that it suits my requirement.

  22. Fran García January 21, 2010 at 7:17 am

    Very nice and easy to use tutorial. I’m going to use this solution.

  23. Jeff January 31, 2010 at 9:01 pm

    How do you add images? I tried $this->cezpdf($img); text renders but no image. I’ve tried both relative and full paths to the image. No luck. Any ideas? Thanks in advance.

  24. Jeff January 31, 2010 at 9:03 pm

    CORRECTION TO LAST: $this->cezpdf->ezImage($img); But still no image?

  25. piyush February 4, 2010 at 1:17 pm

    Hi,
    i liked this library very much and want to integrate it in my application but i am also getting the same kind of errors mentioned by Jan Cornelissen :

    A PHP Error was encountered
    Severity: Notice
    Message: Undefined index:
    Filename: libraries/class.pdf.php
    Line Number: 1934(also getting the same error on different lines as well)

    The code in downloaded archives is working fine, but if i put the same files in my own application then it is showing many errors with message : undefined index

    what i did is :-
    1. copied the files from download archived controller,library folder to my application’s folder, and also copied the fonts from your folder to mine.

    please tell me the way to remove these errors

    Thanks
    Piyush

  26. piyush February 4, 2010 at 4:39 pm

    Hi, problem is fixed by just placing the font folder on the root location.
    earlier i was putting the font folder inside the applications folder,

  27. Pingback: DevSnippets.com: Getting Started with CodeIgniter and How to Create All Those Great Apps | Webs Developer

  28. Pingback: Getting Started with CodeIgniter and How to Create All Those Great Apps « Web Development News

  29. koki March 14, 2010 at 11:56 pm

    Is it possible to open the pdf document in another window or another tab instead of opening the pdf document in same window?

  30. Chris March 15, 2010 at 10:03 am

    koki, this really depends on how you create the PDF. The easy way is to just set the target on the link that triggers the PDF code to _blank which will open it in another window. Problem with that is most people can’t or won’t be viewing the PDF in their browser. Most of the time it will be downloaded to their computer (by default) and opened locally, in that case the new window really doesn’t make much sense because it will just be an empty new window.

  31. hus March 29, 2010 at 9:26 pm

    when i use this class to insert an image..
    it will show errors in infinite loop..the same thing was experienced by other people like they said in code igniter forum..
    is this problem solved??

  32. Chris March 30, 2010 at 8:50 am

    hus, I’m not familiar with this issue. Because this is an older library without a lot of support anymore, you may want to investigate some other options like FPDF. A number of options are mentioned in the form thread you mention.

  33. Saad Ibrahim April 2, 2010 at 1:33 pm

    @Chris is there any way to store the file on server and get the url? i want to save it to database

  34. Chris April 3, 2010 at 9:55 am

    Saad, that’s a good question. I’m not sure there is a way to do this with the R&OS library. The only PDF generation I’ve done has been sent to the browser for the user to save to their computer. You might be able to do some tweaking to the library, store the PDF in a variable and then create a file on the server with the contents of that variable. But that’s just a guess, I’ve never tried this before.

    Out of curiosity, why would you need to do this? The nice thing with being able to generate PDFs on the fly is never having to create and store them indefinitely. You simply need to keep the data handy in a database and then just generate the PDF whenever the user requests to view/download it.

  35. jagocoding April 17, 2010 at 2:00 pm

    nice…
    terimakasih banyak

  36. Pingback: CodeIgniter : miniguida e risorse per questo ottimo Framework PHP | Pecciola

  37. Pingback: Getting Started with CodeIgniter and How to Create All Those Great Apps | PHP Lovers

  38. Fernando June 23, 2010 at 2:22 pm

    I can’t put the image can somebody help me???

  39. mine July 6, 2010 at 2:13 am

    hi, sir i am working in codeigniter, i want to display record in pdf format. i am creating the same directory structure as you created in the .zip folder, place the file with same name as you placed in the .zip folder. than i am trying to run the tutorial.php file in the controls but there is no result display and some message of undefined variables are displayed from the file class.pdf.php on line no nears 1960 and 1024 etc. please guide me the starch(start to end). thanks

  40. Jonathan Gravois August 20, 2010 at 10:25 am

    I reproduced your setup and instead of getting the test .pdf, I get the output below. I think I missed a step. Any Help???

    %PDF-1.3 %âãÏÓ 1 0 obj <> endobj 2 0 obj <> endobj 3 0 obj << /Type /Pages /Kids [6 0 R ] /Count 1 /Resources << /ProcSet 4 0 R /Font <> >> /MediaBox [0.000 0.000 595.280 841.890] >> endobj 4 0 obj [/PDF /Text ] endobj 5 0 obj <> endobj 6 0 obj <> endobj 7 0 obj <> stream xœm޽nÂ0Eç”õîØJÑW¨VÔ¢ ©›ÕÎ&v’&&vC~ž¾ua¿çœ»Ø ,9′¾J‘lRbq ¡ð²‹/‰AäÀÓ‡6ÆâÛ:£ž!*¼‹EÀVŒcHNë׊Ý(QjœºŸ¬Žpp¶oÛUwl=ìY;H9P¶ ¼í=rc³‡}©|Š/ÈaLh]Ø<ÞIó5¥›;é‡}×ÔÅ…/œÌ´šÕó… 7­'le¯<*[D!n†­t¿S„³ЌǶôtmþÆTJ endstream endobj 8 0 obj <> endobj xref 0 9 0000000000 65535 f 0000000015 00000 n 0000000080 00000 n 0000000126 00000 n 0000000280 00000 n 0000000309 00000 n 0000000414 00000 n 0000000477 00000 n 0000000759 00000 n trailer <> startxref 866 %%EOF “

  41. wesam azmy August 30, 2010 at 4:07 am

    hi, can someone help me!!
    I need to use cezpdf for reports contains Arabic characters like ‘مرحبا’

  42. wesam azmy August 30, 2010 at 4:09 am

    for Jonathan Gravois
    I think you don’t select a font or the selected font file does not exist

  43. xeon September 1, 2010 at 1:51 am

    Hi,

    I wasn’t able to find the section regarding how to add gif images in the pdf (in the readme.pdf).
    How can I do this?

    I also want to display images inside a table. I used:

    $db_data[] = array(‘first’ => $pdf->ezImage(‘dummyimg.jpg’, 5, 100, ‘none’, ‘left’ ), ‘second’ => ‘ ‘);

    but the image will be displayed outside the table. Anyone help?

  44. Nils December 4, 2010 at 6:18 pm

    Hey Chris,

    I picked up this blog just today and I really like how you combined pdf-exports to CodeIgniter. However, I did find a minor error in your zipped archive. It is in the controller called tutorial.php, on line 51:

    where you wrote:
    $this->cezpdf->ezTable($dbtable_data, $col_names, ‘Contact List’, array(‘width’=>550));

    it should say:
    $this->cezpdf->ezTable($db_data, $col_names, ‘Contact List’, array(‘width’=>550));

    Thanks again for a great, well-written tutorial :)

    Nils.

  45. Luciano December 14, 2010 at 4:21 am

    For those about to have UNDEFINED INDEX error:

    piyush says:
    February 4, 2010 at 4:39 pm
    Hi, problem is fixed by just placing the font folder on the root location.
    earlier i was putting the font folder inside the applications folder,

  46. Donkey January 27, 2011 at 11:44 am

    FPDF is much more easy!

  47. Ali January 29, 2011 at 5:03 am

    Great Work …. Make me alot easier to do that :)
    Thanks again!

  48. Billy January 31, 2011 at 8:07 am

    Hi Chris,

    I’d also like to save the pdf. In my project I’m creating a pdf on the fly from db data then sending it as an attachment in an email. Have you any idea of the best way to do this?

  49. Chris January 31, 2011 at 10:31 am

    Billy, I’m not sure about this one. You might be better off looking at a newer library to accomplish this as R&OS is getting a little dated.

  50. Mazhar June 25, 2011 at 8:51 pm

    How to change the filename of the pdf?

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>