Effective PDF Generation in Drupal

By Chris Ward

A few months ago I had a client requirement for PDF generation, in this case to generate certificates that could be viewed online or printed. I spent some time looking into the best Drupal options available and picked up some advice along the way on how best to accomplish these aims. After mentioning my results to several people, it seemed that PDF generation was a common requirement and now I have the same need again on a personal project, so it seemed a good case study to walk you through what I found.

Why not just print?

If your requirements are simple, it may be easier to just to tell your website users to print and there’s nothing stopping them doing this. If we want a level of control over what is printed or we want to distribute files for printing, then we need to look into other options.

Web vs Print

PDF generation takes a slight change of mindset. As web developers, we have spent a lot of time convincing designers from a print background to stop producing pixel perfect designs that will be difficult to reproduce on the web. If you want to introduce PDF generation or any form of high designed print output, then we need to relearn some of our old skills we left behind. The nature of print means that it is precise and often needs pixel (or millimeter) perfect design.

What am I trying to accomplish?

I am currently working on a board game and I want to allow players to be able to create their own cards that can be shared on the website and printed for use in the game. We have a specific size and layout that these cards will always be and need to conform to, here’s the initial design that we will partially recreate:

PDF options in Drupal

There are two options in Drupal for creating PDFs. The Print module and Views PDF. Views PDF initially seemed the better option as it would allow us to leverage the power of views and the myriad options it offers. However, it has the PHP module as a dependency and as far as I know, is reliant on the eval() function. PDF generation has the potential to be a server intensive task and this method seemed inefficient to me, aside from my reluctance to ever have any kind of PHP evaluation module enabled in Drupal.

This caused me to settle on the print module, which is also better supported and offers many other options for output that may prove useful.

Next we need to decide on our PDF generation library, I am going to suggest you use wkhtmltopdf and explain why later, as I want to build something to compare first. Do this by visiting the wkhtmltopdf website and follow the instructions for your setup. Remember it will need to be installed on local and production sites. After installing you need to create an alias to the wkhtmltopdf executable into your Drupal libraries folder, i.e.:

ln -s /usr/bin/wkhtmltopdf /var/www/sites/all/libraries/wkhtmltopdf

If you are installing under Ubuntu, I ran into some issues with the official archive, I recommend installing manually from the links above.

Configuring print module

Lets start with general settings at admin/config/user-interface/print/common:

  • Logo Options, Footer Options: Turned off for my example.
  • Keep the current theme CSS: Enable this for theme consistency and less work.

Let’s set how and where we want the links to display to reach our PDF / Print versions, admin/config/user-interface/print/ui.

I am setting mine to be displayed in a block so I can have more control over layout.

The overall configuration options for PDF output are at admin/config/user-interface/print/pdf

I recommend these settings:

  • Open PDF in: New browser window
  • Paper size and orientation: Whatever is appropriate for you. For now I’m using A7 for my card, it’s not quite the same, but close enough for this demo.
  • Caching: I am yet to determine quite how effective this is, but usual rules apply, keep off during development and on in production
  • File name: I will use [site:name] - [node:title], you can use tokens here.

Looking at wkhtmltopdf specifics, admin/config/user-interface/print/pdf/wkhtmltopdf.
As wkhtmltopdf is a more advanced tool, it’s a command line based configuration, about which you can find more details here.

Here are some extras I added:

--margin-bottom 0m --margin-left 0m --margin-top 0m --margin-right 0m --dpi 300

This ensures that we have no margins added by wkhtmltopdf and can rely on our CSS output. We are also rendering at 300dpi for print.

A quick note on images. There are options for setting image dpi rendering here, but of course if someone uploads a 72dpi image and it is upscaled to 300dpi, it will look poor. Getting this right is a combination of configuration and user training.

Creating the HTML

The print module works by recreating HTML markup as other output formats. I find it easier to create the markup and CSS that will result in this output first. In my case this is affecting the default output of my content type, but this could be kept separate through the use of view modes or the print module’s own print output. Below is my content type – I have added a couple of the extra fields that my content type needs, but not all of them:

If you want, the print module also supplies it’s own custom view mode so that we could duplicate the same display or use in combination with techniques mentioned above.

Creating Styles.

The print module comes with its own style sheet (print.css, found in the module folder) that you can use to create styles that only apply to the print module rendered versions of nodes. You will need to add a copy to you theme and add them to your theme’s .info file in the usual way.

If you checked the option Keep the current theme CSS as mentioned above then the print module will use your main theme styles and then check the print.css file for any overrides that you only want in print module rendered output. This makes the most sense to me and feels like the tidiest option. If you don’t use this option then the print.css file is the only style sheet that will affect your output. The rest of this example will assume it is enabled.

