Easy PDF Generation in PHP

by: Akash Mehta

Introduction

PDF is a popular, versatile format for storing content. PDF files can be generated once, and distributed in peace knowing that they will look the same across all platforms. They also serve as a perfect way of allowing your users to download or email a page from your website. In this tutorial, I'll show you how to generate PDF files in pure PHP and distribute your content in a single, consistent format.

Ever wanted to generate PDF files in your web application? You could let your users download pages in PDF format, generate PDF reports to be distributed in your organisation, or just get better control over how your pages look when printed. In this tutorial, we'll work through building a simple page and saving it as a PDF file.

We'll be using the FPDF library to generate our PDF files. The library is a simple PHP class that provides some very complex PDF generation functionality. Luckily, it offers some high level methods that you can use to quickly and easily generate PDF files without having to understand the internals of the PDF format.



Why would you want to generate PDFs?

When it comes to data output (not interface, output), web applications face an inherent problem: complex format and structures are very unreliable. For your complex reporting interfaces, you are faced with browser compatibility challenges, screen width issues and font size uncertainty. When it comes to demoing your latest version to your client, you may often find yourself embarassed by unforseen environment issues, and it's hard to tell a client their computer is broken.

At the same time, distributing reports - or any content, for that matter - from your web applications is also tricky. Users can try the "Save As" or "Save Page As" function in their browser, which will then attempt to calculate all the file dependencies and create an independent copy of the current page. Users will often distribute only the HTML page, losing all the CSS files and images - and with it, all hope of the end user viewing your data.

PDF as a format solves these problems wonderfully. When it comes to laying out a PDF document, you can simply assume it will look the same on your system as on the end user's. Screen resolution differences? Adobe Reader will scale beautifully. Images? SVG them and you'll have no problems; photographic data can cleanly resize. Browser versions? As long as they're all using Adobe Reader, or a reasonable alternative (such as Foxit Reader), you're fine.

Think of it like web design in a world where everyone uses Firefox.



Options for PDF Generation

In this article, we'll take a look at FPDF. However, you may have noticed a section in the PHP manual itself with PDF functions. A brief look at php.net/pdf reveals a PDFLib-based PECL extension that has not been updated in nearly six months. PDFLib itself is not free, however, and PDFLib Lite is not terribly effective. You also need access to the server to install the extension, which isn't always possible on a shared host.

There is a special section in the PHP manual on this - take a look at this FAQ entry. The two main free alternatives to FPDF are the R&OS PDF Class and phppdflib, but neither have been updated in a few years. There's also the Zend_PDF component of the Zend Framework, although it isn't very mature - still worth a look if you use the Zend Framework, however. In this time, FPDF has become the de facto standard for PDF generation in PHP. Other options exist - such as using COM to communicate with an existing Windows application with PDF export functionality - however none are as reliable and flexible as FPDF. In this tutorial, we'll be using FPDF exclusively, but the alternatives are definitely worth a look, especially their source code.



Hello World with FPDF

Let's get started with some basic PDF generation using FPDF. Load up your code editor and bash out the following:

<?php
require('fpdf.php');
$PDF = new FPDF();

$PDF->AddPage();
$PDF->SetFont('Arial', 'B', 16);
$PDF->Cell(40, 10, 'Hello World!');

$PDF->Output();

I'll explain what all this does in a moment. For now, grab the latest version of FPDF from fpdf.org, extract it to somewhere in your web server's document root and save this snippet in a PHP file under the same folder as fpdf.php. Load it up in your web browser and you should see something like this:

Nothing special, but we're on our way to PDF glory!



Examining the code

Let's take a look through that Hello World! snippet we just wrote.

<?php
require('fpdf.php');
$PDF = new FPDF();

$PDF->AddPage();
$PDF->SetFont('Arial', 'B', 16);
$PDF->Cell(40, 10, 'Hello World!');

$PDF->Output();

Barring the output, this is pretty standard stuff. Here's a quick rundown.

We start by including the FPDF library with the require('fpdf.php') line. FPDF is pure PHP: that is, no PECL extension is required. It's a little slower than PDFLib and CPDFLib, but it's infinitely more portable and much easier to use.

We create a new instance of the FPDF class in $PDF. Typically, for each PDF document you want to work with (each document can have multiple pages), you'll want to use a new object. Chances are, however, that you'll only ever need one.

This is where we launch into the actual PDF construction. We first need to create a page. That's right - you can have a PDF document with no pages. If you omit the AddPage() call and the subsequent two lines, then try it in your browser, Adobe Reader will display a blank empty page, but there really isn't one. As an example, let's take a look at what the library outputs without any pages, fonts or text cells created:

%PDF-1.3

3 0 obj

<</Type /Page

/Parent 1 0 R

/Resources 2 0 R

/Contents 4 0 R>>

endobj

4 0 obj

<</Filter /FlateDecode /Length 19>>

stream

x�3R��2�35W(�

Nothing terribly spectacular, especially consider its an empty document. However, this is a barebones PDF document, and while you may never have to actually work with this, it's important to be aware of what's happening. As this is all purely text, all the Output() method (which we'll examine in a moment) does is send a HTTP header of application/pdf and print this data to the page.

But back to our code. Here's the bulk of our PDF:

$PDF->AddPage();
$PDF->SetFont('Arial', 'I', 14);
$PDF->Cell(40, 10, 'Hello World!');

This tells FPDF to first create a page within our PDF document (it works with an internal copy while constructing your PDF), then set the font currently in use to italicised Arial at 14pt. If you don't set a font, it will default to no font and your text will not display as part of the PDF.

Finally, we create a text cell on the page, with a width of 40 and height of 10, and write the text 'Hello World!' in it. The Cell() method is the workhorse of the FPDF library. A cell is a rectangular area with optional borders, background colour and character string. Whenever you want to print text to your PDF file, chances are you'll be using the Cell() method. The method has eight arguments, even though we've only supplied three here. The others include a border option, text alignment, transparent or filled background and URL - read this manual page on the Cell method for further information.

The Output() method is especially interesting. By default it will output the PDF file as the current web page (or shell), but it can also save your newly generated PDF file to disk. To save to disk, for example, we would call the method with $PDF->Output('output.pdf', 'F'). In the first argument, we specify the file name to output (typically relative to the directory of the current script, not the FPDF library file). In the second, we specify 'F' for File, to save to a local file. Other options include sending inline to the browser (default), forcing the browser to download the file, or even simply returning the document data as a string. See this manual page for more details on the options available.



Further reading on FPDF

In this tutorial, we've put together a basic PDF file with nothing but a line of text in it. However, FPDF is capable of far more. The library has a lot of complex yet high level functionality available - you can work with headers and footers, easily handle page breaks, insert images, use multiple columns and tables, and even insert hyperlinked text.

The fpdf.org website has an excellent collection of tutorials; head over to the FPDF tutorial page and have a browse through. You'll notice that the tutorials use OOP to construct pages, defining a class that extends the core FPDF class. The library is very flexible, and works just as you'd expect any normal PHP class to - and this is where its strength lies. Experiment with the library as you read through the tutorials, and you will quickly find how easy it is to create detailed PDF files in PHP.



Article published Saturday, 1st March 2008
© 2008 NetVisits, Inc. All rights reserved.