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

Pdf Bundle Laravel Package

eckinox/pdf-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First PDF

  1. Install Dependencies:

    # Install Puppeteer (Ubuntu example)
    curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash -
    sudo apt-get install -y nodejs gconf-service libasound2 libatk1.0-0
    sudo npm install --global --unsafe-perm puppeteer
    

    Verify: Run puppeteer --version in terminal.

  2. Add Bundle:

    composer require eckinox/pdf-bundle
    
  3. Configure Request Context (config/services.yaml):

    parameters:
        router.request_context.host: 'your-app.com'
        router.request_context.scheme: 'https'
    
  4. Create a Twig Template (resources/views/report.html.twig):

    <html>
        <body>
            <h1>{{ title }}</h1>
            <p>Generated on {{ date }}</p>
        </body>
    </html>
    
  5. Generate PDF in Controller (app/Http/Controllers/ReportController.php):

    use Eckinox\PdfBundle\Pdf\PdfGeneratorInterface;
    
    public function generatePdf(PdfGeneratorInterface $pdfGenerator)
    {
        $pdf = $pdfGenerator->renderPdf('report', [
            'title' => 'Monthly Report',
            'date' => now()->format('Y-m-d')
        ]);
        return $pdf->download('report.pdf');
    }
    
  6. Test: Visit /report in your browser to trigger the download.


First Use Case: Dynamic Invoices

  • Template: invoice.html.twig with placeholders for {client_name}, {amount}, {due_date}.
  • Controller:
    $pdf = $pdfGenerator->renderPdf('invoice', [
        'client_name' => $client->name,
        'amount' => $invoice->total,
        'due_date' => $invoice->due_date->format('Y-m-d')
    ]);
    return $pdf->download("invoice_$invoice->id.pdf");
    

Implementation Patterns

Core Workflows

1. Templating with Twig

  • Data Binding: Pass arrays to renderPdf() to populate Twig variables.
  • Layouts: Extend base templates (e.g., base.pdf.twig) for consistent headers/footers.
  • CSS: Use @page rules for margins:
    @page {
        size: A4;
        margin: 1cm;
    }
    

2. PDF Output Strategies

Use Case Method Example
Browser Preview output('filename.pdf') return $pdf->output('preview.pdf');
Force Download download('filename.pdf') return $pdf->download('invoice.pdf');
Store in Filesystem getContent() + file_put_contents $content = $pdf->getContent(); file_put_contents('storage/reports/report.pdf', $content);
Upload to S3 getContent() + AWS SDK $s3->putObject(['Body' => $pdf->getContent()], 'reports/report.pdf');

3. Reusable PDF Services

  • Service Class:
    namespace App\Services;
    
    use Eckinox\PdfBundle\Pdf\PdfGeneratorInterface;
    
    class PdfService {
        public function __construct(private PdfGeneratorInterface $generator) {}
    
        public function generateCertificate(string $name): string {
            return $this->generator->renderPdf('certificate', ['name' => $name])->getContent();
        }
    }
    
  • Register in config/services.php:
    $app->bind(PdfService::class, function ($app) {
        return new PdfService($app->make(PdfGeneratorInterface::class));
    });
    

4. Dynamic Formats

  • A4 Portrait:
    $pdf = $pdfGenerator->renderPdf('template', [], FormatFactory::a4());
    
  • Custom Size (e.g., 5in x 7in):
    $format = new Format("5in", "7in");
    $pdf = $pdfGenerator->renderPdf('template', [], $format);
    

5. Asynchronous Generation

  • Use Laravel Queues to offload PDF generation:
    // Dispatch job
    GeneratePdfJob::dispatch($userId, 'report_template');
    
    // Job class
    public function handle() {
        $pdf = $this->generator->renderPdf('report_template', ['user' => User::find($this->userId)]);
        Storage::put("reports/user_{$this->userId}.pdf", $pdf->getContent());
    }
    

Integration Tips

1. With Laravel Mailables

  • Attach PDFs to emails:
    public function build() {
        $pdf = app(PdfGeneratorInterface::class)->renderPdf('invoice', $this->data);
        return $this->attachData($pdf->getContent(), 'invoice.pdf');
    }
    

2. With Laravel Notifications

  • Send PDFs via notifications:
    public function toMail($notifiable) {
        $pdf = app(PdfGeneratorInterface::class)->renderPdf('receipt', ['order' => $this->order]);
        return (new MailMessage)
            ->subject('Your Receipt')
            ->attachData($pdf->getContent(), 'receipt.pdf');
    }
    

3. With Laravel Excel

  • Export Excel to PDF:
    $excel = Excel::download(new UsersExport, 'users.xlsx');
    $pdf = app(PdfGeneratorInterface::class)->renderPdf('excel_to_pdf', ['content' => $excel->getContent()]);
    

4. With Livewire

  • Generate PDFs on demand in Livewire components:
    public function generatePdf() {
        $pdf = app(PdfGeneratorInterface::class)->renderPdf('livewire_report', $this->data);
        return response()->streamDownload(function () use ($pdf) {
            echo $pdf->getContent();
        }, 'report.pdf');
    }
    

5. Testing

  • Mock PdfGeneratorInterface in tests:
    $mock = Mockery::mock(PdfGeneratorInterface::class);
    $mock->shouldReceive('renderPdf')->andReturn(new class implements PdfInterface {
        public function output(string $filename = null) { return new Response(); }
        public function download(string $filename = null) { return new Response(); }
        public function getContent() { return 'PDF_CONTENT'; }
    });
    

Gotchas and Tips

Pitfalls

  1. Puppeteer Dependencies:

    • Issue: Missing system libraries cause puppeteer to fail silently.
    • Fix: Use the provided Ubuntu snippet or refer to Puppeteer’s troubleshooting guide.
    • Debug: Check logs for Failed to launch the browser process! errors.
  2. Large PDF Filesizes:

    • Issue: Images/emojis bloat PDFs due to Chromium’s rendering.
    • Fix: Wrap images in SVG tags:
      <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
          <image href="{{ asset('image.png') }}" width="100" height="100" />
      </svg>
      
  3. CSS Margins Ignored:

    • Issue: @page margins in CSS are not respected by Puppeteer.
    • Workaround: Use physical units (cm, in) and apply margins to the <body> or <div>:
      body { margin: 1cm; }
      
  4. Font Rendering Issues:

    • Issue: Custom fonts may not render correctly.
    • Fix: Host fonts locally and reference them in CSS:
      @font-face {
          font-family: 'CustomFont';
          src: url('/fonts/CustomFont.woff2') format('woff2');
      }
      body { font-family: 'CustomFont', sans-serif; }
      
  5. Memory Limits:

    • Issue: Complex PDFs hit PHP’s memory_limit.
    • Fix: Increase memory_limit in php.ini or optimize templates (e.g., lazy-load images).
  6. Filename Sanitization:

    • Issue: Special characters in filenames cause errors.
    • Fix: Use Str::slug() or Str::of($filename)->slug() to sanitize:
      $filename = Str::slug($user->name) . '.pdf';
      return $pdf->download($filename);
      
  7. Headless Chrome Crashes:

    • Issue: Puppete
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky