Mahbubur Riad
Back to blog
Laravel 3 min read

How to Export a PDF File from Laravel Application Data (Complete Guide)

Jun 10, 2026 · Mahbubur Riad

Learn how to generate and export PDF files from your Laravel application using DomPDF, Snappy (wkhtmltopdf), and Browsershot. Includes blade templates, file download, storage, and real-world examples.

How to Export a PDF File from Laravel Application Data (Complete Guide)
On this page

Generating and exporting PDF files is a common requirement in Laravel applications — whether you're building invoices, reports, user data exports, or certificates. In this guide, you'll learn three proven approaches to PDF generation in Laravel, with real code examples you can drop into your project today.


Why PDF Export Matters in Laravel Apps

Modern web applications frequently need to produce downloadable documents:

  • Invoices & receipts — for e-commerce, SaaS billing, and fintech apps
  • Reports — admin panels exporting data tables, charts, or analytics
  • Certificates — for course completion, registration, etc.
  • User data exports — GDPR-compliant data dumps in PDF form

Laravel doesn't ship with built-in PDF support, but the ecosystem provides excellent packages for every use case.


barryvdh/laravel-dompdf is the most popular Laravel PDF package. It wraps the DomPDF library, which converts HTML/CSS to PDF entirely in PHP — no binary dependencies required.

Installation

Bash
composer require barryvdh/laravel-dompdf

Publish the config (optional):

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

Create a Blade Template

HTMLresources/views/pdf/invoice.blade.php
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        body { font-family: DejaVu Sans, sans-serif; font-size: 13px; }
        h1 { color: #2d3748; }
        table { width: 100%; border-collapse: collapse; margin-top: 20px; }
        th, td { border: 1px solid #e2e8f0; padding: 8px 12px; text-align: left; }
        th { background-color: #f7fafc; }
        .total { font-weight: bold; color: #2b6cb0; }
    </style>
</head>
<body>
    <h1>Invoice #{{ $invoice->id }}</h1>
    <p><strong>Customer:</strong> {{ $invoice->customer_name }}</p>
    <p><strong>Date:</strong> {{ $invoice->created_at->format('d M Y') }}</p>

    <table>
        <thead>
            <tr>
                <th>#</th>
                <th>Item</th>
                <th>Qty</th>
                <th>Unit Price</th>
                <th>Total</th>
            </tr>
        </thead>
        <tbody>
            @foreach($invoice->items as $i => $item)
            <tr>
                <td>{{ $i + 1 }}</td>
                <td>{{ $item->name }}</td>
                <td>{{ $item->quantity }}</td>
                <td>{{ number_format($item->unit_price, 2) }}</td>
                <td>{{ number_format($item->total, 2) }}</td>
            </tr>
            @endforeach
        </tbody>
        <tfoot>
            <tr>
                <td colspan="4" class="total">Grand Total</td>
                <td class="total">{{ number_format($invoice->grand_total, 2) }}</td>
            </tr>
        </tfoot>
    </table>
</body>
</html>

Controller: Download PDF

PHP
<?php

namespace App\Http\Controllers;

use App\Models\Invoice;
use Barryvdh\DomPDF\Facade\Pdf;

class InvoiceController extends Controller
{
    public function download(Invoice $invoice)
    {
        $pdf = Pdf::loadView('pdf.invoice', compact('invoice'));

        // Force download
        return $pdf->download("invoice-{$invoice->id}.pdf");
    }

    public function stream(Invoice $invoice)
    {
        $pdf = Pdf::loadView('pdf.invoice', compact('invoice'));

        // Open inline in browser
        return $pdf->stream("invoice-{$invoice->id}.pdf");
    }
}

Route

PHP
Route::get('/invoices/{invoice}/download', [InvoiceController::class, 'download'])
    ->name('invoices.download')
    ->middleware('auth');

DomPDF Configuration Tips

In config/dompdf.php, useful options include:

PHP
'options' => [
    'defaultFont'   => 'DejaVu Sans',   // Best Unicode/Bangla support
    'isRemoteEnabled' => true,           // Allow remote images
    'isHtml5ParserEnabled' => true,
    'dpi'           => 150,              // Higher DPI = sharper output
    'defaultPaperSize' => 'a4',
],

Note for Bangla/Unicode text: Use DejaVu Sans or embed a custom font via @font-face in your Blade CSS. DomPDF has limited font support by default.


Option 2: Snappy PDF (wkhtmltopdf)

barryvdh/laravel-snappy uses wkhtmltopdf, a headless Qt WebKit renderer. It produces pixel-perfect PDFs with full CSS3 support, but requires a system binary.

Installation

Bash
composer require barryvdh/laravel-snappy

Install the binary (Linux):

Bash
# Via h4cc/wkhtmltopdf-amd64 (no system dependency)
composer require h4cc/wkhtmltopdf-amd64 h4cc/wkhtmltoimage-amd64

# Or download from: https://wkhtmltopdf.org/downloads.html

Publish config:

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

Update config/snappy.php:

PHP
'pdf' => [
    'enabled' => true,
    'binary'  => base_path('vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64'),
    'timeout' => 3600,
    'options' => [],
    'env'     => [],
],

Controller

PHP
use Barryvdh\Snappy\Facades\SnappyPdf as PDF;

public function downloadSnappy(Invoice $invoice)
{
    $pdf = PDF::loadView('pdf.invoice', compact('invoice'));

    return $pdf->download("invoice-{$invoice->id}.pdf");
}

Snappy supports additional options like margins, headers, footers:

PHP
$pdf = PDF::loadView('pdf.invoice', compact('invoice'))
    ->setOption('margin-top', 10)
    ->setOption('margin-bottom', 10)
    ->setOption('footer-right', 'Page [page] of [topage]');

Option 3: Browsershot (Headless Chrome)

spatie/browsershot uses a headless Chromium instance (via Puppeteer). It produces the most accurate rendering — identical to what Chrome shows — but requires Node.js and Puppeteer installed.

Installation

Bash
composer require spatie/browsershot
npm install puppeteer

Usage

PHP
use Spatie\Browsershot\Browsershot;

public function downloadBrowsershot(Invoice $invoice)
{
    $html = view('pdf.invoice', compact('invoice'))->render();

    $pdfContent = Browsershot::html($html)
        ->format('A4')
        ->margins(10, 10, 10, 10)
        ->pdf();

    return response($pdfContent, 200, [
        'Content-Type'        => 'application/pdf',
        'Content-Disposition' => "attachment; filename=invoice-{$invoice->id}.pdf",
    ]);
}

Saving PDF to Storage Instead of Downloading

Sometimes you need to store the PDF on disk (e.g., to attach to an email later or cache for repeated downloads).

PHP
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Support\Facades\Storage;

public function generateAndStore(Invoice $invoice): string
{
    $pdf = Pdf::loadView('pdf.invoice', compact('invoice'));

    $path = "invoices/invoice-{$invoice->id}.pdf";

    // Store in storage/app/invoices/
    Storage::put($path, $pdf->output());

    return $path;
}

public function downloadStored(Invoice $invoice)
{
    $path = "invoices/invoice-{$invoice->id}.pdf";

    if (! Storage::exists($path)) {
        $this->generateAndStore($invoice);
    }

    return Storage::download($path, "invoice-{$invoice->id}.pdf");
}

Sending PDF as Email Attachment

PHP
use Barryvdh\DomPDF\Facade\Pdf;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Attachment;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;

class InvoiceMail extends Mailable
{
    public function __construct(public Invoice $invoice) {}

    public function envelope(): Envelope
    {
        return new Envelope(subject: "Invoice #{$this->invoice->id}");
    }

    public function content(): Content
    {
        return new Content(view: 'mail.invoice');
    }

    public function attachments(): array
    {
        $pdf = Pdf::loadView('pdf.invoice', ['invoice' => $this->invoice]);

        return [
            Attachment::fromData(
                fn () => $pdf->output(),
                "invoice-{$this->invoice->id}.pdf"
            )->withMime('application/pdf'),
        ];
    }
}

Comparison Table

Feature DomPDF Snappy (wkhtmltopdf) Browsershot
CSS Support Basic CSS2/3 Full CSS3 Full (Chrome-level)
System Binary ❌ None needed ✅ wkhtmltopdf ✅ Node + Puppeteer
Unicode/Bangla Needs font setup ✅ Native ✅ Native
JavaScript ❌ No ❌ No ✅ Yes
Rendering Quality Good Very Good Excellent
Speed Fast Medium Slowest
Best For Simple invoices, reports Complex layouts JS-heavy pages
Server Requirements PHP only Linux binary Node.js + Chromium

Conclusion

For most Laravel applications — invoices, reports, data exports — barryvdh/laravel-dompdf is the go-to choice. It's pure PHP, easy to install, and works out of the box on any hosting environment including shared hosting and Docker containers.

If your PDFs have complex CSS layouts or you need pixel-perfect rendering, Snappy (wkhtmltopdf) is a solid upgrade. And for the highest fidelity — especially when your Blade views use JavaScript-rendered content — Browsershot with headless Chrome is unbeatable.

Quick Decision Guide

  • Simple invoice / table / reportbarryvdh/laravel-dompdf
  • Complex CSS, headers/footers, page numbersbarryvdh/laravel-snappy
  • Dynamic JS content or pixel-perfect outputspatie/browsershot

Related

Related posts