Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Pdf Laravel Package

spatie/laravel-pdf

Generate PDFs in Laravel from Blade views with a fluent API. Choose drivers like Chromium (Browsershot), Gotenberg, Cloudflare, WeasyPrint, or DOMPDF. Save to disk or return as a response, with support for modern CSS and paged media.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require spatie/laravel-pdf
    

    Run migrations if using the pdf table:

    php artisan migrate
    
  2. First PDF Generation: Use the Pdf facade to generate a PDF from a Blade view:

    use Spatie\Pdf\Pdf;
    
    $pdf = Pdf::loadView('invoice', ['data' => $invoiceData])
        ->setOptions(['defaultFont' => 'DejaVu Sans'])
        ->save(storage_path('app/invoice.pdf'));
    
  3. Quick Use Case: Generate an invoice PDF on demand:

    public function generateInvoice($invoiceId)
    {
        $invoice = Invoice::findOrFail($invoiceId);
        return Pdf::loadView('invoices.pdf', compact('invoice'))
            ->stream('invoice-' . $invoice->id . '.pdf');
    }
    

Key Files to Review

  • Config: config/pdf.php (default options, paths, and storage settings).
  • Facade: Spatie\Pdf\Facades\Pdf (primary API entry point).
  • Service Provider: Spatie\Pdf\PdfServiceProvider (bootstrapping logic).

Implementation Patterns

Common Workflows

  1. Blade-to-PDF Conversion:

    // Generate and download
    return Pdf::loadView('report', ['items' => $items])
        ->download('report.pdf');
    
    // Generate and stream (for direct browser display)
    return Pdf::loadView('report', ['items' => $items])
        ->stream('report.pdf');
    
  2. Dynamic PDF Options: Override default settings per request:

    Pdf::loadView('document')
        ->setOptions([
            'format' => 'A4',
            'orientation' => 'landscape',
            'margin_top' => 20,
            'margin_bottom' => 20,
        ]);
    
  3. Storing PDFs: Save to disk or database:

    // Disk storage
    $path = Pdf::loadView('document')->save(storage_path('pdfs/document.pdf'));
    
    // Database storage (if using `pdf` table)
    $pdf = Pdf::loadView('document')->save();
    $pdf->path; // Retrieve path later
    
  4. Queueing PDF Generation: Use Laravel queues to offload heavy PDF generation:

    // Job
    public function handle()
    {
        Pdf::loadView('large-report', ['data' => $this->data])
            ->save(storage_path('reports/large-report.pdf'));
    }
    
    // Dispatch
    GenerateLargeReportJob::dispatch($data);
    
  5. Reusing PDF Logic: Create a service class for complex PDFs:

    class InvoicePdfService
    {
        public function generate(Invoice $invoice)
        {
            return Pdf::loadView('invoices.detailed', compact('invoice'))
                ->setOptions(['defaultFont' => 'Arial']);
        }
    }
    

Integration Tips

  • Laravel Mail: Attach PDFs to emails:

    Mail::send([], [], function ($message) use ($pdf) {
        $message->subject('Your Invoice');
        $message->attach(
            $pdf->save(storage_path('temp/invoice.pdf')),
            ['as' => 'invoice.pdf', 'mime' => 'application/pdf']
        );
    });
    
  • Laravel Notifications: Send PDFs via notifications:

    public function toMail($notifiable)
    {
        $pdf = Pdf::loadView('receipt', ['order' => $this->order]);
        return (new MailMessage)
            ->subject('Your Receipt')
            ->attach($pdf->save(storage_path('temp/receipt.pdf')));
    }
    
  • API Responses: Return PDFs in API responses:

    return response()->streamDownload(
        function () use ($pdf) {
            echo $pdf->save(storage_path('temp/api-pdf.pdf'));
        },
        'api-report.pdf'
    );
    

Gotchas and Tips

Common Pitfalls

  1. Font Issues:

    • Problem: Missing fonts cause errors or garbled text.
    • Fix: Ensure fonts are installed on the server or specify a fallback:
      ->setOptions(['defaultFont' => 'DejaVu Sans', 'fontSize' => 12]);
      
    • Debug: Check storage/logs/laravel.log for font-related errors.
  2. Memory Limits:

    • Problem: Large PDFs (e.g., multi-page reports) may hit PHP memory limits.
    • Fix:
      • Increase memory_limit in php.ini.
      • Use ->setOptions(['dpi' => 96]) to reduce resolution.
      • Offload to a queue (see Queueing PDF Generation above).
  3. Path Handling:

    • Problem: Incorrect paths when saving PDFs.
    • Fix: Use Laravel’s helpers:
      $path = storage_path('app/pdfs/' . $filename);
      
    • Debug: Verify paths with file_exists() before saving.
  4. Caching:

    • Problem: Cached views may cause stale PDFs.
    • Fix: Clear view cache or use unique filenames:
      $filename = 'report-' . now()->timestamp . '.pdf';
      
  5. DOM Complexity:

    • Problem: Blade views with complex CSS/JS may render poorly.
    • Fix:
      • Simplify CSS (avoid @media queries, position: fixed).
      • Use inline styles where possible.
      • Test with ->setOptions(['disableSmartShrinking' => true]).

Debugging Tips

  • Log PDF Options:

    $pdf = Pdf::loadView('view');
    \Log::info('PDF Options:', $pdf->getOptions());
    
  • Inspect Generated HTML:

    $html = Pdf::loadView('view')->getHtml();
    file_put_contents(storage_path('debug.html'), $html);
    
  • Check DomPDF Errors: Enable DomPDF’s error handling:

    ->setOptions(['isHtml5ParserEnabled' => true, 'isRemoteEnabled' => true]);
    

Extension Points

  1. Custom DomPDF Configuration: Override DomPDF’s default settings globally in config/pdf.php:

    'dompdf' => [
        'font_cache' => storage_path('fonts'),
        'tempDir' => storage_path('temp'),
        'chroot' => null,
    ],
    
  2. Event Listeners: Listen for PDF generation events (e.g., PdfGenerated):

    Pdf::loadView('document')->save(storage_path('pdfs/doc.pdf'))
        ->then(function ($path) {
            // Post-processing (e.g., upload to S3)
        });
    
  3. Middleware: Restrict PDF generation to specific routes:

    Route::middleware(['auth', 'can:generate-pdfs'])->group(function () {
        // Routes requiring PDF generation
    });
    
  4. Testing: Mock PDF generation in tests:

    Pdf::shouldReceive('loadView')
        ->once()
        ->andReturnSelf()
        ->shouldReceive('save')
        ->once()
        ->andReturn('/fake/path.pdf');
    

Pro Tips

  • Dynamic Content: Use Blade components for reusable PDF sections:

    // In Blade
    @component('pdf.table', ['data' => $data])
    
    // In PHP
    Pdf::loadView('document', ['sections' => $sections]);
    
  • Localization: Support multiple languages by passing locale to the view:

    Pdf::loadView('document', ['locale' => app()->getLocale()]);
    
  • Performance: Pre-generate static PDFs and serve them via CDN:

    // Cache the PDF for 1 hour
    $pdf = Pdf::loadView('static-page')->save(storage_path('cached/page.pdf'));
    
  • Security: Sanitize dynamic content to prevent DOMPDF injection:

    $cleanedData = strip_tags($userInput, '<b><i><u>');
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport