wkhtmltopdf – Add Header or Footer to only First or Last Page

June 7th, 2012 - Posted by Steve Marks to PHP, Web Development.

I’ve come across many HTML-to-PDF classes in my time, but by far my preferred option is wkhtmltopdf. It does what it says on the tin, supports complex layouts and uses the webkit rendering engine for nicely formatting your PDF’s.

One feature however that isn’t supported, or at least isn’t documented in the Wiki, is how to add a header or footer to only the first or last page, or indeed, any particular page(s). The functionality does exist to add a header or footer, but by default this adds it to every page.

After a bit of research I was able to find out two important facts regarding the headers and footers:

1) When an external HTML file is used as a header or footer, a set of default parameters are passed in (ie. total number of pages, website address).
2) Javascript is supported in header and footer files.

Knowing the above, I was now able to get the required output. After a bit of trial and error I came up with the code below that adds a footer to just the last page:


$pdf->set_options("--footer-html my-footer.html");

The HTML Footer (my-footer.html)

   function subst() {
      var vars = {};
      // explode the URL query string
      var x = document.location.search.substring(1).split('&');
      // loop through each query string segment and get keys/values
      for (var i in x)
         var z = x[i].split('=',2);
         vars[z[0]] = unescape(z[1]);

      // an array of all the parameters passed into the footer file
      var x = ['frompage', 'topage', 'page', 'webpage', 'section', 'subsection', 'subsubsection'];
      // each page will have an element with class 'section' from the body of the footer HTML
      var y = document.getElementsByClassName('section');
      for(var j = 0; j < y.length; j++)
         // if current page equals total pages
         if (vars[x[2]] == vars[x[1]])
            y[j].innerHTML = "I'm a footer only on the last page";
<body onload="subst()">
   <div class="section"></div>

There we have it. The same logic could also be applied for headers, or if you wanted to show the footer on another specific page rather than only the last one.

Tags: ,
This entry was posted on Thursday, June 7th, 2012 at 10:54 pm by +Steve Marks and is filed under PHP, Web Development. You can follow any responses to this entry through the RSS 2.0 feed.

Fear not, we won't publish this

Comments (5)
  1. This essential works, but you don’t seem to be able to reclaim the space allocated to the header if you choose to remove it. Variable top margin space does not seem to be achievable.

    Repeated headers can also be implemented by wrapping your content in a table and using thead tags. You can prevent headers for trailing pages, by excluding their content from the table. It’s not bulletproof – thead tags are buggy in wkhtmltopdf, but some people might find this a better solution.

  2. Anonymous says:

    vars[x[2]] == vars[x[1]]

    vars is a JavaScript object. This code above is unnecessarily unreadable. You should just write: vars[‘page’] == vars[‘topage’]

  3. Olivier says:

    Thanks! you same my day :)

  4. Paul Fromage says:

    Thanks ! It’s works fine ;)
    I just put

    if (vars[x[1]] == vars[x[2]])
    document.getElementById(‘page’).style.cssText = ‘display:none;’;

    instead of

    var y = document.getElementsByClassName(‘section’);
    for(var j = 0; j < y.length; j++)
    // if current page equals total pages
    if (vars[x[2]] == vars[x[1]])
    y[j].innerHTML = "I'm a footer only on the last page";

  5. Rich says:

    Thank you for sharing this as this was exactly what I was looking for to get me headed in the right direction.