Printing with DOMPDF
My last programming problem was about printing a report from a web application. In the past I solved it using Internet Explorer’s print templates, but that solution had 2 drawbacks: the first was that it required IE 5.5 or later, the second was that the page customizations (margins, orientation, header and footers) required downloading an ActiveX. This was an easy requirement at the time due to the intranet use of the application.
Now that I have moved to Linux and Open Source software that is no more feasible. I had to find another solution.
The IT market is full of reporting tools for the web but most of them are expensive and require some kind of plug-in, since the browser alone is not capable of giving a precise rendering of the printed page. Yes, CSS has something to say about print media but these properties are mostly ignored by the current bunch of browsers.
And then there is my main requirement: all the software used must be Open Source.
After some thoughts I decided to produce a PDF print for my reports. A quick google search gave me a number of products to try. I could divide them in 3 categories:
- raw PDF libraries
- XSL-FO
- conversion tool from other format (i.e. HTML)
I didn’t even think to take into consideration the first solution. XSL-FO looked appealing in beginning, but when I looked more deeply to what was it about, I gave up. BTW just reading the word XML was enough to make me shiver.
The third approach seemed much simpler. Write the report in HTML, give it to the converter program and send the result to the user. Too good to be true: I didn’t have to learn another language and could even reuse the old reports written for IE print templates. The best known of such tools is htmldoc but unfortunately this is a very crude product. It interprets only HTML 3.2 and no CSS. Not very useful. Other products that I downloaded did not look better that htmldoc. I was somewhat amazed by the fact that such a simple and useful concept, an HTML to PDF converter, did not found a supporter in the Open Source that could produce a decent utility. Until I discovered dompdf. It is an impressive library. It supports most of the CSS directives (the notably exceptions being absolute positioning and floating). The first report that I tried worked like a charm. I took my HTML, passed through this utility and my PDF was there. Ok, I have been too enthusiastic. I found a couple of problems when I tried to bend it to some special needs that I had but nothing that some search in the documentation and in the forum couldn’t solve.
So, to help others that might encounter the same problems I thought to add a few points here to the dompdf FAQ:
1. how can I make it faster?
Up to version 0.5.1, there is a line in the library that uses a call to the uniqid() php function. Since this call is slow and it is done once for each dom node in the document, it slows down the translation in a sensible way. The workaround consists in changing the line 171 in file frame.cls.class:
$this->set_id(uniqid(rand()));with :global $dompdf_unique_id; if (isset($dompdf_unique_id)){ $dompdf_unique_id++; }else{ $dompdf_unique_id = 1; } $this->set_id( $dompdf_unique_id );
Alternatively, change the same line with this:
uniqid ('', true)
2. how can I put some data coming from the DB into the header/footer?
See Q.4 in the official FAQ. In the script, declare the variable you want to use as global, like this:
global $my_var;
3. how can I put a background on every page?
if ($draft) // if TRUE print "DRAFT" across every page
{
$obj_draft = $pdf->open_object();
$pdf->text(200, $h - 300, "DRAFT",
Font_Metrics::get_font("verdana", "bold"),
110, array(0.8, 0.8, 0.8), 0, -52, "Darken", 1);
$pdf->close_object();
$pdf->add_object ($obj_draft, "all");
}
4. I followed the instructions in Q.4 but it doesn’t work?
Check that the tag
<script type="text/php">
is INSIDE the body tag.
5. how do I print a page generated from PHP?
All the examples in the official FAQ use the
$dompdf->load_html($html);
function, where $html is a string containing the document to print. But what if the document is the result of the current PHP page. Here the trick consists in buffering the PHP output and then using the load_html() on the content of the buffer. Like this:
<?php
ob_start(); // start buffering
...
// whatever
...
$dompdf = new DOMPDF();
$out = ob_get_clean(); // get the content of the buffer and clear it
$dompdf->load_html($out);
$dompdf->render();
$dompdf->stream ("Filename.pdf");
?>
6. ERROR: Unable to stream pdf: headers already sent
I came across this error few times. The reason was always due to 3 non visible characters at the beginning of the file, as a consequence of using an editor set with a different character encoding (e.g UTF-8, Latin 1, …).
Try to run the command
hexdump -C filename | less
and see what the initial characters are.
Beware that few editors allow to remove them. Emacs is one of these.
7. ERROR: Nesting level too deep - recursive dependency? in (…)/dompdf/include/table_frame_decorator.cls.php on line 143
This error often occurs when a table spans 2 or more pages. DOMPDF tries to split it and repeat the THEAD on the following page. In doing so, it calls the PHP in_array() function, which gives this error. There are 2 workarounds: one is deleting the TBODY tag, the other is patching the split() function found in table_frame_decorator.cls.php, and adding a 3rd argument (true) to the 3 in_array function calls found there. More or less like the following code:
// If $child is a header or if it is the first non-header row, do
// not duplicate headers, simply move the table to the next page.
if ( count($this->_headers) && !in_array($child, $this->_headers, true) &&
!in_array($child->get_prev_sibling(), $this->_headers, true) ) {
...
} else if ( in_array($child->get_style()->display, self::$ROW_GROUPS, true) ) {
8. ERROR: Frame not found in cellmap
I encountered it when using the CSS attribute ‘page-break-inside: avoid’. A possible workaround is reported in the DOMPDF forum and consists in replacing all occurrences of
throw new DOMPDF_Internal_Exception("Frame not found in cellmap");
with
return false;
I don’t know any possible side effects, but it worked for me till now.
Another fix that worked for me in one occasion was replacing the markup used with the ‘page-break-inside: avoid’, in that case from DIV to P.

July 26th, 2007 at %1:%Jul %p
thanks! I have been using dompdf for about two years now, and i know in the beginning I ran into every problem addressed in this post. This should be helpful, and hopefully it’ll stir up more interest in dompdf from developers… i only wish i were better at programming… benj is amazing!
July 26th, 2007 at %1:%Jul %p
Thank you for the encouragement, psychoactive! I will try to update this FAQ as I progress in the use of this library.
July 27th, 2007 at %1:%Jul %p
Thanks! I’ll be aware of your explanations. i’ve got problems rendering img in the footer.
August 18th, 2007 at %1:%Aug %p
Hi.
I have a tedious problem that I couldn’t to resolve at dompf. I want justify all my html into my flags, I have: my longtext.
Thanks in advance.
August 18th, 2007 at %1:%Aug %p
Hi Felix,
I am not sure I understand your question. Could you give an example of what you are trying to do?
Luca
August 19th, 2007 at %1:%Aug %p
Hi Lucas.
I have a HTML page, it has justify paragraphs but DOMPDF is not rendering this style.
How I can justify the paragraphs correctly?
It seems DOMPDF cannot understand the css style that I’ve defined to.
This is my css:
p {
text-align:justify;
font-size:1em;
margin:0.2em;
padding:5px;
}
Thanks for your reply.
August 19th, 2007 at %1:%Aug %p
Hi Felix,
I tried your style but it runs fine here. That is, it justifies correctly. Can you post the whole page you are trying to print?
Luca
August 20th, 2007 at %1:%Aug %p
Hi Luca.
This is the html code that works for me:
setNumero($monto);
$html =
”
Untitled Document
Nº “.$codigo.”
Mérida, “.$fecha.”
SEÑORES:
“.$contratista.”Ciudad.
Por medio de la presente me dirijo a Usted, en la oportunidad de notificarle que se le (s) ha asignado la ejecución de la obra que a continuación se refiere:
Objeto del Contrato de obra: “.$obra.”
Ubicado en el Municipio: “.$munici.” DEL ESTADO MÉRIDA. PROGRAMA: FIDES 2007.
Código Presupuestario: 04-27-02-12-10-02-4,04-02-02-10 , Monto Sin IVA Bs.: 362.918.379,17
Código Presupuestario I.V.A: 04-27-02-00-00-02-4,03-18-01-01, Bs. 0,00
Monto total de la Obra: El monto a contratar será hasta por la cantidad de ” .$aletra->letra() .” (BS.: “.$monto.”) cuya forma de pago se hará conforme a Ley de Condiciones Generales para la Contratación de Obras, según Decreto Nro 1417, Publicado en Gaceta Oficial del Nro. 5096 de fecha 16 de septiembre de 1996. A fin de proceder a la respectiva contratación le agradezco ponerse en comunicación con la Gerencia de planificación y Gestión del INMIVI, el cual tiene como domicilio la Av. Cardenal Quintero Centro Comercial El Viaducto Nivel Mezzanina a objeto de formalizar todo lo relativo a la contratación respectiva, en un lapso perentorio de 15 días continuos contados a partir de la fecha de la entrega de la presente comunicación, de lo contrario la Asignación queda sin efecto de inmediato, y será reasignada a otro beneficiario. En caso de ser imposible la notificación de la presente queda rescindida de pleno derecho la presente carta asignación, si no se lograre su notificación dentro de los 5 días hábiles siguientes a la emisión de la presente. La administración del Instituto Merideño de Infraestructura y Vialidad puede dejar sin efecto la presente carta asignación, cuando a bien lo considere no dando lugar a indemnización alguna a favor de quien se emite la presente carta asignación, bastando para ello notificar al beneficiario de la presente Carta Asignación mediante notificación o publicación en periódico local o nacional, como a bien lo considere el ente. El beneficiario de la presente Carta Asignación debe cumplir con todos los trámites administrativos previos y de ley para el otorgamiento del contrato, so pena que el Instituto deje sin efecto la asignación librada a su favor y debidamente notificada, cuando a bien lo considere por incumplimiento de los requisitos. El beneficiario de la presente Carta Asignación debe suscribir el contrato conforme a las condiciones que predetermine el INMIVI y la Ley de Condiciones Generales de Contratación de Obras. En caso de negativa del beneficiario a suscribir el contrato que dimana con base a la presente carta asignación, el Instituto dejará sin efecto la asignación y los efectos legales que dimanan de la misma, sin indemnización alguna a favor del beneficiario.
ING. ROBERTO MOLINA
PRESIDENTE
INSTITUTO MERIDEÑO DE INFRAESTRUCTURA Y VIALIDAD (INMIVI)
Notificado Nombre (s) y Apellidos (s)
_____________________________________
Firma:________________________________
Lugar y Fecha:__________________________
Teléfono.______________________________
Av. Cardenal Quintero. CC. El Viaducto, Nivel Mezzanina, Mérida - Venezuela. Telfs.: (0274) 244 2948 - 244 5112
“;
$dompdf = new DOMPDF();
$dompdf->load_html($html);
$dompdf->render();
$dompdf->stream(”carta_Asignacion.pdf”, array(”Attachment” => 0));
?>
Thanks for your help.
August 20th, 2007 at %1:%Aug %p
This is the html’s head
Untitled Document
August 20th, 2007 at %1:%Aug %p
//
Untitled Document
August 21st, 2007 at %1:%Aug %p
Hi Luca.
Can you give me an email address where I can send the complete raw html?, because the blog is processing the html code.
August 21st, 2007 at %1:%Aug %p
luca at priorelli dot com
June 11th, 2008 at %1:%Jun %p
Estoy intentando usar el sistema del script type=”text/php” y no parece que funcione. Mas bien parece que ignora lo que pongo alli ya que no me lo hace.
¿necesito alguna configuracion especial del apache? tengo php5.2
June 20th, 2008 at %1:%Jun %p
I’m trying to create a header for the A4 page format (vertical orientation) with just an image (a corporate logo), to be added to all the pages in the PDF document, without any success. A little suggestion would be welcome, a snippet, a little hint…
Official docs aren’t helpful on this matter, imho.
Thank you all!
June 20th, 2008 at %1:%Jun %p
About official dompdf’s support, the official forum seems to be unmanaged by the author; you can find many spam postings, often related with porn content, among the rightful messages by the actual users.
Is dompdf a dismissed project? I’m looking for a reliable PDF generator for my commercial projects, I’ll consider different softwares in this case…
June 21st, 2008 at %1:%Jun %p
To DeepVoid: Is dompdf a dismissed project? I’d like to know it as well. I asked your same question in the forum, and so did others. Every time the answer is: no, it isn’t. I’d like that those that give such an answer would also explain few other things. It’s a pitty that such a promising software, would be left in the present, uncompleted, state.
There are other options, but those that I tried were worse than this, at least for my needs. In any case, even in its present state, it is adeguate for the prints that I produce.
Maybe the unicode support is awkward, some offically supported tags do not work very well when used in given combinations, the CSS support is lacking, but overall I have always been able in some way to reach the intended result.
June 21st, 2008 at %1:%Jun %p
To DeepVoid: there is a full example(http://www.digitaljunkies.ca/dompdf/faq.php#image_footers) in the dompdf FAQ. Does not work for you? What is exactly the problem you encountered? In several occasions I found that there is a problem with image rendering. Depending on the image format and the operating system used, images can be visible, invisible or just wrong.
June 21st, 2008 at %1:%Jun %p
To David: can you post here an example of your code?
June 23rd, 2008 at %1:%Jun %p
hi,
i am suddenly getting below error on my page. what could be the problem? Please help me
Argument #2 should be an array in /var/www/developmentfolder/includes/dompdf/include/abstract_renderer.cls.php on line 689
September 10th, 2008 at %1:%Sep %p
Hi Luca, love your site!
I’d just like to point out that the image footer example in the official dompdf FAQ is not quite correct. The syntax for $pdf->image varies according to the libs specified in the config file. For example, the one in CPDF lib requires image type.
I hope this helps a lot of people…
Cheers,
Hadi
September 25th, 2008 at %1:%Sep %p
Hi Luca.
Could you help me with this ?
http://sourceforge.net/forum/forum.php?thread_id=2285096&forum_id=440392
Its about using justify in dompdf.
Thanks in advance
October 20th, 2008 at %1:%Oct %p
Thanks a lot for answer of 8. ERROR: Frame not found in cellmap. It helps me a lot as my complex html files sometimes generates this Exception, and users get so upset
October 22nd, 2008 at %1:%Oct %p
Hi Luca,
Thank you VERY MUCH for taking the time to document these quirks. If you have any additional performance tips, please let me know. My 11-page PDF, which is a single table, is taking almost 2 minutes to convert. I’ll pass along any tips I may discover while looking for ways to fine-tune this.
Best Regards,
James
November 6th, 2008 at %0:%Nov %p
Hi,
Thank you very much!
The workaround for “Frame not found in cellmap” worked well for me.
Thanks again!
November 13th, 2008 at %0:%Nov %p
Thanks for this page!
today i have made a working (but not perfect) tcpdf_adapter implementation for dompdf (UTF-8) support -> will be releases soon
November 15th, 2008 at %0:%Nov %p
@tucek: nice job. Keep up posted!