Dynamically Generating PDF Files with PHP and Haru

November 17, 2008

Tutorials, Zend Framework

The Ultimate Assistant

When it comes to working with different file formats, PHP is like a Swiss Army knife: it has a tool to handle almost anything you can throw at it. JPEG images, XML files, Word documents, ZIP archives…you name it, and there’s a PHP extension to handle it!

This incredible versatility also applies to the topic of today’s article: the PDF, or Portable Document Format. Not content with just one, PHP actually comes with two different extensions that allow developers to dynamically generate PDF documents: the PDFlib extension, and the libHaru extension. Over the next few pages, I’m going to take a quick look at the Haru extension, providing you with a brief overview of its functions and demonstrating how you can use it in your PHP development. So come on it, and let’s get going!

Tooling Up

LibHaru support in PHP comes through PECL’s ext/haru extension, which is maintained by Antony Dovga and provides an object-oriented API for PDF document generation. This ext/haru extension, in turn, requires you to have the libHaru PDF library installed on your system. This library is available for both Windows and UNIX systems.

If you’re using a UNIX system, begin by downloading, compiling and installing the libHaru library from http://www. libharu.org/. This article uses libHaru 2.0.8.

shell# ./configure --shared
shell# make
shell# make install
Once this is done, download the source code archive (v0.0.1 at this time) from http://pecl.php.net/package/haru and compile it into a loadable PHP module with phpize:
shell# cd haru-0.0.1
shell# phpize
shell# ./configure --with-zlib-dir=/usr/local --with-png-dir=/usr/local --with-haru=/usr/local
shell# make
shell# make install

This procedure should create a loadable PHP module named haru.so in your PHP extension directory. You should now enable the extension in the php.ini configuration file, restart your Web server, and check that the extension is enabled with a quick call to phpinfo():

Windows users have a much easier time of it; a pre-compiled version of the Haru extension is included by default with the Windows version of PHP. If you’re using a Windows system, first download a pre-compiled version of the libHaru library (libhpdf.dll) and place it in your PHP directory. Then, activate the included Haru extension in your php.ini configuration file, restart your Web server, and check the extension’s status with phpinfo(), as described above.

Sword Fight

Once you’ve got the pieces installed, let’s take Haru out for a quick spin. The following example demonstrates how to create a PDF document containing a famous Shakespearean quotation:

<?php
try {
  // create handle for new PDF document
  $pdf = new HaruDoc;
  
  // add a page to the PDF document
  $page = $pdf->addPage(); 
  
  // set page size and orientation
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
  
  // load a TTF font file
  $name = $pdf->loadTTF('/tmp/comic.ttf');
  $font = $pdf->getFont($name);
  
  // set page font and size
  $page->setFontAndSize($font, 12);
  
  // start a text object
  $page->beginText();
  // move to offset
  $page->moveTextPos(50, 630);
  // write text
  $page->showText("When valour preys on reason,");
  // move to relative offset
  $page->moveTextPos(0,-50);
  // add next line of text
  $page->showText("It eats the sword it fights with.");
  // end text object
  $page->endText();
  
  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());    
}
?>

Try running this and once completed, you should have a PDF file at /tmp/test.pdf, which looks something like this:

So what does this script do? It starts off by initializing a new HaruDoc object, which represents the PDF document to be created. It then adds a new page to this document via the addPage() method, which creates a new HaruPage object. This HaruPage object is the primary interface for everything related to the corresponding page. The script then uses this object to set the orientation and size of the page via the setSize() method, and loads the fonts needed for the page via the loadTTF() method. Once loaded, the getFont() method returns an instance of a HaruFont object, which represents the font for all subsequent use.

Now to actually write some text! The first step is to decide which of the loaded fonts to use, and set this with the HaruPage object’s setFontAndSize() method. Next, the HaruPage object’s beginText() and endText() methods are used to mark the beginning and end of a text block. Within these two methods calls, the moveTextPos() method is used to move the text cursor to a specific offset on the page, and the showText() method is used to actually write text to the page beginning from that location. Note that the moveTextPos() method moves the cursor relative to its last position or, if called for the first time, relative to the document origin (0,0) or the bottom left corner of the page.

Once all the text is written, the PDF file is written to disk with the HaruDoc object’s save() method. As an alternative, it’s also possible to output the PDF file direct to the client browser via the output() method (you’ll see this in an upcoming example). Any errors in the PDF creation process will generate an exception, which can be caught by wrapping the script in a try-catch block.

