How to Convert HTML to PDF in Laravel with Dompdf

Convert HTML to PDF in Laravel with Dompdf. Load a Blade view with the Pdf facade and save the file. Remote images stay off.

A closed laptop on a kitchen table beside printed pages and a bowl of fruit

Use the URL to PDF Converter when you want the file without installing anything. The steps below are the detail.

Laravel does not render HTML to PDF by itself. The maintained wrapper around Dompdf is barryvdh/laravel-dompdf. You load a Blade view, or an HTML string, through the Pdf facade and save or download the file. The CSS limits are Dompdf’s limits. This is not Chrome, and it is not the old Laravel 5 facade some tutorials still paste.

Install the package

composer require barryvdh/laravel-dompdf

On Laravel the service provider and the Pdf facade alias are discovered for you. Lumen still needs the provider registered by hand. Publish the config when you want to change paper size, the font cache, or remote file access:

php artisan vendor:publish --provider="Barryvdh\DomPDF\ServiceProvider"

That writes config/dompdf.php.

Convert a Blade view

The facade to import is Barryvdh\DomPDF\Facade\Pdf. loadView renders the view and hands the HTML to Dompdf. setPaper overrides the default. save writes a path on the local disk. download returns a response the controller can send to the browser.

<?php

namespace App\Http\Controllers;

use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Http\Response;

class InvoiceController extends Controller
{
    public function download(): Response
    {
        $pdf = Pdf::loadView('pdf.invoice', [
            'number' => 'INV-1001',
            'customer' => 'Acme Ltd.',
        ])->setPaper('a4', 'portrait');

        $pdf->save(storage_path('app/invoice-1001.pdf'));

        return $pdf->download('invoice-1001.pdf');
    }
}

The view needs a charset, and a font Dompdf can embed. DejaVu Sans ships with Dompdf. Core PDF fonts such as Helvetica do not cover a full Unicode invoice.

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <style>
    body { font-family: "DejaVu Sans", sans-serif; font-size: 12pt; }
    h1 { font-size: 18pt; }
  </style>
</head>
<body>
  <h1>Invoice {{ $number }}</h1>
  <p>{{ $customer }}</p>
</body>
</html>

An HTML string uses Pdf::loadHTML($html) instead of loadView. The chain after that is the same.

Remote images stay off

Since package 3.x, isRemoteEnabled defaults to false. Turn it on in config/dompdf.php only when the PDF must fetch a file over HTTP, and treat that as a choice, not a default. Local files still have to live inside the chroot, which defaults to the application directory.

Pdf::setOption(['defaultFont' => 'DejaVu Sans']);

The same CSS limits as Dompdf

This package does not add a browser. Flexbox is unsupported. CSS Grid is unsupported. A table row has to fit on one page. page-break-before and page-break-after do start a new page, which is the break the readme documents. The plain-PHP version of the same renderer is HTML to PDF in PHP with Dompdf. Do not copy a tutorial that instantiates Barryvdh\DomPDF\Facade without the Pdf class. That was the Laravel 5 style.

Skip the install

For a public page, the URL to PDF converter uses headless Chrome in screen mode. Print-only rules are skipped, and the paper size comes from the form rather than from @page. The file is deleted after download. There is no signup and no watermark.