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

Php Weasyprint Laravel Package

pontedilana/php-weasyprint

PHP wrapper for WeasyPrint (v60+) to generate PDFs from URLs or HTML. Snappy-like API with output streaming or file generation, supports WeasyPrint CLI options (encoding, media type, stylesheets, attachments) and timeouts.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the package:

    composer require pontedilana/php-weasyprint
    
  2. Install WeasyPrint (Python-based, version ≥60):

    pip install weasyprint>=60
    

    Ensure the binary (weasyprint) is in your PATH or specify its full path.

  3. First use case: Generate a PDF from a URL and output it directly:

    use Pontedilana\PhpWeasyPrint\Pdf;
    
    $pdf = new Pdf('/usr/local/bin/weasyprint');
    header('Content-Type: application/pdf');
    echo $pdf->getOutput('https://example.com');
    

Key Starting Points

  • For Laravel: Use the package in controllers, jobs, or commands.
  • For CLI tools: Directly output PDFs to files or streams.
  • For queues: Disable timeouts ($pdf->disableTimeout()) to avoid conflicts with Laravel’s queue workers.

Implementation Patterns

Core Workflows

1. Dynamic PDF Generation from HTML

  • Use case: Invoices, reports, or user-generated content.
  • Pattern:
    $html = view('pdf.invoice', ['data' => $invoice])->render();
    $pdf = new Pdf('/usr/local/bin/weasyprint');
    $pdf->generateFromHtml($html, storage_path("app/invoices/{$invoice->id}.pdf"));
    
  • Tip: Cache generated HTML if the PDF is static (e.g., view()->share()).

2. URL-to-PDF for External Content

  • Use case: Archiving web pages or generating PDFs from third-party URLs.
  • Pattern:
    $pdf = new Pdf('/usr/local/bin/weasyprint');
    $pdf->setOption('no-http-redirects', true); // Avoid following redirects
    return response($pdf->getOutput('https://api.example.com/report'))
        ->header('Content-Type', 'application/pdf');
    

3. Queue-Based PDF Generation

  • Use case: Async processing for large PDFs or batch jobs.
  • Pattern:
    // Job class
    public function handle() {
        $pdf = new Pdf('/usr/local/bin/weasyprint');
        $pdf->disableTimeout(); // Let Laravel Queue handle timeouts
        $pdf->generateFromHtml($this->html, $this->path);
    }
    
  • Tip: Use shouldQueue() and dispatch() in Laravel.

4. Reusable PDF Service

  • Use case: Centralize PDF logic (e.g., in a PdfService).
  • Pattern:
    class PdfService {
        protected $pdf;
    
        public function __construct() {
            $this->pdf = new Pdf(config('weasyprint.binary'));
        }
    
        public function generateFromView(string $view, array $data, string $path) {
            $html = view($view, $data)->render();
            $this->pdf->generateFromHtml($html, $path);
        }
    }
    
  • Tip: Inject the service via Laravel’s container or constructor.

Integration Tips

Laravel-Specific

  • Configuration: Store the WeasyPrint binary path in config/weasyprint.php:

    return [
        'binary' => env('WEASYPRINT_BINARY', '/usr/local/bin/weasyprint'),
    ];
    

    Use config('weasyprint.binary') in your code.

  • Middleware: Add PDF headers for downloadable responses:

    public function handle($request, Closure $next) {
        if ($request->wantsPdf()) {
            header('Content-Type: application/pdf');
            header('Content-Disposition: attachment; filename="document.pdf"');
        }
        return $next($request);
    }
    
  • Events: Trigger PDF generation after model events (e.g., saved):

    public function saved(Invoice $invoice) {
        $pdfService->generateFromView('pdf.invoice', ['invoice' => $invoice], $invoice->pdf_path);
    }
    

