All formats

mPDF

LanguagePHP 5.6 to 8.5
LicenseGPL-2.0-only
Repositorygithub.com/mpdf/mpdf
Documentationmpdf.github.io
Depends onext-gd, ext-mbstring, setasign/fpdi, psr/log, myclabs/deep-copy
Read / writeimports pages of existing PDFs (via FPDI) / yes

mPDF turns HTML and CSS into PDF and is known for its font handling: it embeds and subsets TrueType fonts, does automatic font substitution for missing glyphs, and supports right-to-left scripts (Arabic, Hebrew), Indic scripts with OpenType shaping, and CJK. It also has HTML headers and footers, table of contents, bookmarks, watermarks, barcodes, columns, annotations, PDF/A and PDF/X output and encryption, and it can import pages from existing PDFs through FPDI.

mPDF is GPL-2.0: distributing an application that includes it means distributing under the GPL. It’s slower than Dompdf on large documents and CSS support is partial (no flexbox or grid). The tempDir must be writable.

Installation#

Shell
composer require mpdf/mpdf

Basic usage: convert HTML to PDF#

PHP
<?php
require 'vendor/autoload.php';

$mpdf = new \Mpdf\Mpdf(['format' => 'A4', 'margin_top' => 20, 'tempDir' => __DIR__ . '/tmp']);
$mpdf->SetTitle('Invoice #1001');
$mpdf->SetAuthor('Billing');
$mpdf->SetHTMLFooter('<div style="text-align: right">Page {PAGENO} of {nbpg}</div>');

$mpdf->WriteHTML('<h1>Invoice #1001</h1>
<p>Zażółć gęślą jaźń · Привет · 日本語</p>
<table border="1" style="border-collapse: collapse">
  <tr><th>Item</th><th>Price</th></tr>
  <tr><td>Widget</td><td>9.99</td></tr>
</table>');

$mpdf->Output('invoice.pdf', \Mpdf\Output\Destination::FILE);

Other destinations: INLINE (show in browser), DOWNLOAD, STRING_RETURN.

How to add a watermark#

PHP
$mpdf = new \Mpdf\Mpdf(['tempDir' => __DIR__ . '/tmp']);
$mpdf->SetWatermarkText('DRAFT');
$mpdf->showWatermarkText = true;
$mpdf->WriteHTML('<p>Draft document</p>');
$pdf = $mpdf->Output('', \Mpdf\Output\Destination::STRING_RETURN);

How to merge PDF files#

mPDF includes FPDI, so it can import pages from existing PDFs:

PHP
$mpdf = new \Mpdf\Mpdf(['tempDir' => __DIR__ . '/tmp']);
foreach (['a.pdf', 'b.pdf'] as $file) {
    $pageCount = $mpdf->setSourceFile($file);
    for ($i = 1; $i <= $pageCount; $i++) {
        $mpdf->AddPage();
        $tpl = $mpdf->importPage($i);
        $mpdf->useTemplate($tpl);
    }
}
$mpdf->Output('merged.pdf', \Mpdf\Output\Destination::FILE);

The same limitation as FPDI applies: files with compressed cross-reference streams need the commercial FPDI parser or a rewrite with qpdf first.

How to password-protect a PDF#

PHP
$mpdf = new \Mpdf\Mpdf(['tempDir' => __DIR__ . '/tmp']);
$mpdf->SetProtection(['print', 'copy'], 'user', 'owner', 128);  // RC4 128-bit
$mpdf->WriteHTML('<p>Secret</p>');
$mpdf->Output('secret.pdf', \Mpdf\Output\Destination::FILE);

mPDF writes RC4 encryption (40 or 128 bit), which is weak by today’s standards; re-encrypt with qpdf for AES-256.

Tips#