A quick word here about fonts and font files. The listing above demonstrated the loadTTF() method, which is a convenient way to import TrueType font files from disk into a PDF document. It’s also possible to import fonts from Type1 font files and TrueType font collection files, via the loadType1() and loadTTC() methods. All of these methods return the name of the font file, which is required by the getFont() method to generate a HaruFont instance. It’s also possible to directly use a built-in font, such as ‘Courier’ or ‘Times-Roman’, by passing the font name directly to the getFont() method. A complete list of built-in font names can be found at http://www.php.net/manual/en/haru.builtin.php#haru.builtin.fonts.

An alternative way of writing text to a page is with the textOut() method, which accepts absolute coordinates for the text cursor. This is often easier than using moveTextPos(), which uses relative offsets. Here’s an example, which replicates the output of the previous listing:

<?php
// set some configuration values
define ('SOURCE', 'data.txt');
define ('FONT_NAME', 'Courier');
define ('FONT_SIZE', 12);
define ('LINE_SPACING', 15);

// step 1: create a dummy object to measure sizes, fonts etc //

try {
  // create and set up PDF document
  $pdf = new HaruDoc;
  $page = $pdf->addPage(); 
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
  $font = $pdf->getFont('Courier');
  $page->setFontAndSize($font, FONT_SIZE);
  
  // read in source file text
  $file = file_get_contents(SOURCE);
  
  // measure how many characters fit on a line
  // given the page width and font size
  $count = $page->measureText($file, $page->getWidth()-10, true);
  
  // wrap the source text at the specified character count
  $file = wordwrap($file, $count, "\n");  
  
  // separate the source text into an array of individual lines
  $lines = explode("\n", $file);
  
  // destroy the dummy object
  unset($pdf);
  
  // step 2: generate the PDF for real //
  
  // create and set up PDF document
  $pdf = new HaruDoc;
  $font = $pdf->getFont(FONT_NAME);
  $page = $pdf->addPage(); 
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
  $page->setFontAndSize($font, FONT_SIZE);
  $page->beginText();
  $page->moveTextPos(10, 750);
  
  // process each line
  foreach ($lines as $l) {
    // check if we are at the end of the page
    // if yes, start a new page
    $pos = $page->getCurrentTextPos();
    if ($pos['y'] <= 0) {
      $page->endText();
      $page = $pdf->addPage(); 
      $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
      $page->setFontAndSize($font, FONT_SIZE);
      $page->beginText();
      $page->moveTextPos(10, 750);
    }
    // write the line of text
    // move to the next line position
    $page->showText($l);
    $page->moveTextPos(0, -LINE_SPACING);
  }
  
  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());    
}
?>

This script looks somewhat complex, but it really isn’t. It begins by setting some configuration values, such as the source text file, the font and font size to use, and the line spacing required. It then reads the source file into a string, and passes this string to the HaruPage object’s measureText() method to calculate how many characters will fit on to each line of the page, given the specified page width (with some margin allowance) and font size. Once this character limit is obtained, PHP’s wordwrap() function is used to split the file data into an array of lines, such that the number of characters in each line does not exceed this limit.

The second stage is to actually generate a PDF version of the text file. This is accomplished by creating a new HaruDoc, setting the font and size, and then iterating over the line array in a loop. This loop takes care of printing each line to the page with the showText() method, and then moving the text cursor down to the next line with the moveTextPos() method. On each iteration of the loop, the current position of the text cursor is obtained via the getCurrentTextPos() method. If this position appears to be below the end of the page, a new page is dynamically added to the document via the addPage() method. In this manner, a multi-page PDF document is dynamically generated from a text file.

Here’s an example of the output:

Notice also that the example above uses a built-in font, Courier, instead of loading a TrueType font file. In many cases, this approach can reduce the size of the output PDF file.

Pretty As A Picture

It’s not just text, either – libHaru can also import image files of different formats into a PDF document, via its loadJPEG(), loadRAW() and loadPNG() methods. Here’s an example, which demonstrates the process:

<?php
try {
  // create handle for new PDF document
  $pdf = new HaruDoc;
  
  // add a page to the PDF document
  $page = $pdf->addPage(); 
  
  // set page size and orientation
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
  
  // load a JPEG image
  $image = $pdf->loadJPEG('/tmp/img_0497.jpg');
  
  // add image
  $page->drawImage($image, 50, 450, $image->getWidth()*0.10, $image->getHeight()*0.10);
  
  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());    
}
?>

Here, the loadJPEG() method of the HaruDoc object is used to load a JPEG image from disk. Then, the HaruPage object’s drawImage() method is used to place this image on the page, at a specified set of coordinates. In addition to the image and the location, the drawImage() method must also be provided with the dimensions of the image. In the example above, these dimensions are dynamically obtained from the image file via the getWidth() and getHeight() methods, and then reduced to 10% of their original value. Once the image has been written to the page, the document can be saved to disk with a call to save(), as usual.

Here’s the output:

Lining Up

Why stop there? PHP’s Haru extension comes with a whole bag of functions designed to let you draw lines, circles and other shapes in your PDF document. Consider the following example, which demonstrates the process of drawing a line:

<?php
try{ 
  // create handle for new PDF document
  $pdf = new HaruDoc;
  
  // add a page to the PDF document
  $page = $pdf->addPage(); 
  
  // set page size and orientation
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
  
  // load a JPEG image
  $image = $pdf->loadJPEG('/tmp/logo.jpg');
  
  // load a built-in font
  $font = $pdf->getFont('Courier');
  
  // add image
  $page->drawImage($image, 25, 740, $image->getWidth(), $image->getHeight());
  
  // set stroke color
  // draw line under image
  $page->setRGBStroke(0, 0, 0); 
  $page->moveTo(10,735);
  $page->lineTo(($page->getWidth()-10),735);
  $page->stroke();
  
  // draw another line near the bottom of the page
  $page->moveTo(10,25);
  $page->lineTo(($page->getWidth()-10),25);
  $page->stroke();
  
  // and write some text under it
  $page->setFontAndSize($font, 10);
  $page->beginText();
  $page->moveTextPos($page->getWidth()-250, 10);
  $page->showText('Copyright 2008. All rights reserved.');
  $page->endText();

  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());    
}
?>

With Haru, drawing a line is a three-step process. First, move the drawing cursor to the line’s start point, by calling the HaruPage object’s moveTo() method with the correct coordinates. Then, mark the end-point of the line by calling the lineTo() position with the end-point coordinates. Finally, render the actual line by calling the stroke() method.

The stroke colour is set via a call to the HaruDoc setRGBStroke() method, which accepts RGB values corresponding to the selected colour. It’s important to note that these values must be specified in terms of percentage intensity – that is, the intensity of that colour, expressed as a percentage of the maximum intensity possible. So, for example, if you wanted to set red (RGB: 255,0,0) as the stroke colour, you would invoke the method as $page->setRGBStroke(1, 0, 0). It’s also possible to set a fill colour, with the setRGBFill() method; you’ll see this in the next example.

Now, look closely at the script above and you’ll see that it actually draws more than just a single line. It actually draws two lines, one in the page header and one in the page footer, and it also mixes things up a little by adding an image to the top left corner of the page and footer text to the bottom right corner, using methods you’ve seen in previous examples. Here’s an example of what the final output looks like:

Here’s another example, this one demonstrating how to draw a grid of vertical and horizontal lines using the lineTo() method:

<?php
try {
  // create handle for new PDF document
  $pdf = new HaruDoc;
  
  // add a page to the PDF document
  $page = $pdf->addPage(); 
  
  // set page size and orientation
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
  
  // set stroke colour
  $page->setRGBStroke(0, 0, 0); 
  
  // draw  vertical lines (move along X-axis)
  for ($x=0; $x<$page->getWidth(); $x+=40) {
    $page->moveTo($x,0);
    $page->lineTo($x,$page->getHeight());
    $page->stroke();
  }
  
  // draw horizontal lines (move along Y-axis)
  for ($y=0; $y<$page->getHeight(); $y+=40) {
    $page->moveTo(0,$y);
    $page->lineTo($page->getWidth(),$y);
    $page->stroke();
  }
  
  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());  
}
?>

Here, loops are used to dynamically draw a series of lines across the page, first vertically and then horizontally, to generate a rectangular grid. Here’s what the output looks like:

A Square Face

Lines aren’t the only thing you can draw; circles and rectangles also figure prominently on the menu. Take a look at the following example, which demonstrates:

