Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

developerWorks Community:

  • Close [x]

Understanding the Zend Framework, Part 5: Creating PDF files

Building the perfect reader

Nicholas Chase (nicholas@nicholaschase.com), Developer/Writer, Studio B
Nicholas Chase, a Studio B author, has been involved in Web site development for companies such as Lucent Technologies, Sun Microsystems, Oracle, and the Tampa Bay Buccaneers. Nick has been a high school physics teacher, a low-level radioactive waste facility manager, an online science fiction magazine editor, a multimedia engineer, and an Oracle instructor. More recently, he was the Chief Technology Officer of an interactive communications firm in Clearwater, Florida, USA, and is the author of several books on Web development, including XML Primer Plus (Sams). He's currently trying to buy a farm so he and his wife can raise alpacas and chickens. He loves to hear from readers and can be reached at: nicholas@nicholaschase.com.

Summary:  In previous parts of this "Understanding the Zend Framework" series, you created the basic application, the Chomp online feed reader, using the open source PHP Zend Framework. In this tutorial, you use the Zend Framework's PDF capabilities to generate a PDF document based on entries the user has saved.

View more content in this series

Date:  18 Jan 2011 (Published 01 Aug 2006)
Level:  Intermediate PDF:  A4 and Letter (999 KB | 35 pages)Get Adobe® Reader®

Comments:  

Creating a basic PDF

Let's start by creating a basic PDF file outside of the main application so you can see what's going on.

What is a PDF?

It's hard to spend much time on the Internet without running into a PDF document at some point. Created by Adobe Systems, the Portable Document Format (PDF) was designed to be just that: portable. PDF files can be read on any system for which the Adobe Acrobat Reader (or a reasonable facsimile) is available, and for the most part, it will look the same wherever you view it.

Interestingly, while these are not files that you typically edit, they are actually text-based, embedded binary data. For example, consider the snippet in Listing 1 of the actual PDF that you'll generate in this tutorial.


Listing 1. A sneak peek at the actual PDF
%PDF-1.4
...
1 0 obj
<<;/Type /Catalog /Version /1.4 /Pages 2 0 R >>
endobj
2 0 obj
<</Type /Pages /Kids [3 0 R ] /Count 1 >>
endobj
3 0 obj
<</Type /Page /LastModified (D:20060526190953-04'00') 
/Resources <</ProcSet [/PDF /Text ] /XObject <</X1 5 0 R >> 
/Font <</F1 6 0 R >> >>
/MediaBox [0 0 612 792 ] /Contents [4 0 R ] /Parent 2 0 R >>
endobj
4 0 obj
<</Length 134 >>
stream
q
1 0 0 1 36 684 cm
72 0 0 72 0 0 cm
/X1 Do
Q
/F1 32 Tf
0.2 g
0.9 0 0 RG
3 w
BT
138 708 Td
(Chomp! To go) Tj
ET
18 774 576 -756 re
S

endstream
endobj
5 0 obj
...

As you can see, the file specifies various objects and their attributes. Fortunately, you do not have to get into the actual details of each of these objects because the Zend_PDF component of the Zend Framework takes care of it for you. Let's see how it works.


Create the document

Start by creating a document called createPDF.php. You may find it easiest to create this file in the <ZEND_HOME>/library directory, but the actual location is not important as long as it can find the Zend class files. Add the code in Listing 2.


Listing 2. Create the document
<?php

require_once 'Zend/Pdf.php';

$pdf = new Zend_Pdf();

$pdf->save("chomp.pdf");

?>

Here you include the Zend_PDF class files and use them to create a new PDF object. Once you have the object, you are simply saving it out to an arbitrary file.

You can execute this file by typing php createPDF.php on the command line. You should see a new file in the directory called chomp.pdf, but if you try to open it, you will get an error because it has no content. Let's take care of that next.


Add a page

Each page in a PDF document is an object unto itself. You can create a page of any size, using x and y values measured in points (1/72 of an inch), or you can use one of the four predetermined sizes, as you can see in Listing 3.


Listing 3. Adding a page
<?php
require_once 'Zend/Pdf.php';

$pdf = new Zend_Pdf();
$page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_LETTER);
$pageHeight = $page->getHeight();
$pageWidth = $page->getWidth();

echo 'Height = '.$pageHeight.'\n';
echo 'Width = '.$pageWidth.'\n';

$pdf->pages[0] = ($page);

$pdf->save("chomp.pdf");

?>

Start by creating a new page as a standard letter-size page. The other choices are Zend_Pdf_Page::SIZE_LETTER_LANDSCAPE, Zend_Pdf_Page::SIZE_A4, and Zend_Pdf_Page::SIZE_A4_LANDSCAPE. Note that you can have different size pages in a single document.

Once you create the page, you can retrieve its height and width, but it still doesn't actually belong to the document. (An alternate means of creating a page, the $pdf->newPage() method, does belong to the document, and it reportedly has slightly better performance, but it creates a page that cannot be shared between documents.) To attach it to the document, you add it to the pages attribute, an array of page objects you can also manipulate like any other array.


Add an image

Start by adding an image to the document. As of this writing, the Zend Framework supports only JPEG images, but that is likely to change.

You start by creating an image object, as shown in Listing 4.


Listing 4. Adding an image
<?php
require_once 'Zend/Pdf.php';

