Try Live
Add Docs
Rankings
Pricing
Docs
Install
Install
Docs
Pricing
More...
More...
Try Live
Rankings
Enterprise
Create API Key
Add Docs
Laravel PDF
https://github.com/spatie/laravel-pdf
Admin
A package that simplifies PDF creation in Laravel applications by rendering Blade views using
...
Tokens:
28,171
Snippets:
272
Trust Score:
-
Update:
1 month ago
Context
Skills
Chat
Benchmark
89.6
Suggestions
Latest
Show doc for...
Code
Info
Show Results
Context Summary (auto-generated)
Raw
Copy
Link
# Laravel PDF Laravel PDF is a package by Spatie that provides a simple, elegant way to create PDFs in Laravel applications. It supports multiple PDF generation backends through a driver-based architecture: Browsershot (Chromium-based, default), Gotenberg (Docker-based), Cloudflare Browser Rendering API, and DOMPDF (pure PHP). The Chromium-based drivers support modern CSS features like flexbox, grid, and Tailwind CSS, while DOMPDF offers a zero-dependency solution for simpler PDFs. The package integrates seamlessly with Laravel's Blade templating, filesystem abstraction, and queue system. You can render Blade views as PDFs, save them locally or to cloud storage (S3, etc.), return them as HTTP responses, and generate them in background queues. It also includes a comprehensive testing API with fakes and assertions for verifying PDF generation in your test suite. ## Installation Install the package via Composer, then optionally install a driver dependency. ```bash # Install the package composer require spatie/laravel-pdf # For Browsershot driver (default) - requires Node.js and Chrome composer require spatie/browsershot # For DOMPDF driver (pure PHP, no external dependencies) composer require dompdf/dompdf # Publish config file (optional) php artisan vendor:publish --tag=pdf-config ``` ## Creating PDFs from Blade Views Render a Blade view as a PDF and save it to the filesystem. Pass data to the view as the second argument. ```php use Spatie\LaravelPdf\Facades\Pdf; // Basic usage - render view and save Pdf::view('pdf.invoice')->save('/path/to/invoice.pdf'); // Pass data to the view Pdf::view('pdf.invoice', ['invoice' => $invoice, 'customer' => $customer]) ->save('/path/to/invoice.pdf'); // Create PDF from raw HTML Pdf::html('<h1>Hello World</h1><p>This is a PDF document.</p>') ->save('/path/to/document.pdf'); ``` ## Returning PDFs as HTTP Responses Return a PDF directly from a controller as an HTTP response. Use the `pdf()` helper or the Facade. ```php use Spatie\LaravelPdf\Facades\Pdf; use function Spatie\LaravelPdf\Support\pdf; class InvoiceController { // Using the helper function - inline display in browser public function show(Invoice $invoice) { return pdf('pdf.invoice', ['invoice' => $invoice]) ->name('invoice-2024.pdf'); } // Force download instead of inline display public function download(Invoice $invoice) { return Pdf::view('pdf.invoice', ['invoice' => $invoice]) ->name('invoice-2024.pdf') ->download(); } } ``` ## Page Format and Orientation Set page size, orientation, and margins using fluent methods. Supports standard formats and custom dimensions. ```php use Spatie\LaravelPdf\Facades\Pdf; use Spatie\LaravelPdf\Enums\Format; use Spatie\LaravelPdf\Enums\Orientation; use Spatie\LaravelPdf\Enums\Unit; Pdf::view('pdf.report', ['data' => $data]) ->format(Format::A4) // Standard format (A4, Letter, Legal, etc.) ->landscape() // Landscape orientation ->margins(20, 15, 20, 15, Unit::Millimeter) // Top, right, bottom, left margins ->save('report.pdf'); // Custom paper size (e.g., for receipts) Pdf::view('pdf.receipt', ['order' => $order]) ->paperSize(80, 200, 'mm') // Width, height, unit ->orientation(Orientation::Portrait) ->save('receipt.pdf'); ``` ## Headers and Footers Add repeating headers and footers to every page. Use Blade views or raw HTML with page number directives. ```php use Spatie\LaravelPdf\Facades\Pdf; Pdf::view('pdf.contract', ['contract' => $contract]) ->headerView('pdf.header', ['company' => $company]) ->footerView('pdf.footer') ->format('a4') ->save('contract.pdf'); // Using raw HTML for header/footer Pdf::view('pdf.invoice', ['invoice' => $invoice]) ->headerHtml('<div style="text-align: center;">Company Name</div>') ->footerHtml('<div style="font-size: 10px;">Page @pageNumber of @totalPages</div>') ->save('invoice.pdf'); ``` ```blade {{-- resources/views/pdf/footer.blade.php --}} <style> .footer { font-size: 10px; text-align: center; } </style> <div class="footer"> Page @pageNumber of @totalPages | Generated on {{ now()->format('Y-m-d') }} </div> ``` ## Saving to Cloud Storage Disks Save PDFs directly to any Laravel filesystem disk (S3, GCS, etc.) using the `disk()` method. ```php use Spatie\LaravelPdf\Facades\Pdf; // Save to S3 Pdf::view('pdf.invoice', ['invoice' => $invoice]) ->disk('s3') ->save('invoices/invoice-2024-001.pdf'); // Save with custom visibility Pdf::view('pdf.report', ['report' => $report]) ->disk('s3', 'public') ->save('reports/monthly-report.pdf'); ``` ## Queued PDF Generation Generate PDFs in background queues for better performance. Chain callbacks for success/failure handling. ```php use Spatie\LaravelPdf\Facades\Pdf; use Illuminate\Support\Facades\Mail; use Illuminate\Support\Facades\Log; Pdf::view('pdf.invoice', ['invoice' => $invoice]) ->format('a4') ->disk('s3') ->saveQueued('invoices/invoice.pdf') ->onQueue('pdfs') ->onConnection('redis') ->then(function (string $path, ?string $diskName) use ($user) { // PDF generated successfully - send email notification Mail::to($user)->send(new InvoiceReady($path, $diskName)); }) ->catch(function (Throwable $e) { Log::error('PDF generation failed: ' . $e->getMessage()); }); ``` ## PDF Metadata Set document metadata like title, author, and keywords that appear in PDF viewers. ```php use Spatie\LaravelPdf\Facades\Pdf; Pdf::view('pdf.invoice', ['invoice' => $invoice]) ->meta( title: 'Invoice #' . $invoice->number, author: 'Acme Corporation', subject: 'Monthly Invoice', keywords: 'invoice, billing, acme', creator: 'My Laravel App', creationDate: now() ) ->save('invoice.pdf'); ``` ## Advanced Formatting Options Use scale, page ranges, tagged PDFs, and conditional formatting for advanced output control. ```php use Spatie\LaravelPdf\Facades\Pdf; Pdf::view('pdf.report', ['report' => $report]) ->format('a4') ->scale(0.75) // Scale content (0.1 to 2.0) ->pageRanges('1-3, 5, 7-10') // Include specific pages only ->tagged() // Generate accessible/tagged PDF ->save('report.pdf'); // Conditional formatting based on data Pdf::view('pdf.invoice', ['invoice' => $invoice]) ->format('a4') ->when($invoice->isLandscape(), fn ($pdf) => $pdf->landscape()) ->when($invoice->hasLetterhead(), fn ($pdf) => $pdf->headerView('pdf.letterhead')) ->unless($invoice->isCompact(), fn ($pdf) => $pdf->margins(20, 15, 20, 15)) ->save('invoice.pdf'); ``` ## Multi-Page PDFs with Page Breaks Use Blade directives to create multi-page documents with explicit page breaks and page numbers. ```blade {{-- resources/views/pdf/report.blade.php --}} <div> <h1>Executive Summary</h1> <p>{{ $report->summary }}</p> </div> @pageBreak <div> <h2>Detailed Analysis</h2> @foreach($report->sections as $section) <h3>{{ $section->title }}</h3> <p>{{ $section->content }}</p> @if(!$loop->last) @pageBreak @endif @endforeach </div> ``` ## Driver Selection and Configuration Switch between PDF drivers globally or per-PDF. Configure via environment variables or at runtime. ```php use Spatie\LaravelPdf\Facades\Pdf; // Use a specific driver for this PDF Pdf::view('pdf.invoice', ['invoice' => $invoice]) ->driver('cloudflare') // 'browsershot', 'cloudflare', 'dompdf', 'gotenberg' ->format('a4') ->save('invoice.pdf'); // Environment configuration (.env) // LARAVEL_PDF_DRIVER=cloudflare // CLOUDFLARE_API_TOKEN=your-token // CLOUDFLARE_ACCOUNT_ID=your-account-id // Or for Gotenberg (Docker-based) // LARAVEL_PDF_DRIVER=gotenberg // GOTENBERG_URL=http://localhost:3000 ``` ## Customizing Browsershot Customize the underlying Browsershot instance for advanced Chrome/Puppeteer options. ```php use Spatie\LaravelPdf\Facades\Pdf; use Spatie\Browsershot\Browsershot; Pdf::view('pdf.invoice', ['invoice' => $invoice]) ->withBrowsershot(function (Browsershot $browsershot) { $browsershot ->scale(0.8) ->setOption('args', ['--disable-web-security']) ->waitUntilNetworkIdle(); }) ->save('invoice.pdf'); // Set Browsershot defaults for all PDFs in a service provider Pdf::default()->withBrowsershot(function (Browsershot $browsershot) { $browsershot->setOption('args', [ '--disable-web-security', '--allow-file-access-from-files', ]); }); ``` ## AWS Lambda PDF Generation Offload PDF generation to AWS Lambda using Sidecar for better performance and scalability. ```php use Spatie\LaravelPdf\Facades\Pdf; // Generate single PDF on Lambda Pdf::view('pdf.invoice', $data) ->onLambda() ->save('invoice.pdf'); // Set Lambda as default for all PDFs (in service provider) Pdf::default()->onLambda(); ``` ## Setting Global Defaults Configure default options for all PDFs in a service provider. ```php use Spatie\LaravelPdf\Facades\Pdf; use Spatie\LaravelPdf\Enums\Format; // In AppServiceProvider::boot() Pdf::default() ->headerView('pdf.default-header') ->footerView('pdf.default-footer') ->format(Format::A4) ->margins(15, 10, 15, 10); // Individual PDFs can still override defaults Pdf::html('<h1>Hello</h1>') ->format(Format::Letter) // Overrides A4 default ->save('document.pdf'); ``` ## Extending with Macros Add custom methods to the PdfBuilder class using Laravel's macro functionality. ```php use Spatie\LaravelPdf\PdfBuilder; // In AppServiceProvider::boot() PdfBuilder::macro('companyInvoice', function (string $invoiceNumber) { return $this ->headerView('pdf.company-header') ->footerHtml('<div>Invoice ' . $invoiceNumber . '</div>') ->format('a4'); }); // Usage Pdf::view('pdf.invoice', ['invoice' => $invoice]) ->companyInvoice($invoice->number) ->save('invoice.pdf'); ``` ## Creating Custom Drivers Implement the PdfDriver interface to create custom PDF generation backends. ```php namespace App\Pdf\Drivers; use Spatie\LaravelPdf\Drivers\PdfDriver; use Spatie\LaravelPdf\PdfOptions; class WeasyPrintDriver implements PdfDriver { public function __construct(protected array $config = []) {} public function generatePdf( string $html, ?string $headerHtml, ?string $footerHtml, PdfOptions $options, ): string { // Generate PDF and return content as string $process = Process::run(['weasyprint', '-', '-'], $html); return $process->output(); } public function savePdf( string $html, ?string $headerHtml, ?string $footerHtml, PdfOptions $options, string $path, ): void { file_put_contents($path, $this->generatePdf($html, $headerHtml, $footerHtml, $options)); } } // Register in service provider $this->app->singleton('laravel-pdf.driver.weasyprint', fn () => new WeasyPrintDriver()); // Use the custom driver Pdf::view('invoice')->driver('weasyprint')->save('invoice.pdf'); ``` ## Testing PDFs Use the fake() method to mock PDF generation and make assertions in tests. ```php use Spatie\LaravelPdf\Facades\Pdf; use Spatie\LaravelPdf\PdfBuilder; it('generates an invoice PDF', function () { Pdf::fake(); $invoice = Invoice::factory()->create(); $this->get(route('invoice.download', $invoice))->assertOk(); // Assert PDF was returned as response Pdf::assertRespondedWithPdf(function (PdfBuilder $pdf) use ($invoice) { return $pdf->downloadName === 'invoice.pdf' && $pdf->isDownload() && str_contains($pdf->html, $invoice->number); }); }); it('saves invoice to storage', function () { Pdf::fake(); GenerateInvoice::dispatch($invoice); // Assert PDF was saved to specific path Pdf::assertSaved(function (PdfBuilder $pdf, string $path) { return $path === storage_path('invoices/invoice.pdf') && $pdf->viewName === 'pdf.invoice'; }); }); it('queues PDF generation', function () { Pdf::fake(); QueueInvoice::dispatch($invoice); Pdf::assertQueued(function (PdfBuilder $pdf, string $path) { return $path === 'invoice.pdf' && $pdf->contains('Total'); }); }); // Simple assertion methods Pdf::assertViewIs('pdf.invoice'); Pdf::assertSee('Total: $100.00'); Pdf::assertViewHas('invoice', $invoice); Pdf::assertNotQueued(); ``` ## Using Tailwind CSS Style PDFs with Tailwind CSS using the Chromium-based drivers (Browsershot, Cloudflare, Gotenberg). ```blade {{-- resources/views/pdf/invoice.blade.php --}} <html> <head> <script src="https://cdn.tailwindcss.com"></script> </head> <body class="bg-white"> <div class="max-w-2xl mx-auto p-8"> <div class="flex justify-between items-center mb-8"> <h1 class="text-2xl font-bold text-gray-800">Invoice</h1> <span class="text-gray-600">#{{ $invoice->number }}</span> </div> <table class="w-full mb-8"> <thead> <tr class="border-b-2 border-gray-300"> <th class="text-left py-2">Item</th> <th class="text-right py-2">Amount</th> </tr> </thead> <tbody> @foreach($invoice->items as $item) <tr class="border-b border-gray-200"> <td class="py-2">{{ $item->name }}</td> <td class="text-right py-2">${{ number_format($item->amount, 2) }}</td> </tr> @endforeach </tbody> </table> <div class="text-right text-xl font-bold"> Total: ${{ number_format($invoice->total, 2) }} </div> </div> </body> </html> ``` ## Inline Images in Headers/Footers Use the @inlinedImage directive to embed images in headers and footers. ```blade {{-- resources/views/pdf/header.blade.php --}} <style> .header { display: flex; justify-content: space-between; align-items: center; } .logo { height: 40px; } </style> <div class="header"> @php $logo = public_path('images/logo.png'); @endphp @inlinedImage($logo) <span>{{ $company->name }}</span> </div> {{-- Or use a URL --}} @inlinedImage('https://example.com/logo.png') ``` ## Configuration Reference Complete configuration file with all available options. ```php // config/laravel-pdf.php return [ 'driver' => env('LARAVEL_PDF_DRIVER', 'browsershot'), 'browsershot' => [ 'node_binary' => env('LARAVEL_PDF_NODE_BINARY'), 'npm_binary' => env('LARAVEL_PDF_NPM_BINARY'), 'chrome_path' => env('LARAVEL_PDF_CHROME_PATH'), 'node_modules_path' => env('LARAVEL_PDF_NODE_MODULES_PATH'), 'include_path' => env('LARAVEL_PDF_INCLUDE_PATH'), 'bin_path' => env('LARAVEL_PDF_BIN_PATH'), 'temp_path' => env('LARAVEL_PDF_TEMP_PATH'), 'write_options_to_file' => env('LARAVEL_PDF_WRITE_OPTIONS_TO_FILE', false), 'no_sandbox' => env('LARAVEL_PDF_NO_SANDBOX', false), ], 'cloudflare' => [ 'api_token' => env('CLOUDFLARE_API_TOKEN'), 'account_id' => env('CLOUDFLARE_ACCOUNT_ID'), ], 'gotenberg' => [ 'url' => env('GOTENBERG_URL', 'http://localhost:3000'), ], 'dompdf' => [ 'is_remote_enabled' => env('LARAVEL_PDF_DOMPDF_REMOTE_ENABLED', false), 'chroot' => env('LARAVEL_PDF_DOMPDF_CHROOT'), ], 'job' => \Spatie\LaravelPdf\Jobs\GeneratePdfJob::class, ]; ``` Laravel PDF is ideal for generating invoices, reports, contracts, receipts, and any document requiring PDF output in Laravel applications. The driver-based architecture allows you to choose the best backend for your infrastructure - use Browsershot for full CSS support with local Chrome, Cloudflare for serverless deployments, Gotenberg for containerized environments, or DOMPDF for simple PDFs without external dependencies. The package follows Laravel conventions with its fluent API, Blade integration, filesystem abstraction support, and queue compatibility. Combined with the comprehensive testing utilities, it provides a complete solution for PDF generation that scales from simple documents to complex, high-volume PDF workflows. The macroable PdfBuilder class and custom driver support ensure you can extend the package to meet any specialized requirements.