title: How to bulk generate PDF from HTML templates ready for double-sided printing in PHP?
body: <p>I've been struggling with this for a while and feel helpless.
  Prestashop uses <a href="https://github.com/tecnickcom/TCPDF" rel="noreferrer">tcpdf</a> to generate invoices and delivery slips from HTML templates filled using Smarty. We are working on updating the invoice design and found tcpdf to be lacking in CSS support. After some research we settled for <a href="https://wkhtmltopdf.org/" rel="noreferrer">wkhtmltopdf</a> as the right tool from converting the HTML/CSS templates to PDF.</p>
  
  <p><strong>The problem</strong></p>
  
  <p>The store has a feature for exporting multiple invoices into a single PDF. Using <code>TCPDF</code> I was able to make the batch file ready for double sided printing by inserting a blank page after each invoice that had odd number of pages before the file was generated. But now that we switched to <code>wkhtmltopdf</code> I cannot achieve the same result.</p>
  
  <p>The crucial problem is that while <code>wkhtmltopdf</code> allows for the usage of multiple HTML templates there seems to be no reliable way to <a href="https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1889" rel="noreferrer">determine the number of pages</a> they are each going to have before the file is generated. The header and footer templates can receive the page count that the invoice ends up being but they are separate from the main content and therefore I cannot insert a page break accordingly. </p>
  
  <p>I've also tried to calculate the <code>height of the content</code> / <code>PDF page height</code> but there were <a href="https://github.com/wkhtmltopdf/wkhtmltopdf/issues/1927" rel="noreferrer">various issues</a> with that once I started exporting multiple templates (worked alright with a single template). This approach isn't great either because inserting a blank page into the content itself causes the footer to appear on the new page as well which is not what I want.</p>
  
  <p><strong>My best attempt</strong></p>
  
  <p>The only way I've figured out that could get me around these issues is very inefficient. Each time a template is added to the batch I could pre-generate it using a separate instance of a <a href="https://github.com/mikehaertl/phpwkhtmltopdf" rel="noreferrer">wrapper</a> for <code>wkhtmltopdf</code>, get the temporary file name, determine how many pages it has using <code>pdfinfo</code> and add a blank HTML template to the main instance accordingly. Here's a <em>draft</em> of a function to get the number of pages of the last template added (from a class that extends the wrapper, based on some other <code>pdfinfo</code> <a href="https://stackoverflow.com/questions/14644353/get-the-number-of-pages-in-a-pdf-document">questions</a> I found on SO):</p>
  
  <pre><code>/**
  * Return the number of pages in the last invoice template added
  * $complete === true =&gt; return the length of the entire document
  */
  public function getNumPages($complete = false)
  {
      if (!$complete) {
          // Generate PDF of last template added
  
          $tmpPdf = new WKPdf($this-&gt;_options);
          $tmpPdf-&gt;addPage($this-&gt;content, Array(
              'footer-html' =&gt; $this-&gt;footer
          ));
  
          /**
             The createPdf method is protected so I need to get 
             the content as string here to force the wrapper to 
             call wkhtmltopdf.
          */
          $tmpPdf-&gt;toString();
          $document = $tmpPdf-&gt;getPdfFilename();
      } else {
  
          // Generate entire batch
          $this-&gt;createPdf();
          $document = $this-&gt;getPdfFilename();
      }
  
      // Use pdfinfo to get the PDF page count
      $cmd = 'pdfinfo';
      exec("$cmd \"$document\"", $output);
  
      $pagecount = 0;
      foreach($output as $op)
      {
          // Extract the number
          if(preg_match("/Pages:\s*(\d+)/i", $op, $matches) === 1)
          {
              $pagecount = intval($matches[1]);
              break;
          }
      }
  
      return $pagecount;
  }
  </code></pre>
  
  <p>This is very inefficient - it takes about 80 seconds to generate a batch of 25 invoices because I have to call <code>wkhtmltopdf</code> 25 times to create the temporary PDF files so that I can call <code>pdfinfo</code> 25 times to get their individual lengths and insert blank pages where necessary and then generate the final document. </p>
  
  <p>The advantage of TCPDF is that it can give you the number of pages on the fly and a similar functionality takes about 5 seconds to generate a batch file of 25 invoices.</p>
  
  <p>Anyone has any ideas on how to speed things up? Or a better idea to do this altogether. I've considered various tools for the generation including dompdf but wkhtmltopdf is simply the most powerful. The batch generation is really only used from the back office by the store admins so maybe they could be patient. But still.</p>