DOMPDF - failing to generate pdf for more than 100 pages

4,759 views
Skip to first unread message

Preeti Savant

unread,
Oct 19, 2014, 9:18:04 PM10/19/14
to dom...@googlegroups.com
Hi, 

In my application i have a loop which executes for minimum 5000 times and inside each loop am forming html page and storing it in a single variable, (hope its correct) , and at the end of the loop i have all 5000 pages in one variable $html, which when i am trying to pass to dompdf its taking more than 5000 seconds, and then displaying an error. Is it because of the size of the html variable? Is there any way to go on adding pages to pdf in a loop itself instead of storing all 5000 pages in a single variable, n then after loop rendering the pdf file???

Hermann Herz

unread,
Oct 20, 2014, 5:52:19 PM10/20/14
to dom...@googlegroups.com
I do that rendering again and again in a for loop ($dompdf = new DOMPDF(); $dompdf->load_html($html); $dompdf->render(); $pdfoutput = $dompdf->output(); unset($dompdf); ... on every loop), in that loop I store every generated pdf file as new pdf file on my server. 

I also update a bootstrap progressbar div and do a flush in that loop in order to be able to update that progressbar correct...
// This is for the buffer achieve the minimum size in order to flush data
echo str_repeat(' ',1024*64);
flush();

After the loop I merge all these pdf files into one big pdf file with 
gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE="merged_pdf.pdf" -dBATCH pdf1.pdf pdf2.pdf ....and so on

This works perfect for about 400 pdf files (in about ~40sec) so I can't speak for your 5000 pages.

BrianS

unread,
Oct 20, 2014, 11:09:25 PM10/20/14
to dom...@googlegroups.com
I've done something similar in the past, though running each render in a separate process (using `exec()`), which seems to greatly decrease resource usage.

If you're feeling adventurous you could try a non-official version that has been modified to allow rendering of individual HTML document into a single PDF. See this repo: https://github.com/craigfrancis/dompdf/

Hermann Herz

unread,
Oct 21, 2014, 4:09:32 AM10/21/14
to dom...@googlegroups.com
@BrianS Can you please post an example which uses this separate process with exec()?

Thanks

BrianS

unread,
Oct 21, 2014, 11:54:36 AM10/21/14
to dom...@googlegroups.com
Some of this would depend on your process (e.g. how you put your HTML together). One way I've done it in the past is to save the HTML to a file and render the file to PDF. At the end of the process you can combine the various files as you've indicated. So something like:

$filenames = array();
foreach ( $doc_ids as $doc_id ) {
  $html
= create_html( $doc_id );

  $filename_html
= 'someplace/safe/doc' . $doc_id . '.html';
  $filename_pdf
= 'someplace/safe/doc' . $doc_id . '.pdf';
  file_put_contents
( $filename_html , $html );
 
exec( 'dompdf/dompdf.php ' . $filename_html );
 
if ( file_exists( $filename_pdf ) ) {
    $filenames
[] = $filename_pdf;
 
}
}

exec('gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE="merged_pdf.pdf" -dBATCH ' . implode( ' ' , $filenames ) );

Since dompdf is running outside the current process it's memory will be freed up after each render. You do have a bit more resources allocated to overhead, but it's negligible compared to the savings you get.

You can do the same thing in different ways as well. For example, use a cmd script that accepts a parameter indicating the document ID from the database which then puts together the HTML and render in the same file. You'd still get savings in resource usage and the process would be self-contained. Some methods have trade-offs over others (for example, establishing db connections is costly).

Hermann Herz

unread,
Jan 7, 2015, 8:37:14 AM1/7/15
to dom...@googlegroups.com
Had to generate 310 invoices (with html tables and some images in it) and with my old method the loop stopped at around 295 invoices.

So I tested your code using exec() method and now I'm able to generate all invoices without a problem!!!

Thanks again BrianS!!!

Jefferson Duterwill

unread,
Aug 21, 2015, 1:31:32 PM8/21/15
to dompdf
Hello Bryan okay ?
I have an application with dompdf that need to generate more than 100 pages , I could not understand how to apply that his explanation would help me , below is my code to render :

require_once ( " dompdf / dompdf_config.inc.php ");
ini_set ( " memory_limit ", " 3072M ");
$ html = urldecode ( $ _ POST [' html '] ) ;
$ dompdf DOMPDF = new ();
$ dompdf- > load_html ( $ html ) ;
$ dompdf- > set_paper ( ' a4 ', ' landscape ');
$ dompdf- > render () ;
$ dompdf- > stream ( " etiqueta.pdf ");
exit () ;

Or it takes too long or freezes my CloudServer

thank ,

Jeff

BrianS

unread,
Sep 8, 2015, 2:15:25 PM9/8/15
to dompdf
So you're passing the 100 page HTML as a single string to dompdf? That makes it a bit more difficult. The method described above requires pages to be chunked into blocks that can be rendered separately. After the multiple documents are rendered you can combine them using something like pdftk.

Post with more details and we'll try to provide some more advice.

(Also, might want to start a new thread.)

Sandeep Bangarh

unread,
Oct 29, 2015, 2:33:00 AM10/29/15
to dompdf
Reply all
Reply to author
Forward
0 new messages