Advanced Options

  • CSS/JS Control: Pass WeasyPrint options for fine-tuning:
    $pdf->setOption('media-type', 'screen'); // Render as if viewed on screen
    $pdf->setOption('stylesheet', [public_path('css/pdf-styles.css')]);
    
  • Timeouts: Adjust for slow environments:
    $pdf->setTimeout(60); // 60 seconds
    
  • Error Handling: Wrap calls in try-catch:
    try {
        $pdf->generateFromHtml($html, $path);
    } catch (\Pontedilana\PhpWeasyPrint\Exception\GenerationException $e) {
        Log::error('PDF generation failed', ['error' => $e->getMessage()]);
        abort(500, 'Failed to generate PDF');
    }
    

Gotchas and Tips

Pitfalls

  1. WeasyPrint Binary Path:

    • Issue: weasyprint command not found.
    • Fix: Verify the binary is installed and the path is correct. Use absolute paths (e.g., /usr/local/bin/weasyprint).
    • Debug: Run which weasyprint in your server’s shell to confirm the path.
  2. Timeout Conflicts:

    • Issue: PDF generation hangs or fails in queues.
    • Fix: Disable the internal timeout if using Laravel’s queue system:
      $pdf->disableTimeout();
      
    • Alternative: Set a higher timeout:
      $pdf->setTimeout(120); // 2 minutes
      
  3. CSS/JS Limitations:

    • Issue: Complex JavaScript or unsupported CSS (e.g., calc(), filter) breaks rendering.
    • Fix: Test with WeasyPrint’s CSS support table. Use inline styles or minimal external CSS for critical PDFs.
  4. Memory Usage:

    • Issue: Large HTML or images cause high memory usage.
    • Fix:
      • Optimize images before generating PDFs.
      • Use optimize-images: true:
        $pdf->setOption('optimize-images', true);
        
      • Generate PDFs in chunks for very large documents.
  5. HTTP Redirects:

    • Issue: URLs with redirects fail silently.
    • Fix: Explicitly allow or block redirects:
      $pdf->setOption('no-http-redirects', true); // Block redirects
      // or
      $pdf->setOption('http-redirects', true); // Allow redirects (default)
      
  6. Font Issues:

    • Issue: Custom fonts render as boxes or default fonts.
    • Fix: Ensure fonts are embedded or available on the server. Use @font-face in CSS with src: url() pointing to local font files.
  7. WeasyPrint Version Mismatch:

    • Issue: New WeasyPrint options are unsupported.
    • Fix: Update the package and WeasyPrint:
      composer update pontedilana/php-weasyprint
      pip install --upgrade weasyprint
      

Debugging Tips

  1. Log WeasyPrint Output:

    • Enable verbose logging to debug rendering issues:
      $pdf->setOption('verbose', true);
      
    • Check Laravel logs for WeasyPrint errors.
  2. Test with Minimal HTML:

    • Isolate issues by testing with a simple HTML string:
      $pdf->generateFromHtml('<h1>Test</h1>', '/tmp/test.pdf');
      
  3. Check WeasyPrint CLI:

    • Test WeasyPrint directly via CLI to rule out PHP wrapper issues:
      weasyprint --verbose https://example.com /tmp/test.pdf
      
  4. Validate HTML/CSS:

    • Use tools like W3C Validator to ensure clean HTML/CSS before PDF generation.

Extension Points

  1. Custom Options:

    • Add support for new WeasyPrint options by extending the Pdf class:
      class CustomPdf extends \Pontedilana\PhpWeasyPrint\Pdf {
          public function setCustomOption(string $name, $value) {
              $this->setOption($name, $value);
          }
      }
      
    • Example: Add --dpi support (if available in newer WeasyPrint versions).
  2. Pre/Post-Processing:

    • Hook into PDF generation to modify HTML or handle post-generation tasks:
      $pdf = new Pdf('/usr/local/bin/weasyprint');
      $html = $this->preProcessHtml($rawHtml); // Add headers, watermarks, etc.
      $pdf->generateFromHtml($html, $path);
      $this->postProcessPdf($path); // Compress, sign, etc.
      

3

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.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai