Create a webservice for generating pdf's from html

February 23, 2015

Creating pdf’s from a html page is’t all that fun in PHP. There are some nice classes that help you do this, but is just not it. I will show you how to setup a webservice to a achieve this. You can always use it directly from you application if you don’t like webservices.

Why a webservice?

This is rather simple. I hate updating, maintaining and debuging the same peaces of functionality over and over again.

What utility to use?

I am going to use wkhtmltopdf as it is the one I like most. wkhtmltopdf: Simple shell utility to convert html to pdf using the webkit rendering engine, and qt. Install wkhtmltopdf

I am using the static binaries to complete the job, as they are by far the easiest to update.

Download the latest static binary from the developers page and place it wherever you like, I prefer ~/bin.

Give it a try.

On linux:

$ ./wkhtmltopdf-xxx

On Mac OSX

$ wkhtmltopdf.app/Contents/MacOS/wkhtmltopdf  -V

It it gives you a nice output of the Name, License and the Author you are ready for the next step. Using it from PHP

I wrote a little class to access the binary. Download it and place it in you webservices project.

Now we need to make a symlink to the project so the class can access it.

$ ln -s /path/to/wkhtmltopdf wkhtmltopdf

Now create a php file and paste this code.

<?php

// Add some security
$allowedIps = array(
  '127.0.0.1', //localhost
);
if (!in_array($_SERVER['REMOTE_ADDR'], $allowedIps)) {
  header('HTTP/1.1 401 Unauthorized');
  echo 'Error: Please log in.';
  exit(0);
}

// Merge the given params into the defaults
$params = array_merge(array(
  'T' => '0',
  'R' => '0',
  'B' => '0',
  'L' => '0',
), $_GET);

if (isset($params['html'])) {
  $url = base64_decode($params['html']);
  unset($params['html']);
}
elseif (isset($params['url'])) {
  $url = $params['url'];
  unset($params['url']);
}
else {
  header('HTTP/1.1 400 Bad Request');
  echo 'Error: Please include a url of some encoded html.';
  exit();
}
$name = 'file';
if (isset($params['name'])) {
  $name = $params['name'];
  unset($params['name']);
}

require_once('wkhtmltopdf.class.php');
$wkhtmltopdf = new wkhtmltopdf();
$wkhtmltopdf->setBuildPath(__DIR__ . '/tmp');
$wkhtmltopdf->sendFile(false);

foreach( $params as $name=>$value) {
  $wkhtmltopdf->addParam($name, $value);
}

if (isset($html)) {
  $string = $wkhtmltopdf->buildFromHtml($html);
}
elseif (isset($url)) {
  $string = $wkhtmltopdf->buildFromUrl($url);
}

header("Content-Type: application/pdf");
header("Content-Length: " . mb_strlen( $string ) );
header('Content-Disposition: inline; filename="' . basename($name) .'.pdf";');
echo $string;
exit(0);

Now you can navigate to you webservice and it should give you a nice pdf.

http://webservices.dev/wkhtmltopdf/webservice.php?url=google.com

Note: This is only an example and might need some further improvements before using it in a production environment.

comments powered by Disqus