How to Stop Struggling with PDF Generation in Laravel
Generating PDF documents on the web has always been quite a challenge. Think about how many times you've tried to lay out the perfect invoice or report, only to find that fonts shifted, tables went out of alignment, or images disappeared entirely. Usually the choice comes down to complex system utilities like wkhtmltopdf, which require server configuration, and paid cloud services.
If you're working with the Laravel stack, there's a time-tested solution — the laravel-dompdf package by Barry van den Heuvel. It's a wrapper around the Dompdf library that takes your familiar Blade template and converts it into a PDF file. No extra server dependencies, just PHP.
What's under the hood
The project essentially does one thing: connects the power of Laravel with the Dompdf engine. The main feature is that you don't need to learn new syntax for document layout. You create a regular View, pass data to it, and the package handles the rendering.
Interestingly, the package supports not only standard Laravel but also Lumen. This is useful if you're extracting document generation into a separate microservice.
How it works in practice
Installation is standard via Composer:
composer require barryvdh/laravel-dompdf
After that, you get access to the Pdf facade. The simplest example of creating a file looks like this:
use Barryvdh\DomPDF\Facade\Pdf;
$pdf = Pdf::loadView('emails.invoice', ['order' => $order]);
return $pdf->download('invoice.pdf');
The loadView method picks up your Blade file, passes variables to it, and generates an object that you can immediately send to the user for download or just display in the browser via stream().
Flexible page setup
Often you need to change page orientation or paper format directly in code. For example, landscape orientation works better for wide tables:
Pdf::loadHTML($html)
->setPaper('a4', 'landscape')
->setWarnings(false)
->save('report.pdf');
By the way, if you need to save the file to disk instead of serving it to the user, the save() method will do it in one action.
PDF/A-3b support and electronic invoices
Recent versions (3.x) added support for the PDF/A-3b standard. This is critical for long-term document archiving. But there's a catch: this standard requires all fonts to be embedded in the file. Standard Helvetica or Times won't work — you'll need to use something like DejaVu Sans.
For those working on accounting automation, the package now supports Zugferd and Factur-X formats. This is when an XML file with invoice data is embedded directly into the PDF. It looks something like this:
$pdf = Pdf::loadView('invoice', $data)->setPdfA();
// Добавляем метаданные для Factur-X
$pdf->setAdditionalXmpRdf($xmlMetadata);
// Прикрепляем сам XML
$pdf->addEmbeddedFile(
storage_path('invoices/factur-x.xml'),
'factur-x.xml',
'Factur-X Invoice',
'text/xml'
);
A few layout tips
Dompdf is not a full browser engine. It handles CSS 2.1 well and some CSS 3 properties, but don't try using Flexbox or Grid there. Good old tables and floats are your best bet.
Two things that will save you a lot of time:
- Always specify encoding in your template:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>. Without this, Cyrillic will turn into question marks. - For page breaks, use the CSS property
page-break-after: always. This is the most reliable way to make the printer start a new sheet where you need it.
Is it worth using
laravel-dompdf is a workhorse. It's perfect for generating simple to medium-complexity documents: invoices, service reports, simple statements.
The main advantage is simplicity. You don't need to install Node.js, Puppeteer, or configure server binaries. Everything works out of the box on standard PHP hosting.
However, if you need to render complex JavaScript charts or your layout is heavy with modern CSS tricks, Dompdf may struggle. In such cases, it's better to look at Chromium-based tools. But for 90% of backend developer tasks, this package is more than enough.
The project is alive and actively maintained (over 7,000 stars on GitHub) and is supported by one of the most well-known contributors in the Laravel community. If you haven't tried it yet — now is the time to bookmark it.
Related projects