$pdf = new Zend_Pdf();
$page = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_LETTER);
$chompImage = new Zend_Pdf_Image_JPEG::imageWithPath(
                      dirname(__FILE__) . '/chomp.jpg');

$pageHeight = $page->getHeight();
$pageWidth = $page->getWidth();
$imageHeight = 72;
$imageWidth = 72;

$topPos = $pageHeight - 36;
$leftPos = 36;
$bottomPos = $topPos - $imageHeight;
$rightPos = $leftPos + $imageWidth;

$page->drawImage($chompImage, $leftPos, $bottomPos, $rightPos, $topPos);

$pdf->pages[0] = ($page);

$pdf->save("chomp.pdf");

?>

Note: If you do not have the image extension enabled for PHP, you will get an error when you try to execute this file. To solve this problem, open your php.ini file and uncomment the line that says extension=php_gd2.dll.

Creating the actual image object is self-explanatory. You are simply loading the JPEG from a file. But from there, you have to think about positioning, which might not be entirely obvious.

A PDF document uses the same conventions as a PostScript file. That means everything is measured in "points," rather than pixels. There are 72 points to an inch, so if you want the image to be 1 inch high by 1 inch wide, you set both values to 72.

As far as the actual positioning, the origin for the coordinate system is in the bottom left-hand corner of the page. In other words, the point 0,0 corresponds to the lower left-hand corner, with coordinates going up as you get higher on the page and further to the right.

So, to place an object half an inch from the top of the page, you need to set that coordinate to the total height of the page, minus 36 points, or half an inch. Similarly, the bottom of the image will be at that point, minus the height of the image. Also, because you want it in the left-hand corner, you start with the coordinate of 36, then add the width of the image for the second coordinate.

Once you have all of that information, you can use the drawImage() method to add it to the actual page. The process of adding text is similar.


Add text

Before you can add any text to the page, you need to determine what it's going to look like. You can accomplish that through the use of styles, as shown in Listing 5.


Listing 5. Adding text
...
$topPos = $pageHeight - 36;
$leftPos = 36;
$bottomPos = $topPos - $imageHeight;
$rightPos = $leftPos + $imageWidth;

$page->drawImage($chompImage, $leftPos, $bottomPos, $rightPos, $topPos);

$style = new Zend_Pdf_Style();
$style->setLineColor(new Zend_Pdf_Color_RGB(0.9, 0, 0));
$style->setFillColor(new Zend_Pdf_Color_GrayScale(0.2));
$style->setLineWidth(3);
$style->setFont(
            new Zend_Pdf_Font::fontWithName(Zend_PDF_Font::FONT_HELVETICA_BOLD) ,32);

$page->setStyle($style);
     ->drawText('Chomp! To go', $rightPos + 32, $topPos - 48);

$pdf->pages[0] = ($page);

$pdf->save("chomp.pdf");

?>

Start by creating a style object and setting its attributes. The line color, here set as an RGB value (with the red, green, and blue values being set on a scale of zero to one), mostly applies to shapes, as you'll see in a moment. The fill color, here set as a very dark gray, also applies to shapes, but more importantly, in this case, sets the color of your text. The line width determines the width of your lines. Then you set the font and the size, in points. Fourteen standard fonts are included in PDF documents and can be referenced as Zend_PDF_Font values. They include Zend_Pdf_Font::FONT_TIMES_ROMAN, Zend_Pdf_Font::FONT_TIMES_BOLD, Zend_Pdf_Font::FONT_TIMES_ITALIC, Zend_Pdf_Font::FONT_TIMES_BOLDITALIC, the same four varieties for Helvetica and Courier, and the Symbol and Zapf Dingbats fonts.

Once you create the style, you can set it for the page. Finally, you are ready to actually add the text to the page, specifying the text itself and its position. In this case, you want the text to be half an inch to the right of the image, and two-thirds of an inch from the top of the page.


Add a shape

The final touch to your sample page is a border around the outside (see Listing 6).


Listing 6. Adding a shape
...
$style->setFont(new
 Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA_BOLD), 32);

$page->setStyle($style);
    ->drawText('Chomp! To go', $rightPos + 32, $topPos - 48);
	->drawRectangle(18, $pageHeight - 18, $pageWidth - 18, 
                           18, Zend_Pdf_Page::SHAPEDRAW_STROKE);

$pdf->pages[0] = ($page);

$pdf->save("chomp.pdf");

?>

You already set a color and width of the line that makes up the rectangle, so now you're setting the top-left and bottom-right corners to be a quarter of an inch from the edges of the page, and specifying that you want just the line, as opposed to a filled shape. You have three options: Zend_Pdf_Page::SHAPEDRAW_FILLNSTROKE, Zend_Pdf_Page::SHAPEDRAW_STROKE, and Zend_Pdf_Page::SHAPEDRAW_FILL. The first includes a line and a fill, so if you had used it here, you would've wound up with a dark gray rectangle with a red border.

Let's look at actually implementing this within the application.

2 of 9 | Previous | Next

Comments



static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Open source
ArticleID=148418
TutorialTitle=Understanding the Zend Framework, Part 5: Creating PDF files
publish-date=01182011
author1-email=nicholas@nicholaschase.com
author1-email-cc=dwxed@us.ibm.com