πŸ‘‹ Hey! Nice that you are here!

On this website, I show you the rendering results of different html2pdf tools. I compare mPDF, typeset.sh, PDFreactor, wkhtmltopdf, WeasyPrint, Prince, Puppeteer, openhtmltopdf, pdfHTML (iText 7 add-on), and Flying Saucer.

πŸ”¬ Test Sections

CSS Properties CSS Selectors E-Commerce Paged Media Personal Vendor Samples

πŸ”¬ Test Conditions

For all tests, each tool uses the exact same HTML and CSS input. I do not set any special options the tools might offer, instead I use the most basic call to render a PDF (with external resources).

For the rendering with Prince and PDFreactor, I use free personal licenses. That’s why PDFs generated with these tools have a small logo on the top right corner of each page.

The vendor samples might contain tool-specific syntax. This syntax is not understood by the other tools. That’s why some of these tests look best for the vendor providing them.

Code to Render

I use the following code snippets to create the PDF files. If you want to see the code for this website have a look at the GitHub Repository.

mPDF

$oMPdf = new \Mpdf\Mpdf();
$oMPdf->WriteHTML($sHtmlFileContent);
$oMPdf->Output(
    "result/mpdf.pdf", 
    false
);

typeset.sh

$resourceCache = new \typesetsh\Resource\Cache("./cache-dir/");
$resourceCache->downloadLimit = 5242880;

$resolveUrl = function($url) use ($resourceCache) {
    if (strpos($url, "http://") === 0 || strpos($url, "https://") === 0) {
        $file = $resourceCache->fetch($url);

        return $file;
    }

    throw new Exception("Access denied for local resource `$url`");
};

$oTypesetPdf = typesetsh\createPdf($sHtmlFileContent, $resolveUrl);
$oTypesetPdf->toFile("result/typeset.pdf");

PDFreactor

$oPdfReactor = new PDFreactor();
$aPdfReactorConfig = array(
    "document" => $sHtmlFileContent
);
file_put_contents(
    "result/pdfreactor.pdf", 
    $oPdfReactor->convertAsBinary($aPdfReactorConfig)
);

wkhtmltopdf

$snappy = new Knp\Snappy\Pdf("/usr/local/bin/wkhtmltopdf");
$snappy->generateFromHtml(
    $sHtmlFileContent, 
    "result/wkhtmltopdf.pdf"
);

WeasyPrint

exec("python -m weasyprint '$sInputHTMLFilePath' '" . __DIR__ . "/result/weasyprint.pdf'", $output);

Prince

exec("prince '$sInputHTMLFilePath' -o '" . __DIR__ . "/result/princexml.pdf'", $output);

Puppeteer

$puppeteer = new Puppeteer;
$browser = $puppeteer->launch();

$page = $browser->newPage();
$page->setContent($sHtmlFileContent);
//$page->emulateMedia('screen');
$page->pdf([
    'path' => __DIR__ . '/result/puppeteer.pdf',
    'preferCSSPageSize' => true,
    'printBackground' => true,
    ]);

$browser->close();

openhtmltopdf

OutputStream os = new FileOutputStream(sHtmlFilePath);
PdfRendererBuilder builder = new PdfRendererBuilder();
builder.useFastMode();

builder.withUri("file:///path/to/result/openhtmltopdf.pdf");
builder.toStream(os);
builder.run();

pdfHTML (iText 7 add-on)

File htmlSource = new File(sHtmlFilePath);
File pdfDest = new File(resultFilepath);
ConverterProperties converterProperties = new ConverterProperties();
HtmlConverter.convertToPdf(new FileInputStream(htmlSource), new FileOutputStream(pdfDest), converterProperties);

Flying Saucer

String url = new File(aFile.getAbsolutePath()).toURI().toURL().toString();
OutputStream os = new FileOutputStream(resultFilepath);

ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
renderer.layout();
renderer.createPDF(os);

os.close();