Creating PDF documents from PHP with PD4ML

v3.x

PD4ML is HTML-to-PDF converting Java library and command line tool. With a simple wrapper script it works also in PHP environment. The application expects there is Java runtime environment 1.4 (or above) installed on the server.

Installation and environment test

Download PD4ML library with PHP samples: pd4ml_php_wrapper.zip

The archive includes two PD4ML JAR files (PD4ML java libraries itself) and three directories.

  • probe/ - contains an environment test script, demo documents and demo converting scripts.
  • fonts/ - includes a Chinese font file for TTF embedding demonstration
  • cgi-bin/ - perl CGI scripts for the cases PHP runtime configuration does not allow to execute java

Upload the unpacked ZIP content to the server and make sure the web server has read/write permissions for the target directory and the target directory is PHP-enabled.

cgi-bin/ directory content is supposed to go to cgi-bin/ directory of the web server. You do not need the CGI scripts if PHP check succeeds.

Let's say the target directory is mapped to http://myserver/pd4ml/ URL. In order to test the deployment, try to open http://myserver/pd4ml/probe/index.php

The output should look like on the picture:

If any of the test steps is failed, the script prints suggestions what could be done to fix.

If the minimal requirements fulfilled, it enables links to demo scripts.

Customizing demo scripts

The demo scripts have the following customization points:

  • $evaluation variable switches between trial (pd4ml_demo.jar) and non-trial (pd4ml.jar) PD4ML libraries. Set it to 0 after you purchased and deployed pd4ml.jar
  • $jar variable allows to specify location of PD4ML jars. In the examples it is set to ../pd4ml_demo.jar as long as the library is in the parent directory.
  • $java variable specifies Java executable path. If you have correctly defined  $PATH on the server, the value may remain java. Otherwise you would need to specify exact Java interpreter location i.e. /usr/local/bin/java
  • $url is URL to convert to PDF.

PHP configuration does not allow to run external applications

As the last resort the package includes a couple of CGI scripts. probe.pl is for environment test and pd4ml.pl is a general purpose converter. The converter expects source document URL as a 'url' HTTP parameter.

Copy the scripts to CGI-BIN directory of the server and make sure the file permissions allow the scripts to run. On most UNIX-derived systems 755 file permission mode is expected.

After that adjust $jar variables of the scripts to point to the actual pd4ml(_demo).jar location. The script execution from PHP is more-less identical to execution of pd4ml.php in the example below.

"As PDF" button from scratch

Below is a sample implementation of "As PDF" button, which can add to any PHP page its PDF view.

First we need  to create a converter PHP (let's call it pd4ml.php).

<?
  header("Pragma: cache");
  header("Expires: 0");
  header("Cache-control: private");
		
  if (array_key_exists('url', $_POST)) {
		
    header('Content-type: application/pdf');
    header('Content-disposition: inline');
    //header('Content-disposition: attachment; filename=test.pdf');
		
    // UNIX version
    passthru('java -Xmx512m -Djava.awt.headless=true ' . 
      '-cp pd4ml_demo.jar Pd4Cmd</b> \'' . $_POST['url'] . '\' 800 A4'); 
		
    // Windows version
    // passthru('java -Xmx512m ' .
    // ' -cp pd4ml_demo.jar Pd4Cmd \"' . $_POST['url'] . '\" 800 A4');

  } else {
    echo 'invalid usage';
  }
?>

The converter utilizes Pd4Cmd command line tool, which is a part of PD4ML library starting from v3.6.0.

For the particular script pd4ml_demo.jar must be in the same directory where pd4ml.php is (or the actual JAR path needs to be reflected in -cp pd4ml_demo.jar command line part). The script expects the source URL is passed as an HTML form variable named url.

The next step is to create the button on the page you want add PDF view to.

<?php
// the function determines the current page URL
function curPageURL() {
  $pageURL = 'http';
  if ($_SERVER["HTTPS"] == "on") {
	$pageURL .= "s";
  }
  $pageURL .= "://";

  if ($_SERVER["SERVER_PORT"] != "80") {
    $pageURL .= "localhost:".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
  } else {
    $pageURL .= "localhost".$_SERVER["REQUEST_URI"];
  }
  return $pageURL;
}
?> 
		
<!-- ... your HTML code here ... -->

<!-- the button -->
<form action="pd4ml.php" method=post>
<input type=hidden value="<?php echo curPageURL(); ?>" name=url>
<input style="pd4ml-display: none; pd4ml-visibility: hidden"
    type=submit value="<b>Get the invoice as PDF</b>">
</form>

The minimalistic PHP code determines on-a-fly the page URL and stores it as hidden url parameter.

A button press will send the parameter to pd4ml.php and force PDF generation.

Useful info:

  • In order to deploy the PDF generating solution you need to copy pd4ml.jar (or pd4ml_demo.jar) and ss_css2.jar from PD4ML distribution and pd4ml.php file to any PHP-enabled directory of your web server.
     
  • PD4ML-specific style="pd4ml-display: none; pd4ml-visibility: hidden" excludes the button from the resulting PDF layout.
     
  • If you deploy the application to a server, which hosts multiple web sites, "localhost" server address cannot be distinct. Please use your actual server name in curPageURL()instead of it.
  • There are two places, where you can control PDF page margins. Default HTML document margins can be changed with BODY { margin: 0 } CSS property. PDF margins (insets) can be impacted via Pd4Php command line parameter -insets TOP,LEFT,BOTTOM,RIGHT,units. For example: -insets 10,20,10,10,mm
     
  • Page orientation can be changed from the default PORTRAIT with -orientation LANDSCAPE command line parameter
  • PD4ML Pro feature: you can define page headers/footers with HTML code like the following
    <pd4ml:page.header><img src="logo.gif"> page $[page] of $[total]</pd4ml:page.header>
  • If you need a generated PDF not to be sent to clients browser, but saved to the disk, add -out /generated/file/location/file.pdf command-line parameter and remove header('Content-type: application/pdf'); directive in pd4ml.php.

See also: