Potential pitfalls when using Dompdf and how to fix them

In a current project, I had to generate PDF documents based on custom entities on a Drupal 8 page. Obviously I decided to use the great Entity Print module together with the very popular Dompdf library. Formatting PDF has always been an annoying task, even if you use HTML and CSS based library. But they are getting better and better. After I have been using MPDF quite a long time in the past, I now tried Dompdf, as it seems to have the better CSS support, and it's also the chosen default library of Entity Print and gets shipped with it (when you do Composer installation). And I must say, it really works great. In combination with the Entity Print's debug view, you can get rather quick results, when building a PDF template.

Unfortunately, two problems cost my quite a lot of time to find out. And they are quite easy to trigger, so I'll share it with you now:

1. Tiny images in tables

I've made good progress in styling the PDF output, until I've inserted images and tried to render the PDF then: the images were even tinier than Donald's hands! ;)

I've finally found a bug report on Dompdf's Github page, telling that images inside tables can get really very small. Another user reported the same problem, while the project maintainer couldn't find a way to reproduce the problem. I was rather guessing that this has to do with different system environment, especially different PHP versions. My first reaction was to work around the problem and change the HTML markup because in this place I've decided to use a table for getting a two-column layout, as this has always been the easier approach when dealing with e-mail or PDF templates. However I knew, that I'll add a "real" table containing images later on. So I reported that I encountered the problem too. After quick response by the maintainer, I've decided to have a closer look on the problem.

Finally I've found out that it wasn't the <img> alone inside a table that is causing the problem. It's finally triggered, when you have set a max-width CSS property on the image. Unfortunately Entity Print was shipping with a default CSS (which you can disable though) containing a "max-width: 100%" rule on <img> elements - which is generally a good option (and the result of the solution for this issue).

Knowing this, it was easy to fix the problem by overriding the max-width property for images inside tables and setting the max-width to "none". I've opened up an issue for Entity Print and my fix has already been committed :)

2. Header and/or footer on every page

Adding a page header or footer on every page is basically very easy with Dompdf just by setting the position of the element to "fixed" - at least theoretically. Because there are at least two preconditions that must be met  and are not so obviously documented (or not at all):

  • The element(s) have to be part of the first rendered page. So adding a footer to the end of your markup is a bad idea. You should do it at the beginning. Since it's positioned fixed, there's no optical difference. However DomPdf needs this information during the rendering of the first page, otherwise it'll be too late (to have it on every page).
  • This one was hard to find out, haven't found it on any Stackoverflow page or Github issue or elsewhere, only by debugging: the footer or header must be a direct child of the body element in order to get it on every page!

I had to fight with the second requirement until I found out. I've added the footer information directly inside the entity template, while I left entity_print's page template as is. And there we have the div.page element per default. So you either have to add your header/footer in the entity-print template before div.page, or if you wanna render it in your node/entity template directly, you have to take care to override the entity-print template to not having any wrapper element!

Besides of these problems, it was really great to work with the library. The combination Drupal + Twig + Entity Print + Dompdf is a really powerful one :-)

Neuen Kommentar schreiben