<?php
try {
  // create handle for new PDF document
  $pdf = new HaruDoc;
  
  // add a page to the PDF document
  $page = $pdf->addPage(); 
  
  // set page size and orientation
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
   
  // set stroke colour
  $page->setRGBStroke(0, 0, 0); 

  // set fill colour
  $page->setRGBFill(1, 0, 0); 
  
  // draw rectangle
  $page->rectangle(50,500,150,150);
  
  // fill and stroke rectangle
  $page->fillStroke();
   
  // draw right eye
  $page->setRGBFill(0, 1, 0); 
  $page->rectangle(350,500,150,150);
  $page->fillStroke();
  
  // draw nose
  $page->setRGBFill(0, 1, 1); 
  $page->rectangle(250,300,50,150);
  $page->fillStroke();
  
  // draw mouth
  $page->setRGBFill(1, 0, 1); 
  $page->rectangle(150,200,250,50);
  $page->fillStroke();
  
  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());  
}
?>

This script attempts to draw a face, using filled rectangles of different sizes for the eyes, nose and mouth. As before, it first uses the setRGBFill() and setRGBStroke() to define the fill and stroke colour for each rectangle. The rectangle itself is marked out using the HaruPage object’s rectangle() method, which accepts four arguments: the X and Y coordinates of the rectangle’s lower left corner, and the width and height of the rectangle, in pixels. Once the rectangle has been marked out, the fillStroke() method is used to simultaneously fill and stroke it with the previously-selected colours.

Here’s what the output looks like:

Circling The Wagons

Drawing circles is also fairly easy: simply call the circle() method with the coordinates of the circle center and the length of the radius, and Haru will draw you a circle with the specified parameters. You can then stroke it, fill it or do both with the stroke(), fill() or fillStroke() methods.

Here’s an example, which rewrites the previous one and replaces the rectangular eyes with circular ones instead:

<?php
try {
  // create handle for new PDF document
  $pdf = new HaruDoc;
  
  // add a page to the PDF document
  $page = $pdf->addPage(); 
  
  // set page size and orientation
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
   
  // draw left eye
  $page->setRGBStroke(0, 0, 0); 
  $page->setRGBFill(1, 0, 0); 
  $page->circle(150,500,75);
  $page->fillStroke();
   
  // draw right eye
  $page->setRGBFill(0, 1, 0); 
  $page->circle(400,500,75);
  $page->fillStroke();
  
  // draw nose
  $page->setRGBFill(0, 1, 1); 
  $page->rectangle(250,300,50,150);
  $page->fillStroke();
  
  // draw mouth
  $page->setRGBFill(1, 0, 1); 
  $page->rectangle(150,200,250,50);
  $page->fillStroke();
  
  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());  
}
?>

And here’s the output:

It’s also possible to draw arcs, with the HaruPage object’s arc() method. This method accepts five arguments: the X and Y coordinates of the arc center, the arc radius, and the angles for the arc’s start- and end-point. To see this in action, consider yet another revision of the previous listing, which replaces the rectangular mouth with a curved smile and – for good measure – adds a pair of eyebrows. Take a look at the code:

<?php
try {
  // create handle for new PDF document
  $pdf = new HaruDoc;
  
  // add a page to the PDF document
  $page = $pdf->addPage(); 
  
  // set page size and orientation
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
   
  // draw left eye
  $page->setRGBStroke(0, 0, 0); 
  $page->setRGBFill(1, 0, 0); 
  $page->circle(150,500,75);
  $page->fillStroke();
   
  // draw right eye
  $page->setRGBFill(0, 1, 0); 
  $page->circle(400,500,75);
  $page->fillStroke();
  
  // draw nose
  $page->setRGBFill(0, 1, 1); 
  $page->rectangle(250,300,50,150);
  $page->fillStroke();
  
  // draw smile
  $page->setRGBStroke(1, 0, 0); 
  $page->arc(275,300,150,90,270);
  $page->stroke();
  
  // draw left eyebrow
  $page->setRGBStroke(0, 0, 0); 
  $page->arc(150,550,75,-60,60);
  $page->stroke();

  // draw right eyebrow
  $page->setRGBStroke(0, 0, 0); 
  $page->arc(400,550,75,-60,60);
  $page->stroke();
  
  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());  
}
?>

And here’s the new output:

Who says PDF can’t put a smile on your face?

Linking Out

The Haru library also supports the creation of text annotations within your PDF document, via the – what else? – createTextAnnotation() method. This method accepts an array of coordinates for the annotation, together with the annotation text. Here’s an example:

