HTML to PDF converter for Java and .NET

<< back

Using PD4ML with Zend Framework 2 (ZF2)


For this example we are going to use Albums sample application explained in ZF2 tutorial. We recommend to follow the tutorial steps first, to get the demo application up and running.

After you did that, download pd4ml_php_wrapper, unpack it to the application root. A directory structure should look like on the picture:

Make sure Java runtime is installed on the server and php.ini enables external processes execution. Try to run the just installed PD4ML PHP wrapper demo.  See


An adding of "Page as PDF" button to a view

In the sample we plan add "Page as PDF" button to the list of albums. "Page as PDF" feature probably makes not much prcatical sense; it just shows the main configuration/adjustment steps. In real life use cases you would probably only need to create a print-optimized report or invoice view with a known URL and to point PD4ML converter action directly to it, skipping the below tricks with HTTP refferer.

1. Add a pdf generation link to the list of albums view module/Album/view/album/album/index.phtml

<?php endforeach; ?>
<!-- edit begin -->
<tr style="pd4ml-display: none">
<a href="<?php echo $this->url('album', array('action'=>'pdf'));?>">Page as PDF</a>
<!-- edit end -->

(An added section is inbetween edit begin and edit end comments).

pd4ml-display: none style is applied to the added code to hide the link in the generated PDF as it may look confusing there.

A list of albums should look like that now:

The link refers to a new, currently not handled action pdf


2. Add pdf action handler to module/Album/src/Album/Controller/AlbumController.php

public function pdfAction()
	$url = $this->getRequest()->getHeader('Referer')->getUri(); 
	$enc = base64_encode($url);
	$this->redirect()->toUrl($this->getRequest()->getBaseUrl() . '/pd4ml.php?url=' . $enc);

The handler takes a referrer page URL (in our case it is an URL of an album list) and forwards it to PDF converter page as url parameter. In order to avoid possible troubles with special characters, it base64-encodes the URL. 


3. The redirect command in the step above assumes an existence of pd4ml.php converter script in public/ directory. Create it:

$evaluation = 1;
$java = "java";

$url = base64_decode($_GET['url']) . '?layout=pdf';

if ( $evaluation == 1 ) {
$jar = "../pd4ml_php_wrapper/pd4ml_demo.jar";
} else {
$jar = "../pd4ml_php_wrapper/pd4ml.jar";

header("Pragma: cache");
header("Expires: 0");
header("Cache-control: private");
header('Content-type: application/pdf'); 
header('Content-disposition: inline'); 

if ( strpos(php_uname(), 'Windows' ) !== FALSE) { 
// server platform: Windows
$jar = preg_replace('/\//', "\\", $jar);
$cmdline = "$java -Xmx512m -cp $jar Pd4Cmd \"$url\" 800 A4";
} else {
// server platform: UNIX-derived
$cmdline = "$java -Xmx512m -Djava.awt.headless=true -cp $jar Pd4Cmd \"$url\" 800 A4";

// see for more command-line parameters:

passthru( $cmdline );

Make sure there is no whitespaces before <?php and after ?>

The script reads url parameter, decodes it, converts a decoded URL to a PDF and sends the generated PDF bytes to HTTP.

Also, as you may see, the script appends to the URL ?layout=pdf parameter: we'll use it to signal the application to optimize the page layout for PDF rendering.


4. The original album list view includes a navigation bar, which is great for an interactive web application, but makes not much sense in a PDF document (or by print). For the case we'll create a lightweight layout template, with a navigation bar removed. The best way would be to copy-paste the default module/Application/view/layout/layout.phtml to the same directory under blank.phtml name. After a navigation removal the template looks like that:

<?php echo $this->doctype(); ?>

<html lang="en">
<meta charset="utf-8">
<?php echo $this->headTitle('ZF2 '. $this->translate('Skeleton Application'))->setSeparator(' - ')->setAutoEscape(false) ?>

<?php echo $this->headMeta()->appendName('viewport', 'width=device-width, initial-scale=1.0') ?>

<!-- Le styles -->
<?php echo $this->headLink(array('rel' => 'shortcut icon', 'type' => 'image/', 'href' => $this->basePath() . '/images/favicon.ico'))
->appendStylesheet($this->basePath() . '/css/bootstrap.min.css')
->appendStylesheet($this->basePath() . '/css/style.css')
->appendStylesheet($this->basePath() . '/css/bootstrap-responsive.min.css') ?>

<!-- Scripts -->
<?php echo $this->headScript()->appendFile($this->basePath() . '/js/html5.js', 'text/javascript', array('conditional' => 'lt IE 9',))
->appendFile($this->basePath() . '/js/jquery-1.7.2.min.js') ?>


<div class="container">
<?php echo $this->content; ?>

5. Register the new template in the module config file module/Album/config/module.config.php

'view_manager' => array(
	'template_path_stack' => array(
		'album' => __DIR__ . '/../view',
// edit begin
'template_map' => array(
	'layout/blank' => __DIR__ . '/../view/layout/blank.phtml',
// edit end


6. Add a template switch to index action handler of module/Album/src/Album/Controller/AlbumController.php:

public function indexAction()
	// edit begin
	$flag = $this->params()->fromQuery('layout');
	if ('pdf' == $flag) {
		$layout = $this->layout();
	// edit end

	return new ViewModel(array(
		'albums' => $this->getAlbumTable()->fetchAll(),
The code checks an URL for a parameter layout=pdf and, if defined, switches a view.

 Now a click to "Page as PDF" link should generate and open a PDF like this.


You may download the complete application structure (excluding pd4ml_php_wrapper) by the link.
(Do not forget to adjust database access credentials in config/autoload/local.php)


Copyright ©2004-23 zefer|org. All rights reserved. Bookmark and Share