The Zend Framework (ZF) provides a class, Zend_Pdf, for creating PDF files. A few years ago I had some experience creating PDFs using the fpdf library. As I recall, it worked quite well. However, since I now had begun developing using the ZF, I decided to try and make use of what it had to offer in the realm of PDF creation when the need for it arose recently.
I can't guarantee what follows will address all the needs of anyone reading this, but it solved a couple of issues I was having. Namely:
1) Wrapping text cleanly (breaking at words and not mid-words)
2) Creating new pages to the PDF, if necessary - since I had no idea how long the text might be.
The first place I looked was the documentation of Zend_Pdf. While it has a lot of really good examples on using Zend_Pdf, it didn't seem to address my particular needs. I then poked around the net to see what others had to say regarding Zend_Pdf and wrapping text. For the most part, what I found were people asking why Zend_Pdf didn't have a wrapping function. My inclination was to agree with that observation. Now, however, I'd have to say I think it makes more sense to handle the wrapping (and any other text manipulation) prior to passing it along to the PDF.
Here's an overview of how I achieved the results I was going after and an outline of what's going on in the example below.
1) Create a Zend_Pdf Object, set up the style, create the first page
2) Create a $text variable (in the example below, I read it in from a text file)
3) Draw $text to the PDF: $page->drawText($text, 40, 760);
At this point, this will just output the text on one line in one page. Not what we need.
4) Wrap $text using the wordwrap() function
where
$text = The string to wrap
80 = How long each line should be after wrapping (column width)
"\n" = How the line is broken (\n is the default)
false = Don't cut strings (as in, break up words to keep the desired width)
5) Tokenize $text and pass it line by line to the Zend_Pdf Object
What this does is tokenize $text at each occurrence of "\n" (which we created above)
6) Set a variable to track the vertical position of the output, as new text is added (in this case, $y)
7) Loop through $token:
if ($y < 60) {
$pdf->pages[] = ($page = $pdf->newPage(Zend_Pdf_Page::SIZE_LETTER));
$page->setStyle($style);
$y = 740;
}
else {
$page->drawText($token, 40, $y);
$y-=15;
}
$token = strtok("\n");
}
Here's what's going on:
The loop continues as long as $token is not false. It first tests to see if $y is less than 60. $y is what is determining where, vertically, on the PDF the text should be placed and so at a certain point a new page should be created. That's what's going on within that conditional statement. A new page is created, it's given a style, and $y is reset to the top of the next page, in this case $y = 740. If $y is not less than 60, the line is drawn to the PDF at a consistent horizontal position (40) and the varying vertical position ($y). $y is then updated to move down the line on the next pass. Once outside the if/else, the string is tokenized again using $token = strtok("\n") - and if there is something to tokenize the process repeats.
8) Generate the PDF:
That's it.
Here's the complete PHP:
require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();
$color = array();
$color["blue"] = new Zend_Pdf_Color_Html("#466E99");
$color["grey"] = new Zend_Pdf_Color_Html("#454545");
$font = Zend_Pdf_Font::fontWithName(Zend_Pdf_Font::FONT_HELVETICA_BOLD);
$size = 13;
$style = new Zend_Pdf_Style();
$style->setFont($font, $size);
$style->setFillColor($color["grey"]);
$pdf = new Zend_Pdf();
$pdf->pages[] = ($page = $pdf->newPage(Zend_Pdf_Page::SIZE_LETTER));
$page->setStyle($style);
$file = "zendpdf.txt";
$fh = fopen($file, 'r');
$text = fread($fh, filesize($file));
$page->drawText($text, 40, 760);
$text = wordwrap($text, 80, "\n", false);
$token = strtok($text, "\n");
$style->setFillColor($color["blue"]);
$page->setStyle($style);
$y = 740;
while ($token != false) {
if ($y < 60) {
$pdf->pages[] = ($page = $pdf->newPage(Zend_Pdf_Page::SIZE_LETTER));
$page->setStyle($style);
$y = 740;
}
else {
$page->drawText($token, 40, $y);
$y-=15;
}
$token = strtok("\n");
}
$pdf->save('mine.pdf');

Thanks
Nice work, Thank You :) I have to test this in my project. I wonder when such functionality will be added to Zend Framework Core.
Post new comment