DevZone Zend - PDF Tutorial
DevZone Zend - PDF Tutorial
Cal Evans (Editor-in-Chief) * Link http://devzone.zend.com/author/admin/* | 18 comments * Link http://devzone.zend.com/1064/zend_pdf-tutorial/#comments* | September 7th, 2007
By: Alexander Veremyev
The Zend_Pdf * Link http://framework.zend.com/manual/en/zend.pdf.html* component of the Zend Framework * Link http://framework.zend.com* is intended to allow you to create or manipulate PDF documents from within your applications. In addition to its text handling capabilities, it comes complete with drawing features that allow you to create or manipulate graphical primitives. When working with text Zend_Pdf gives you the option of using the built-in fonts or custom TrueType fonts. Its page manipulation capabilities allow you to create new pages, remove existing pages or change the order of pages already in the document. In this tutorial my goal is to give you an overview of the capabilities of Zend_Pdf.
First things first, you should make sure that you have the latest version of the Zend Framework installed and properly configured. If you are in doubt, check out the Zend Framework manual * Link http://framework.zend.com/manual/en/introduction.installation.html* for instructions. Now, lets dive right in and look at the code. If you are working in an applications written with the Zend Framework, you can use the loadClass() method to load Zend_Pdf. // Load Zend_Pdf class Zend_Loader::loadClass('Zend_Pdf'); However, if you are using Zend_Pdf standalone in your application, you can simply include it with a require_once() call: // Load Zend_Pdf class require_once('Zend/Pdf.php');
Once you have the class loaded you can create an instance. PDF document is represented by Zend_Pdf class. There are three ways to accomplish this. Create a new PDF
1 sur 16
// Create new PDF document. $pdf = new Zend_Pdf(); Load an existing document // Load PDF document from a file. $fileName = '/path/to/your/file.pdf'; $pdf = new Zend_Pdf($fileName); Create a document by parsing a string // Parse PDF document from a string. $pdf = Zend_Pdf::parse($pdfString);
Now that we have our document, we can start manipulating the pages. To access the pages of our document, we turn to the public property pages. Pages is an array of Zend_Pdf_Page objects. Because it is a native PHP array, any of PHPs array handling methods can be used to manipulate it. For instance. // Reverse document pages. $pdf->pages = array_reverse($pdf->pages); // Add new page $pdf->pages[] = new Zend_Pdf_Page(Zend_Pdf_Page::SIZE_A4); // Add new page $pdf->pages[] = $pdf->newPage(Zend_Pdf_Page::SIZE_A4); // Remove specified page. unset($pdf->pages[$id]); There are two methods that you can use to create a new page. First, you can directly instantiate a Zend_Pdf_Page object and add it to the array yourself. Second, you can use the newPage() method of Zend_Pdf object. newPage() method is a little bit faster, but needs document object. Either way, you end up with a new Zend_Pdf_Page object to work with. Both methods take page size as a parameter. Page size may be specified using one of the following Zend_Pdf_Page class constants. Zend_Pdf_Page::SIZE_A4 Zend_Pdf_Page::SIZE_A4_LANDSCAPE Zend_Pdf_Page::SIZE_LETTER Zend_Pdf_Page::SIZE_LETTER_LANDSCAPE using special pagesize name (names are case insensitive): A4 A4-Landscape Letter Letter-Landscape or using special notation: x_size:y_size: where size is given in points * Link http://en.wikipedia.org /wiki/Point_(typography)* . // Add new page (A4 size) $pdf->pages[] = $pdf->newPage('595:842:');
2 sur 16
So far you have created your document, youve added pages, youve made it pretty. Lets save it now so you can share it with others. There are three ways to save a PDF once you have created it. The easiest is to simply call the save() method. save() takes one parameter, a file name. Even if youve already saved the document once, or you loaded it form an existing document, you still have to specify the file name again. // Save document as a new file or rewrite existing document $pdf->save($fileName); The second way is to use the incremental update PDF feature. Using this, only file modifications are appended. If you want to use the incremental update feature, you pass true as the second parameter of save(). // Update existing document // (only document modifications are appended to a file) $pdf->save($fileName, true); You should be careful when using this second method. You have to use the same file name for loading and for saving the updates. Finally, prepared PDF document can be also rendered into a string. This is useful if you plan to return file through HTTP. // Create new PDF $pdf = new Zend_Pdf(); // Add new page to the document $page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4); $pdf->pages[] = $page; // Draw something on a page ... // Get PDF document as a string $pdfData = $pdf->render(); header("Content-Disposition: inline; filename=result.pdf"); header("Content-type: application/x-pdf"); echo $pdfData;
So, we have a page, but honestly, a PDF full of blank pages isnt that exciting. To use the PDF to convey ideas we need text and we need images. Lets work with Text first. For those not familiar with PDFs, everything is drawn on the page, even text. Therefore we will refer to the placing of text on the page from here on out as drawing text. Here is an example of most simple text drawing: // Create new PDF $pdf = new Zend_Pdf(); // Add new page to the document $page = $pdf->newPage(Zend_Pdf_Page::SIZE_A4); $pdf->pages[] = $page;
3 sur 16
// Set font $page->setFont(Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA), // Draw text $page->drawText('Hello world!', 100, 510); Congratulations, you have created your Hello World PDF! See, it wasnt nearly as hard as you thought it would be. Now, before we move on, there are some other things you need to know about drawing text. First, Zend_Pdf supports the 14 standard PDF fonts. Here is a list of the fonts. Zend_Pdf_Font::FONT_COURIER Zend_Pdf_Font::FONT_COURIER_BOLD Zend_Pdf_Font::FONT_COURIER_OBLIQUE (identical to Zend_Pdf_Font::FONT_COURIER_ITALIC) Zend_Pdf_Font::FONT_COURIER_BOLD_OBLIQUE (identical to Zend_Pdf_Font::FONT_COURIER_BOLD_ITALIC) Zend_Pdf_Font::FONT_HELVETICA Zend_Pdf_Font::FONT_HELVETICA_BOLD Zend_Pdf_Font::FONT_HELVETICA_OBLIQUE (identical to Zend_Pdf_Font::FONT_HELVETICA_ITALIC) Zend_Pdf_Font::FONT_HELVETICA_BOLD_OBLIQUE (identical to Zend_Pdf_Font::FONT_HELVETICA_BOLD_ITALIC) Zend_Pdf_Font::FONT_SYMBOL Zend_Pdf_Font::FONT_TIMES_ROMAN Zend_Pdf_Font::FONT_TIMES Zend_Pdf_Font::FONT_TIMES_BOLD Zend_Pdf_Font::FONT_TIMES_ITALIC Zend_Pdf_Font::FONT_ZAPFDINGBATS Second, you always have to set a font before drawing text onto the page. (always) Here is another example of the drawText() command. // Set font $page->setFont(Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA), // Draw text $page->drawText($message, 100, 510, 'UTF-8'); The second and third parameters are the drawing coordinates and are given in points starting from left bottom page corner. The forth and optional parameter of drawText() is the encoding. Each of the standard 14 fonts, with the exceptions of Symbol and ZapfDingbats, support the Latin character set which may be represented in any encoding supported by iconv library. In addition to the standard 14 fonts, Zend_Pdf also supports custom TrueType. Custom TrueType fonts may be added into your document with Zend_Pdf_Font::fontWithPath() method, like this. // Set font $page->setFont(Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::fontWithPath($fon // Draw text $page->drawText('Hello world!', $x, $y); In the example above $size is the font size to draw in. Font sizes are expressed in points.
4 sur 16
Text is great, text helps convey ideas, but you know the old saying about the worth of a picture. Lucky for us, PDF and Zend_Pdf support drawing images. Raster images are drawn on a page using special image object. JPEG (requires GD PHP extension), PNG (requires ZLIB PHP extension for images with Alpha channel) and TIFF images are supported. // Load image $image = Zend_Pdf_Image::imageWithPath($imagePath); // Draw image $page->drawImage($image, $left, $bottom, $right, $top); drawImage() takes 5 parameters, first the image represented as a Zend_Pdf_Image object. Then the four corners of the placement box represented by $left, $bottom, $right and $top.
In addition to placing raster images on the page, Zend_Pdf_Page has a number of methods for drawing common shapes Zend_Pdf_Page::drawLine() Zend_Pdf_Page::drawRectangle() Zend_Pdf_Page::drawPolygon() Zend_Pdf_Page::drawCircle() Zend_Pdf_Page::drawEllipse() See Zend_Pdf documentation * Link http://framework.zend.com/manual /en/zend.pdf.drawing.html#zend.pdf.drawing.shape-drawing* for more details. Lets take a look at sample code to draw a few shapes. // Draw rectangle $page->setFillColor(new Zend_Pdf_Color_GrayScale(0.8)); $page->setLineColor(new Zend_Pdf_Color_GrayScale(0.2)); $page->setLineDashingPattern(array(3, 2, 3, 4), 1.6); $page->drawRectangle(60, 400, 400, 350); // Draw circle $page->setLineDashingPattern(Zend_Pdf_Page::LINE_DASHING_SOLID); $page->setFillColor(new Zend_Pdf_Color_Rgb(1, 0, 0)); $page->drawCircle(85, 375, 25); // Draw sectors $page->drawCircle(200, 375, 25, 2*M_PI/3, -M_PI/6); $page->setFillColor(new Zend_Pdf_Color_Cmyk(1, 0, 0, 0)); $page->drawCircle(200, 375, 25, M_PI/6, 2*M_PI/3); $page->setFillColor(new Zend_Pdf_Color_Rgb(1, 1, 0)); $page->drawCircle(200, 375, 25, -M_PI/6, M_PI/6); // Draw ellipse $page->setFillColor(new $page->drawEllipse(250, $page->setFillColor(new $page->drawEllipse(250, $page->setFillColor(new $page->drawEllipse(250,
Zend_Pdf_Color_Rgb(1, 0, 0)); 400, 400, 350); Zend_Pdf_Color_Cmyk(1, 0, 0, 0)); 400, 400, 350, M_PI/6, 2*M_PI/3); Zend_Pdf_Color_Rgb(1, 1, 0)); 400, 400, 350, -M_PI/6, M_PI/6);
5 sur 16
// Draw and fill polygon $page->setFillColor(new Zend_Pdf_Color_Rgb(1, 0, 1)); $x = array(); $y = array(); for ($count = 0; $count < 8; $count++) { $x[] = 140 + 25*cos(3*M_PI_4*$count); $y[] = 375 + 25*sin(3*M_PI_4*$count); } $page->drawPolygon($x, $y, Zend_Pdf_Page::SHAPE_DRAW_FILL_AND_STROKE, Zend_Pdf_Page::FILL_METHOD_EVEN_ODD); // Draw line $page->setLineWidth(0.5); $page->drawLine(60, 375, 400, 375); Result of this code usage:
The code above demonstrates usage of colors objects and assigning them to fill color and line color. In addition, lines may also be decorated with Zend_Pdf_Page::setLineDashingPattern($pattern, $phase) method, where $pattern is an array of floats: array(on_length, off_length, on_length, off_length, ) and $phase is a shift from the beginning of line. The Zend_Pdf component operates with gray scale, RGB, CMYK and HTML colors. // $grayLevel (float number). 0.0 (black) - 1.0 (white) $color1 = new Zend_Pdf_Color_GrayScale($grayLevel); // $r, $g, $b (float numbers). 0.0 (minimum intensity) - 1.0 (maximum inten $color2 = new Zend_Pdf_Color_Rgb($r, $g, $b); // $c, $m, $y, $k (float numbers). 0.0 (minimum intensity) - 1.0 (maximum i $color3 = new Zend_Pdf_Color_Cmyk($c, $m, $y, $k); // HTML $color4 $color5 $color6 colors = new Zend_Pdf_Color_Html('#3366FF'); = new Zend_Pdf_Color_Html('silver'); = new Zend_Pdf_Color_Html('forestgreen');
An instance of the Zend_Pdf_Style object may be used to assign a set of drawing properties. // Create new Style
6 sur 16
$style = new Zend_Pdf_Style(); After creation style may collect number of drawing settings like line color, fill color, line width, line dashing pattern and phase, current font and font size. $style->setFillColor(new Zend_Pdf_Color_Rgb(0, 0, 0.9)); $style->setLineColor(new Zend_Pdf_Color_GrayScale(0.2)); $style->setLineWidth(3); $style->setLineDashingPattern(array(3, 2, 3, 4), 1.6); $style->setFont(Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA_B Then all these settings may be applied through one step. // Apply style $page->setStyle($style);
Because nothing is ever quite as easy as it seems, to get angled text or graphics on a page, you need to rotate the page before drawing; luckily for you, Zend_Pdf makes this easy. Zend_Pdf_Page has a method rotate() that will allow you to easily rotate a page by a given angle, around a specific point on the page. Ok, that sounds a bit confusing so just read the code. // Rotate page coordinate system $page->rotate($x, $y, $angel); See, not nearly as difficult as it sounds. Here is an example of several scripts and resulting pages (axes drawing is skipped): 1. Source page. $page->drawText('Hello world!', 150, 100);
7 sur 16
2. Page rotated around left bottom corner. $page->rotate(0, 0, M_PI/12); $page->drawText('Hello world!', 150, 100);
3. Page rotated around specified point. $page->rotate(150, 100, M_PI/12); $page->drawText('Hello world!', 150, 100);
8 sur 16
Clipping is the process of limiting the region a paint operator will work on. The default for a paint operator paints the entire page, in most cases, this is not the desired result. Clipping effects can also be applied to images, as can be seen in this example below. // Create new image object $image = Zend_Pdf_Image::imageWithPath($imagePath); // Draw part of the image within a circle $page->saveGS(); $page->clipCircle(200, 150, 50); $page->drawImage($image, 200, 100, 300, 200); $page->restoreGS(); Result without clipping:
The last thing we need to cover is graphics state. Any time the graphic state of the page changes (current font, font size, line color, fill color, line style, page rotation, clip area) you can use saveGS() and restorGS() to save it or restore it. This allows you to save the current graphic state, make changes and draw things, then restore it. Each save graphics state call mast have corresponded restore graphic state method: foreach ($pdf->pages as $page){ $page->saveGS(); $page->setStyle($style); $page->rotate(0, 0, M_PI_2/3); $page->saveGS(); $page->clipCircle(550, -10, 50);
9 sur 16
$page->drawImage($stampImage, 500, -60, 600, 40); $page->restoreGS(); $page->drawText('Modified', 150, 0); $page->restoreGS(); }
We really hope that this short tutorial has given you a taste for what is possible with Zend_PDF and more importantly, sparked your imagination on how you can use it in your own applications. As with all parts of the Zend Framework, Zend_Pdf is constantly undergoing review, refactoring and enhancement. as of this writing, there are new features that have been checked in for release in Zend Framework 1.1 and additional features on the roadmap that have yet to be pinned down. Document info processing. Get/set document title, author, subject and other pieces of metadata about the document. Pages cloning. Allows to clone existing page and use it as a template for another pages. This feature is complete, tested, planned to be included into ZF 1.1 It is already available if you fetch the Zend Framework from SVN or download a nightly snapshot. Detaching page (and other resources) from a PDF document. This feature, coupled with page cloning will allow developers to mix pages from different documents to create a new one. This feature is scheduled to be available at the release of Zend Framework 1.1 Rich text drawing functions. For more information on Zend_Pdf or the Zend Framework in general * Link http://framework.zend.com* , check out the extensive documentation * Link http://framework.zend.com/manual/en/* . If you still have questions, pop over to the #zftalk channel on freenode.net and chat with other Zend Framework users. We also encourage you to voice your opinion. What new features of Zend_Pdf are important to you?
Tweet 3
0
Like 1 Share
0
Published: September 7th, 2007 at 7:17 Categories: Tutorials, Zend Framework Tags: Zend_Pdf
10 sur 16