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.
Install the package:
composer require pontedilana/php-weasyprint
Install WeasyPrint (Python-based, version ≥60):
pip install weasyprint>=60
Ensure the binary (weasyprint) is in your PATH or specify its full path.
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');
$pdf->disableTimeout()) to avoid conflicts with Laravel’s queue workers.$html = view('pdf.invoice', ['data' => $invoice])->render();
$pdf = new Pdf('/usr/local/bin/weasyprint');
$pdf->generateFromHtml($html, storage_path("app/invoices/{$invoice->id}.pdf"));
view()->share()).$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');
// 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);
}
shouldQueue() and dispatch() in Laravel.PdfService).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);
}
}
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);
}
$pdf->setOption('media-type', 'screen'); // Render as if viewed on screen
$pdf->setOption('stylesheet', [public_path('css/pdf-styles.css')]);
$pdf->setTimeout(60); // 60 seconds
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');
}
WeasyPrint Binary Path:
weasyprint command not found./usr/local/bin/weasyprint).which weasyprint in your server’s shell to confirm the path.Timeout Conflicts:
$pdf->disableTimeout();
$pdf->setTimeout(120); // 2 minutes
CSS/JS Limitations:
calc(), filter) breaks rendering.Memory Usage:
optimize-images: true:
$pdf->setOption('optimize-images', true);
HTTP Redirects:
$pdf->setOption('no-http-redirects', true); // Block redirects
// or
$pdf->setOption('http-redirects', true); // Allow redirects (default)
Font Issues:
@font-face in CSS with src: url() pointing to local font files.WeasyPrint Version Mismatch:
composer update pontedilana/php-weasyprint
pip install --upgrade weasyprint
Log WeasyPrint Output:
$pdf->setOption('verbose', true);
Test with Minimal HTML:
$pdf->generateFromHtml('<h1>Test</h1>', '/tmp/test.pdf');
Check WeasyPrint CLI:
weasyprint --verbose https://example.com /tmp/test.pdf
Validate HTML/CSS:
Custom Options:
Pdf class:
class CustomPdf extends \Pontedilana\PhpWeasyPrint\Pdf {
public function setCustomOption(string $name, $value) {
$this->setOption($name, $value);
}
}
--dpi support (if available in newer WeasyPrint versions).Pre/Post-Processing:
$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
How can I help you explore Laravel packages today?