Here is a simplified HTML version of the design we saw earlier:

I am using a bootstrap sub theme which comes with its own markup that may be different from your theme. I have some custom fonts loaded through font-your-face and created a custom image style for the image, these field names also represent my fields added above. Image styles don’t let you define sizes in centimeters, to get the right size in pixels I used this tool.

We have a particular print size we are trying to accomplish. You can specify sizes in CSS in a variety of units, so in our case I am using centimeters.

Here is my CSS:

//This is my main content area, will be different in other themes and in mine covers the regions that appear for logged in and anonymous users
    .node-type-event-card .main-container section.col-sm-9,
    .node-type-event-card .main-container section.col-sm-12 {
      border: solid 1px #000000;
      width: 6.8cm;
      height: 9.3cm;
      padding: 0.681cm;
    //The card title
    .node-type-event-card .main-container {
      text-align: right;
      margin: 0;
      font-size: 14px;
    //Sets card padding
    .node-type-event-card .main-container .content {
      padding: 20px;
    //Formats the field contents
    .node-type-event-card .main-container .content .field {
      color: black;
      margin-top: 10px;
      margin-bottom: 10px;
    .node-type-event-card .main-container .content .field-name-body {
      font-size: 12px;
      text-align: center;
    .node-type-event-card .main-container .content .field-name-field-image img {
      width: 100%;

Here is how the PDF output currently looks:

Not quite right.

This is because the print module is using our theme but a different tpl file, print.tpl.php. Copy it from the module and into your theme so we can make some changes. You can add --format to specify the output format, i.e. print--pdf.tpl.php.

The main reason we want to edit this is that the print module by default prints a bunch of links at the top of the page and some hr tags that we don’t want and can’t remove in the UI, so let’s tidy it up. Here is my final HTML:

    <html xmlns="" xml:lang="<?php print $language->language; ?>" version="XHTML+RDFa 1.0" dir="<?php print $language->dir; ?>">
        <?php print $head; ?>
        <base href='<?php print $url ?>' />
        <title><?php print $print_title; ?></title>
        <?php print $scripts; ?>
        <?php if (isset($sendtoprinter)) print $sendtoprinter; ?>
        <?php print $robots_meta; ?>
        <?php if (theme_get_setting('toggle_favicon')): ?>
          <link rel='shortcut icon' href='<?php print theme_get_setting('favicon') ?>' type='image/x-icon' />
        <?php endif; ?>
        <?php print $css; ?>
        <?php if (!empty($message)): ?>
          <div class="print-message"><?php print $message; ?></div><p />
        <?php endif; ?>
        <?php if ($print_logo): ?>
          <div class="print-logo"><?php print $print_logo; ?></div>
        <?php endif; ?>
        <?php if (!isset($node->type)): ?>
          <h2 class="print-title"><?php print $print_title; ?></h2>
        <?php endif; ?>
        <div class="print-content"><?php print $content; ?></div>
        <div class="print-footer"><?php print theme('print_footer'); ?></div>
        <?php if ($sourceurl_enabled): ?>
          <div class="print-source_url">
            <?php print theme('print_sourceurl', array('url' => $source_url, 'node' => $node, 'cid' => $cid)); ?>
        <?php endif; ?>
        <?php print $footer_scripts; ?>

And my CSS (print.css) is much the same as the previous CSS but reflects the page structure:

// I have found that clearing the margins helps with the PDF generation    
    body {
          margin: 0;
          padding: 0;
        html {
          margin: 0;
        .print-content .node {
          border: solid 1px #000000;
          width: 6.8cm;
          height: 9.3cm;
          padding: 0.681cm;
          font-family: 'VT323';
          font-size: 20px;
        .print-content h2 {
          text-align: right;
          margin: 0;
          font-size: 14px;
        .print-content .content {
          padding: 20px;
        .print-content .content .field {
          color: black;
          margin-top: 10px;
          margin-bottom: 10px;
        .print-content .content .field-name-body {
          font-size: 12px;
          text-align: center;
        .print-content .content .field-name-field-image img {
          width: 100%;

Now, what’s wrong with the fonts? Unfortunately we can’t use custom fonts that are on a remote server (in this case Google Fonts). I’m not sure if this is an issue with the print module (looking at print.tpl.php, it loads styles in a different way) or if it’s a wkhtmltopdf issue. I found a few other potential paths you may be able to follow if you can’t download your font, but I will assume you can and show a foolproof method.

Download your fonts and add them locally, I’m putting them into theme/fonts, and add the following CSS at the top of your print.css file.

@font-face {
      font-family: 'VT323';
      src: url('../fonts/VT323-Regular.ttf');
      font-style: regular;
      font-weight: 400;


Well, we still have a margin, but that’s because we’re not using the right paper size. So, that aside, this is pretty great!

Why wkhtmltopdf?

Many of you may be familiar with TCPDF and dompdf – they are commonplace and reasonably lightweight. I tried TCPDF and here are the results:

Not as accurate as wkhtmltopdf out of the box, so I tried dompdf:

Hmm. This is because I am using custom fonts and documentation mentions that with changes I can get this working. However, wkhtmltopdf worked for me straight away with no tweaking or sifting through documentation. It aims to produce a complete copy of HTML so is generally 99% accurate. With my last project (which was far more complicated) I found a few problems when using a couple of CSS techniques that were more appropriate to screen, but even those were fixable.

Whilst wkhtmltopdf offers by far the best PDF output, setup involves installing an executable and this may make it unsuitable for many of you. However, I will make the assumption that if you are working with Drupal and need to achieve this level of layout complexity then you have access to your own server or VPS.

Have you tried any form of PDF (or other formats) generation with Drupal? I would love to hear tips and tweaks that you found.


I had tried getting wkhtmltopdf working a few months ago; however, I was unable to get it working. Seemed to be a problem at the Drupal integration level since wkhtmltopdf worked at the command line level. I was curious whether you had to do any specific tweaking to get wkhtmltopdf working with Drupal (e.g. had to use specific version of wkhtmltopdf, etc.)?


Hmm, the only tweaking I did on the drupal side was the dpi and margins mentioned above. You sym linked the executable into the libraries folder?

I am using : wkhtmltopdf 0.12.1 (with patched qt)

Which is on a Vagrant box running Ubuntu 14.04

What's your setup? And what errors do you get in logs?


If you want something that is much more scalable and without limitations of html5/css3 inclusions, i encourage you to take a look at docraptor third party service. It's nominal cost and I created a plugin to the print module that works quite well. My issue with the other libraries were limitations in recognized styles as well as performance. I can send several hundred pages to docraptor with no issues. Everything else i tried failed on larger documents.


Thanks for that, I wasn't aware of the option. Have you had any issues with replicating layouts?


I haven't tried this in Drupal, but I was recently successful in using FPDF in WordPress. I assume it will be a little more challenging in Drupal, but I was more than happy with my WP results.


No problems in replicating layouts with Docraptor. FYI, docraptor runs on princexml. I chose docraptor because princexml as a standalone has to run as an executable on the server which i can't do in a cloud hosting environment and its also very expensive for license. So, docraptor acts as a middleman to generate the pdfs on their end and return them to your site.

Additionally, you can create pdf bookmarks, dynamic table of contents, footers with page count, etc... You can see some pretty nice samples here: All of the supported css is listed on that site as well.


I've been battling this issue for years. I started with htmldoc, and then went to wkhtmltopdf. While the second was better than the first, both of them require setting up a binary on the server which means that the code is not portable, especially in a shared hosting environment.
I then tried PhantomJS, which is better again, and you can install the binary as part of your source tree, however it still isn't all that great.

Which brings us to PHP libraries.
DomPDF had various issues, I struggled to get it working properly (as you did).

What I'm using now is mpdf, which I've found to be fantastic. It supports CSS properly (unlike wkhtmltopdf), is totally portable with your codebase, and to be honest I haven't found any issues with it. It just works really well.

I'd really recommend trying it out.


Thanks for all your feedback everyone! I had mainly followed the path of what was listed on the print module page, but as I continue my project I may look into some of these other options.

Does anyone have any extra tips for getting layouts working well in 'print', I assume/hope that the article still applies with any of these other options and the CSS advice.


I had a similar requirement a few weeks back and decided to write a new module that was much smaller than Print. The module is called Entity Print and it uses wkhtmltopdf. The main advantages are:

  • It works with any entity type, not just nodes.
  • Much lighter, the whole module is less than a few hundred lines of code.


I remember coming across this module and there was a reason I didn't pick it at the time, can't quite remember why though. I'm wondering if it wasn't stable when I was looking. May give it a go with this project instead and report back.


Yes it likely wasn't tagged. I'd love some feedback if you have time to test it.

The main issue right now is the amount of setup phpwkhtmltopdf requires which I depend on.



Because We Like You
Free Ebooks!

Grab SitePoint's top 10 web dev and design ebooks, completely free!

Get the latest in PHP, once a week, for free.