<?php
try {
  // create handle for new PDF document
  $pdf = new HaruDoc;
  
  // add a page to the PDF document
  $page = $pdf->addPage(); 
  
  // set page size and orientation
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
  
  // load a built-in font file
  $font = $pdf->getFont('Courier');
  
  // set page font and size
  $page->setFontAndSize($font, 12);
  
  // write tex
  $page->beginText();
  $page->moveTextPos(50, 630);
  $page->showText("When valour preys on reason,");
  $page->moveTextPos(0, -50);
  $page->showText("It eats the sword it fights with.");
  $page->endText();

  // add text annotation
  $anno = $page->createTextAnnotation(array(300,600,320,580), 'Enobarbus, Act III, Scene XIII');
  $anno->setIcon(HaruAnnotation::ICON_NOTE);
    
  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());    
}
?>

And here’s what the output looks like:

It’s also possible to create link and URL annotations, with the createLinkAnnotation() and createURLAnnotation() methods, respectively.

Access Denied

You can set document information with the HaruDoc object’s setInfoAttr() method; this information identifies the document creator, title, subject and content keywords. You can also set the document’s creation and last modification date, with the setInfoDateAttr() method. The following example demonstrates both:

<?php
try {
  // create handle for new PDF document
  $pdf = new HaruDoc;
  
  // add a page to the PDF document
  $page = $pdf->addPage(); 
  
  // set page size and orientation
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
  
  // load a built-in font file
  $font = $pdf->getFont('Courier');
  
  // set page font and size
  $page->setFontAndSize($font, 12);
  
  // start a text object
  $page->beginText();
  $page->moveTextPos(50, 630);
  $page->showText("When valour preys on reason,");
  $page->moveTextPos(0, -50);
  $page->showText("It eats the sword it fights with.");
  $page->endText();

  // add author information
  $pdf->setInfoAttr(HaruDoc::INFO_AUTHOR, 'William Shakespeare');  
  $pdf->setInfoAttr(HaruDoc::INFO_TITLE, 'Enobarbus');  
  $pdf->setInfoAttr(HaruDoc::INFO_SUBJECT, 'Act III, Scene XIII');  
  $pdf->setInfoAttr(HaruDoc::INFO_KEYWORDS, 'shakespeare, play, theatre, enobarbus, valour, reason');  

  // add date information  
  $pdf->setInfoDateAttr(HaruDoc::INFO_CREATION_DATE, 2008, 9, 18, 12, 01, 34, '', null, null);  
  $pdf->setInfoDateAttr(HaruDoc::INFO_MOD_DATE, 2008, 9, 24, 12, 01, 34, '', null, null);  
  
  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());    
}
?>

In a similar vein, you can set user and owner passwords for the PDF document with the setPassword() method, and control whether the document can be read, copied, printed and edited with the setPermission() method. Here’s an example:

<?php
try {
  // create handle for new PDF document
  $pdf = new HaruDoc;
  
  // add a page to the PDF document
  $page = $pdf->addPage(); 
  
  // set page size and orientation
  $page->setSize(HaruPage::SIZE_LETTER, HaruPage::PORTRAIT);
  
  // load a built-in font file
  $font = $pdf->getFont('Courier');
  
  // set page font and size
  $page->setFontAndSize($font, 12);
  
  // start a text object
  $page->beginText();
  $page->moveTextPos(50, 630);
  $page->showText("When valour preys on reason,");
  $page->moveTextPos(0, -50);
  $page->showText("It eats the sword it fights with.");
  $page->endText();

  // add author information
  $pdf->setInfoAttr(HaruDoc::INFO_AUTHOR, 'William Shakespeare');  
  $pdf->setInfoAttr(HaruDoc::INFO_TITLE, 'Enobarbus');  
  $pdf->setInfoAttr(HaruDoc::INFO_SUBJECT, 'Act III, Scene XIII');  
  $pdf->setInfoAttr(HaruDoc::INFO_KEYWORDS, 'shakespeare, play, theatre, enobarbus, valour, reason');  

  // add date information  
  $pdf->setInfoDateAttr(HaruDoc::INFO_CREATION_DATE, 2008, 9, 18, 12, 01, 34, '', null, null);  
  $pdf->setInfoDateAttr(HaruDoc::INFO_MOD_DATE, 2008, 9, 24, 12, 01, 34, '', null, null);  
  
  // set passwords
  $pdf->setPassword('owner', 'user');
  
  // then set permissions using bitwise OR operator
  $pdf->setPermission(HaruDoc::ENABLE_READ | HaruDoc::ENABLE_PRINT); 
  
  // output the PDF document to disk
  $pdf->save("/tmp/test.pdf"); 
  echo 'SUCCESS: Document created!';  
} catch (Exception $e) {
  die('ERROR: ' . $e->getMessage());    
}
?>

