wkhtmltopdf setup guide with KnpLabs Snappy support on Debian
This document will show you how to get wkhtmltopdf working on Debian using KnpLabs Snappy. If you try and install from distribution you won’t get some of the latest features of wkhtmltopdf like {shell}–javascript-delay{/shell}. This guide will help you install the latest version {shell}0.11.0 rc1{/shell}. This guide assumes you have LAMP already installed and that you can run {shell}sudo{/shell}.
1. Installing dependencies
Before you install you will need to have X11, gcc and openssl installed.
|
1 |
sudo aptitude install openssl build-essential xorg libssl-dev libxrender-dev |
2. Getting the source
The bleeding edge build from git didn’t work for me so let’s download the latest stable release build.
Let’s make a temp directory
|
1 |
mkdir ~/temp && cd ~/temp; |
Download and extract the code by running
|
1 2 3 |
wget https://wkhtmltopdf.googlecode.com/files/wkhtmltopdf-0.11.0_rc1.tar.bz2; tar -xvf wkhtmltopdf-0.11.0_rc1.tar.bz2; ln -s wkhtmltopdf-0.11.0_rc1 wkhtmltopdf; |
Be sure to change the version number to the latest source release.
3. Installing QT
Before you can compile wkhtmltopdf you need to have QT installed, again you have two options: You can install the QT from your distribution, this will be fast but your wkhtmltopdf build will not have all the features of the static build, or you can compile QT your self, this takes a long time but you will get all the features.
NOTE: I would suggest installing from distribution (3.b). I tried installing from source and it didn’t work.
3.a Installing QT from your distribution
|
1 |
sudo aptitude install libqt4-dev qt4-dev-tools |
You must now run qmake in the wkhtmltopdf folder.
|
1 2 |
cd wkhtmltopdf; sudo qmake-qt4; |
3.b Installing QT yourself
First check out the source
|
1 2 3 4 |
git clone git://gitorious.org/+wkhtml2pdf/qt/wkhtmltopdf-qt.git wkhtmltopdf-qt; cd wkhtmltopdf-qt; git checkout staging; QTDIR=. ./bin/syncqt; |
Qt must be configured, a good set of configuration options for qt can found by looking at the output of
|
1 2 |
cat ../wkhtmltopdf/static_qt_conf_base ../wkhtmltopdf/static_qt_conf_linux | sed -re 's/#.*//'; ./configure -nomake tools,examples,demos,docs,translations -opensource -prefix "../wkqt"; |
And Qt compiled and installed (this will take a while)
|
1 2 3 |
sudo make -j3; sudo make install; cd ..; |
You must now run qmake in the wkhtmltopdf folder.
|
1 2 |
cd wkhtmltopdf; ../wkqt/bin/qmake; |
4. Compiling and installing wkhtmltopdf
Now all you need to do is compile and install wkhtmltopdf
|
1 2 |
sudo make; sudo make install; |
5. You man need a few symbolic links
For some reason Debian wants execute from
|
1 |
/usr/local/bin/wkhtmltopdf |
. So do the following to fix the issue.
|
1 2 |
ln -s /bin/wkhtmltopdf /usr/local/bin/wkhtmltopdf ln -s /bin/wkhtmltoimage /usr/local/bin/wkhtmltoimage |
6. Check to see if it works
Run the following. If you get the error {shell}”Cannot connect to X server”{/shell} then continue to number 7.
|
1 |
wkhtmltopdf http://www.google.com test.pdf |
7. Fixing “Cannot connect to X server”
We need to run it headless on a ‘virtual’ x server. We will do this with a package called xvfb.
|
1 |
sudo aptitude install xvfb |
8. Create a shell script wrapper for wkhtmltopdf
We need to write a little shell script to wrap wkhtmltopdf in xvfb. Make a file called wkhtmltopdf.sh using the following:
|
1 |
echo 'xvfb-run -a -s "-screen 0 595x842x16" /bin/wkhtmltopdf $*' >> /usr/bin/wkhtmltopdf.sh; |
Now let’s make it executable.
|
1 |
sudo chmod a+x /usr/bin/wkhtmltopdf.sh |
Give step 6 a try again.
Using KnpLabs Snappy
Here I will show you how to use KnpLabs Snappy. Snappy is a PHP5 library allowing thumbnail, snapshot or PDF generation from a url or a html page. It uses the excellent webkit-based wkhtmltopdf and wkhtmltoimage available on OSX, linux, windows.
1. Download snappy from github
|
1 |
wget https://github.com/KnpLabs/snappy/archive/master.tar.gz && tag -xvf master.tar.gz; |
2. Copy the {shell}snappy-master/src{/shell} folder to your webroot.
3. Create a html file for your template
Save this file as {shell}hello.html{/shell} in your webroot. This will be used as your template. It contains a chart from hicharts.js.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Page Title</title> <script src="http://code.jquery.com/jquery-1.8.3.min.js"></script> <script src="http://code.highcharts.com/highcharts.js"></script> <script src="http://code.highcharts.com/modules/exporting.js"></script> </head> <body> <div id="container" style="width: 595px; height: 842px; margin: 0 auto"></div> </body> <script> $(function(){ var chart; $(document).ready(function() { chart = new Highcharts.Chart({ chart: { renderTo: 'container', type: 'column', animation: false }, plotOptions: { series: { animation: false }, column: { stacking: 'normal' } }, title: { text: 'Total fruit consumtion, grouped by gender' }, xAxis: { categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'] }, yAxis: { allowDecimals: false, min: 0, title: { text: 'Number of fruits' } }, tooltip: { formatter: function() { return '<b>'+ this.x +'</b><br/>'+ this.series.name +': '+ this.y +'<br/>'+ 'Total: '+ this.point.stackTotal; } }, series: [{ name: 'John', data: [5, 3, 4, 7, 2], stack: 'male' }, { name: 'Joe', data: [3, 4, 4, 2, 5], stack: 'male' }, { name: 'Jane', data: [2, 5, 6, 2, 1], stack: 'female' }, { name: 'Janet', data: [3, 0, 4, 4, 3], stack: 'female' }] }); }); }); </script> </html> |
Notes
In order for wkhtmltopdf to correctly print the chart, it is advised to remove any animations on hicharts.js objects. You will need to set the {javascript}animation{/javascript} property to false for both the {javascript}Chart{/javascript} object and the {javascript}plotOptions.series{/javascript} object.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
chart: { renderTo: 'container', type: 'column', animation: false }, plotOptions: { series: { animation: false }, column: { stacking: 'normal' } }, |
4. Create the following php file in your webroot.
Save this file as {shell}generate-pdf.php{/shell} in your webroot.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php require_once 'src/autoload.php'; use KnpSnappyPdf; $snappy = new Pdf(); $snappy->setBinary('/usr/bin/wkhtmltopdf.sh'); $snappy->setOption('javascript-delay', 500); header('Content-Type: application/pdf'); header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1 header('Pragma: public'); header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); header('Content-Disposition: inline; filename="hello.pdf";'); echo $snappy->getOutput('hello.html'); ?> |
Notes
Note the use of {php}javascript-delay{/php}:
|
1 |
$snappy->setOption('javascript-delay', 500); |
This will allow you to delay the printing of the pdf for a specified amout of time defined by ms. In this case the delay is set to {php}500ms{/php}. Also the {php}Content-Disposition{/php} is set to {php}inline{/php}. This will allow the pdf to show withing the browser window if the user has a pdf plugin installed. Supported browsers are Chrome and Safari. If the user does not have a supported browser they will be presented with a file download diaglog.
|
1 |
header('Content-Disposition: inline; filename="hello.pdf";'); |
