Generating PDF - Wkhtmltopdf and ignoring footer or header

Stephan Köllen 17-01-2019


Today I came across an issue while adding a new feature for our pdf-invoice creation in one of our apps. This took me way longer to figure out than it should have, so maybe you'll find this helpful:

Why adding header and/or footer content to every page of an pdf, using wkhtmltopdf via laravel snappy, did not work and how I made it work.


Starting situation

I use some libraries that interact and generate our invoices based on laravel blade views I provide them. The set-up:

Wkhtmltopdf was installed via apt:

# install version 0.12.4 of wkhtmltopdf
sudo apt install wkhtmltopdf

Within laravel you can come up with something like this to generate an invoice:

public function show(Order $order)
    SnappyPdf::loadView('invoices.invoice', ['order' => $order]);
    return $pdf->stream();

This show function simple accepts and order instance and prepares a pdf to view in the browser. The view invoice.blade.php can use the order information to display details like prices, shipping address etc..

So far so good, but I needed additional functionality.

Code preperation

Since everything worked as expected with my current invoice generator, I prepared our events and backend that generates invoices.

I wanted to repeat the header and footer to appear on every page of the invoice, also when large content leads to page breaks.

public function show(Order $order) 
    $footer = view('invoices.footer')->render();
    $header = view('invoices.header')->render();

    $options = [
        'footer-html' => $footer,
        'header-html' => $header,
    $pdf = SnappyPdf::loadView('invoices.invoice', ['order' => $order]);
    return $pdf->stream();

Wkhtmltopdf provides the handy options to insert header and/or footer content on every page generated. This options --header-html and --footer-html can be utilized via e.g. ->setOption('footer-html', $footer) or an array, like in the example above (and with setOptions()).

This should work. But didn't. (Other tips are for sure helpful: e.g. adding document margin or add a <!DOCTYPE html> to your footer and header, but I already did that.)

Wkhtmltopdf package, patches and other helpful insights

I had a little trial and error session in order to figure out what was happening. It's always the last place you look ;).

It turned out that I needed to install the "qt patched" version of wkhtmltopdf. Before that my header and footer options were simply ignored. Found that out with running wkhtmltopdf via the command line. So you may try that, if you find yourself in that situation.

In order to get the new version directly from wkhtmltopdf you might want to remove your currently installed package:

sudo apt purge wkhtmltopdf

After that you should find the right version for you, as of version 0.12.5 on github and install it with:

# make a directory
mkdir wkhtmltopdf_0-12-5
cd wkhtmltopdf_0-12-5/

# Download

# Install the package from your downloaded file
sudo apt install ./wkhtmltox_0.12.5-1.bionic_amd64.deb

Verify the new version with wkhtmltopdf --version. Tip: If your using laravel + snappy, you should check which binaries you're referencing in config/snappy and see if you're using the right version, e.g.:

/usr/local/bin/wkhtmltopdf --version

# might be different to

/usr/bin/wkhtmltopdf --version

So use the right binary to do the job :).


If you're using wkhtmltpdf (with laravel snappy for example) and your header and/or footer html is ignored and you cannot get this to show on your generated PDF, you may try the following:

  1. Do you have the qt patched version of wkhtmltopdf installed? You may check this from the command line (use the same binary as for example your application uses. In Laravel snappy this is configured in config/snappy.php):
/usr/bin/wkhtmltopdf --version

You can try to use the options like adding a header from the command line:

/usr/bin/Wkhtmltopdf --header-html test.pdf

You can install wkhtmltopdf from their website and github. See above for instructions.

  1. Add <!DOCTYPE html> to your footer and header file and check if they appear.
  2. Add margins to check if your content becomes visible.

I hope this works for you.