The setPermission() method accepts a series of permission values, separated with the bitwise OR operator (|). The available permissions are:

  • HaruDoc::ENABLE_READ
  • HaruDoc::ENABLE_PRINT
  • HaruDoc::ENABLE_EDIT_ALL
  • HaruDoc::ENABLE_COPY
  • HaruDoc::ENABLE_EDIT

And that’s about all I have for the moment. I hope this article demonstrated some of the most important features of the Haru PDF extension, and intrigued you enough to go out there and start experimenting with it. Happy coding!

This article copyright Melonfire, 2008. All rights reserved.

About Vikram Vaswani

Vikram Vaswani is the founder and CEO of "Melonfire":http://www.melonfire.com/, a consultancy specializing in open-source tools and technologies. He is a passionate proponent of the open-source movement and frequently contributes articles and tutorials on open-source technologies, including Perl, Python, PHP, MySQL, and Linux, to the community at large. He is the author of four books on PHP and MySQL, including "MySQL: The Complete Reference":http://www.mysql-tcr.com/, "How to Do Everything with PHP and MySQL":http://www.everythingphpmysql.com/ and "PHP Programming Solutions":http://www.php-programming-solutions.com/. Vikram has more than eight years of experience working with PHP and MySQL as an application developer. He is the author of Zend Technologies' "PHP 101 series":http://devzone.zend.com/tag/PHP101 for PHP beginners, and has extensive experience deploying PHP in a variety of different environments (including corporate intranets, high-traffic Internet Web sites, and mission-critical thin client applications). A Felix Scholar at the University of Oxford, England, Vikram combines his interest in Web application development with various other activities. When not dreaming up plans for world domination, he amuses himself by reading crime fiction, watching old movies, playing squash, blogging, and keeping an eye out for unfriendly Agents.

View all posts by Vikram Vaswani

9 Responses to “Dynamically Generating PDF Files with PHP and Haru”

  1. jhribik Says:

    Thank you for nice article.
    But I am sorry, this "PHP swiss knife for PDF" is very blunt knife when you need more complicated features.

    - No unicode encoding supported (UTF-8, UTF-16)
    - No background drawings (watermark)
    - No document manipulation (copy page from another PDF file)
    - … probably more pitfalls

    Does anybody know a PHP library with features like iText for Java or .NET?
    http://www.lowagie.com/iText/

  2. kevinkorb Says:

    I think referring it to a swiss army knife works. Honestly a Swiss army knife isn’t the best at anything, however it has tons of useful tools. You don’t see many Swiss army knifes used in kitchens or any specialized uses, however if you’re in the middle of nowhere and happen to need a corkscrew, knife, scissors, nail file or whatever, well for the most part you’ll be covered. Are any of these tools the ideal tool for any one advanced job? Probably not but lots of times your damn glad you have it.

  3. jhribik Says:

    @kevinkorb: I must argue.
    1. Swiss knife should be something unbeatable, something that saves your life in every trouble. It can be very dangerous to start coding without knowing a weaknesses of the foreign library. How you tell your customer "I am sorry we can not generate a customer order PDF with russian azbuka".
    2. The open-source PDF libraries for Java or .NET support the features mentioned above.

  4. mathrm Says:

    I don’t like the idea of having to ask server admin for installing this or that…

    Have you ever used mPDF?
    http://mpdf.bpm1.com

    "mPDF is a PHP class which generates PDF files from UTF-8 encoded HTML. It is based on FPDF, HTML2FPDF, and UFPDF, with a number of enhancements."

  5. dpassey Says:

    I currently use my own class extended off of the FPDF class (fpdf.org). It works just fine for my needs and I believe it will do all like Haru. Anyone have any input on that?

  6. pauljmartinez Says:

    I found the syntax to be quite similar to TCPDF, which is a nice library. TCPDF supports both PHP4 and PHP5 and has support for UTF-8.

  7. schogini Says:

    This is a well presented article, but needing to compile the module using shell may be asking a bit too much these days.

    We have been using fPDF, but I took a look at
    http://mpdf.bpm1.com, it is very handy to build quick PDF straight from HTML pages thus eliminating the need to position text etc.

  8. todd_wallar Says:

    Zend Framework has a decent PDF generating lib. Why not use that? It’s broken in a few places, but not bad overall.

  9. _____anonymous_____ Says:

    this is wonderful tutorial .. i read it 3 times and get a fantastic results and sure i put a
    copy of this lesson on my site here
    http://www.malak-rouhi.com/vb/index.php