How to create a PDF file from HTML in PHP?

Below you can find a handy comparison of how a HTML to PDF conversion works using different tools and libraries. All documents were generated from the same HTML source. All the look is achieved via CSS, including Flexbox to position Sender and Recipient sections.

Always choose a tool that suits your job best and is well-maintained. Good luck!

Last updated: December 12th, 2019

Compare screenshots:

Google Chrome HTML to PDF screenshot
Google Chrome 78 (reference image)
94 KB
wkhtmltopdf screenshot
wkhtmltopdf 0.12.5
29 KB
Dompdf HTML to PDF screenshot
Dompdf 0.8.3
3 KB
Mpdf HTML to PDF screenshot
Mpdf 8.0.4
44 KB
TCPDF HTML to PDF screenshot
TCPDF 6.3.2
9 KB

How it's made?

All above examples are screenshots of PDF documents generated from the same HTML source:

<!DOCTYPE html>
<html>
<head>
<style>
body {
    font-family: sans-serif;
}

header {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
}

.issue-date {
    text-align: right;
    width: 100%;
}

.sender, .recipient {
    width: 45%;
}

address {
    font-style: normal;
}

h1 {
    text-align: center;
}

table {
    border-collapse: collapse;
    width: 100%;
}

thead {
    background: #E0E0E0;
}

th, td {
    border: solid black 1px;
    padding: 0.5rem;
}

.product-name {
    width: 33%;
}

.number {
    text-align: center;
}

tfoot th {
    text-align: right;
}

dt {
    font-weight: bold;
}

dd {
    margin-bottom: 1rem;
}

footer {
    font-style: italic;
    text-align: center;
}
</style>
<meta charset="utf-8">
</head>
<body>

<header>
    <dl class="issue-date">
        <dt>Issue date</dt>
        <dd>2020-01-02</dd>
        <dt>Due date</dt>
        <dd>2020-01-16</dd>
    </dl>
    <section class="sender">
        <h2>Seller</h2>
        <address>
            Test Seller<br>
            VAT ID: PL1112223344<br>
            Grunwaldzka 1<br>
            00-001 Warszawa
        </address>
    </section>
    <section class="recipient">
        <h2>Buyer</h2>
        <address>
            Test Recipient<br>
            VAT ID: PL5556667788<br>
            Prosta 1<br>
            00-002 Kraków
        </address>
    </section>
</header>

<main>
    <h1>Invoice 123/2020</h1>

    <table>
        <thead>
            <tr>
                <th class="product-name">Name</th>
                <th>Quantity</th>
                <th>Net amount</th>
                <th>VAT rate</th>
                <th>VAT amount</th>
                <th>Gross amount</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>First product</td>
                <td class="number">1</td>
                <td class="number">100.00</td>
                <td class="number">8%</td>
                <td class="number">8.00</td>
                <td class="number">108.00</td>
            </tr>
            <tr>
                <td>Second product</td>
                <td class="number">1</td>
                <td class="number">50.00</td>
                <td class="number">23%</td>
                <td class="number">11.50</td>
                <td class="number">61.50</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <th colspan="2">Total</th>
                <td class="number">150.00</td>
                <td></td>
                <td class="number">19.50</td>
                <td class="number"><strong>169.50</strong></td>
            </tr>
        </tfoot>
    </table>

    <dl class="payment-terms">
        <dt>Payment method</dt><dd>Bank transfer</dd>
        <dt>Account number</dt><dd>00 1111 2222 3333 4444 5555 6666</dd>
    </dl>
</main>

<footer>
Please state the invoice number while paying this invoice
</footer>

</body>
</html>

All examples were generated using default settings for a specific tool or library and with A4 page size. They differ in terms of font embedding, compression, metadata etc.

For PHP libraries, the code was following:

require './vendor/autoload.php';
$html = \file_get_contents('../example-documents/invoice.html');

$mpdf = new Mpdf\Mpdf();
$mpdf->AddPage();
$mpdf->WriteHTML($html);
$mpdf->Output('../example-documents/output/invoice-mpdf.pdf', 'F');

$tcpdf = new TCPDF();
$tcpdf->AddPage();
$tcpdf->writeHTML($html);
\file_put_contents('../example-documents/output/invoice-tcpdf.pdf', $tcpdf->Output('', 'S'));

$dompdf = new Dompdf\Dompdf();
$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();
\file_put_contents('../example-documents/output/invoice-dompdf.pdf', $dompdf->output());

Screenshots were made using Ghostscript 9.50 and ImageMagick 7.0.9.

See my blog post about generating PDF files.