Improved PDF generation with RE Framework RE_Pdf

March 20, 2009 – 9:48 pm Tags: , ,

I’ve previously written a post on creating a PDF generator class using Zend_Pdf, which detailed some Zend_Pdf usage and introduced a class which could be used to create PDFs easily based on an XML configuration file or such.

Zend_Pdf, while generally quite good, has one big issue: It does not support word wrapping text!

There’s a new and still a bit obscure framework called RE Framework, which has an excellent PDF component – it includes support for word wrapping, better support for PDF templates, image loading etc.

Let’s check out how to use RE_Pdf to improve the earlier CU_PdfGenerator class!

The XML configuration

Let’s first modify the code which parses the XML file. We will also add a new feature: Setting dimensions for a text box.

RE_Pdf shares a similar interface as Zend_Pdf, so for this part the rewrite will be quite simple: We’ll just replace Zend_ with RE_:

$xml = simplexml_load_file('path/to/definition.xml');
$fontSize = (int)$xml->font['size'];
$fontFamily = (string)$xml->font['family'];
$generator = CU_PdfGenerator::create()
           ->setFont(RE_Pdf_Font::fontWithName($fontFamily), $fontSize);
foreach($xml->elements[0] as $element) {
    $key = (string)$element['key'];
    //New code to add support for width/height of textboxes!
    $w = 0;
    $h = 0;
    if(isset($element['width'])) {
        $w = (int)$element['width'];
        $h = (int)$element['height'];
    $generator->setPosition($key, (int)$element['x'], (int)$element['y'], $w, $h);
    if(isset($element->font)) {
        $family = $fontFamily;
        $size = $fontSize;
        if(isset($element->font['family'])) {
            $family = (string)$element->font['family'];
        if(isset($element->font['size'])) {
            $size = (int)$element->font['size'];
        $font = RE_Pdf_Font::fontWithName($family);
        $generator->setFontForKey($key, $font, $size);

So instead of creating new Zend_Pdf_Fonts, we use RE_Pdf_Font. We also added new code which grabs width and height from the XML configuration.

As a refresher, let’s have a look at the XML config too:

  <font family="Helvetica" size="12" />
    <element key="firstname" x="10" y="10" />
    <element key="lastname" x="10" y="50">
      <font size="16" />
    <element key="description" x="10" y="90" width="100" height="150" />

If you compare this to the old example, we’ve added a new element which also includes new attributes width and height.

Next, we’ll modify the actual generator class itself to support word-wrap.

Modifying the generator class

Again, we’re going to replace all references to Zend_Pdf_Font with RE_Pdf_Font. We’ll also modify the setPosition method to accept a width and a height. Finally, the getPdf() method needs to be modified to use RE_Pdf’s classes.

You can get the original code here.

You can just do a search and replace for Zend_ and replace with RE_ to start. That will cover all other places except the two methods we will look at next:

public function setPosition($key, $x, $y, $width = 0, $height = 0) {
  $this->_positions[$key] = array($x, $y, $width, $height);
  return $this;

Now setPosition accepts width and height – by default they are both 0, meaning that if they’re unset, there will be no word wrap or anything.

public function getPdf() {
  $pdf = new RE_Pdf_Document();
  //Need to load the template PDF file as an image:
  $template = RE_Pdf_Image::imageWithPath($this->_template);
  //We select the first page of the template as that's what we want to use
  for($i = 0, $dataCount = count($this->_data); $i < $dataCount; $i++) {
    //Need to draw the template on the new page for it to display:
    $page = $pdf->newPage();
    $template->draw($page, new RE_Rect(new RE_Point(), 
            new RE_Point($template->getPixelWidth(), $template->getPixelHeight())));
    $values = $this->_data[$i];
    foreach($values as $key => $value) {
      $font = $this->getFontForKey($key);
      $size = $this->getFontSizeForKey($key);
      if($font != null) {
        $page->setFont($font, $size);
      else {
        $page->setFont($this->_font, $this->_fontSize);
      $position = $this->getPosition($key);
      if($position == null) {
      //Store position in variables to make it clearer					
      list($x, $y, $width, $height) = $position;
      $yFromTop = $page->getHeight() - $y;
      //If there's no width, we draw text as a single line:
      if($width === 0) {				
        $page->drawText($value, $x, $yFromTop);
      else {
        //otherwise we use RE's layoutmanager to create a wrapping text box:
        $text = new RE_Pdf_Text($value);
        RE_Pdf_LayoutManager::drawText($text, $page, new RE_Rect(
          $x, $yFromTop - $height, $width, $height
  return $pdf;

So there!

Now we can draw word wrapping textboxes in our PDF by simply adding a width and height to the XML configuration. Does it get any easier than this?

RE_Pdf supports various things that Zend_Pdf doesn’t. In my opinion, it’s easier to use than FPDF as well – I couldn’t find a way to use a template PDF using FPDF for example.

You can learn more about RE from their site, or by joining their IRC channel, #refw on They are working on improving the documentation, too. When they get that done, they’ll have easily the best PDF component.

Share this:
  1. 4 Responses to “Improved PDF generation with RE Framework RE_Pdf”

  2. I also like tcpdf for pdf generation. If you want to check it out, visit There are constant bug fixes and updates.

    By Brent on Mar 24, 2009

  3. You can use templates with fpdf with fpdi (

    By darookee on Mar 30, 2009

  1. 2 Trackback(s)

  2. Apr 5, 2009: Improved PDF generation with RE Framework RE_Pdf « - Daily tutorial for the people
  3. May 7, 2009: Making a PDF generator class using Zend_Pdf | CodeUtopia

Post a Comment

You can use some HTML (a, em, strong, etc.). If you want to post code, use <pre lang="PHP">code here</pre> (you can replace PHP with the language you are posting)