Installation:
composer require greenter/htmltopdf
Ensure wkhtmltopdf is installed on your system (Linux/Windows/macOS). Check wkhtmltopdf docs for installation instructions.
Basic Usage:
use Greenter\HtmlToPdf\HtmlToPdf;
$html = '<h1>Hello, PDF!</h1><p>This is a test.</p>';
$pdf = new HtmlToPdf();
$pdf->setHtml($html);
$pdf->setOptions(['orientation' => 'Portrait']);
$pdf->saveAs('output.pdf');
First Use Case: Convert a Blade template to PDF in a Laravel controller:
use Greenter\HtmlToPdf\HtmlToPdf;
use Illuminate\Support\Facades\View;
public function generatePdf()
{
$html = View::make('invoice.template', ['data' => $invoiceData])->render();
$pdf = new HtmlToPdf();
$pdf->setHtml($html);
$pdf->saveAs(storage_path('app/invoice.pdf'));
return response()->download(storage_path('app/invoice.pdf'));
}
Dynamic PDF Generation: Use Blade templates for dynamic content:
$html = View::make('report', ['user' => $user])->render();
$pdf->setHtml($html);
Streaming PDFs: Stream directly to the browser without saving to disk:
$pdf->setHtml($html);
$pdf->stream('invoice.pdf');
Custom wkhtmltopdf Options: Pass options like margins, page size, or headers/footers:
$pdf->setOptions([
'margin-top' => 20,
'margin-right' => 20,
'margin-bottom' => 20,
'margin-left' => 20,
'footer-html' => '<div>Page <span class="page-number"></span></div>',
]);
Queueing Long-Running Jobs: Use Laravel queues to avoid timeouts for complex PDFs:
GeneratePdfJob::dispatch($html, $path)->onQueue('pdfs');
Laravel Service Provider: Bind the package to the container for dependency injection:
$this->app->bind(HtmlToPdf::class, function ($app) {
return new HtmlToPdf();
});
Configuration:
Override default wkhtmltopdf path in config/services.php:
'wkhtmltopdf' => [
'binary' => '/usr/local/bin/wkhtmltopdf',
],
Testing:
Mock the HtmlToPdf class in unit tests:
$mock = Mockery::mock(HtmlToPdf::class);
$mock->shouldReceive('setHtml')->once();
$mock->shouldReceive('saveAs')->once();
wkhtmltopdf Binary Path:
wkhtmltopdf isn’t in PATH, explicitly set the binary path in the constructor or config.Command not found or Failed to execute command.Memory Limits:
queue:work or increase memory_limit in php.ini.CSS/JS Dependencies:
file:// URLs or base64-encoded assets.file:// to local paths or use asset() helper in Blade.Font Issues:
@font-face with local paths.Deprecated Methods:
Logs:
Enable verbose logging in wkhtmltopdf via options:
$pdf->setOptions(['quiet' => false]);
Check Laravel logs for wkhtmltopdf errors.
Dry Runs: Test with a simple HTML string before complex templates:
$pdf->setHtml('<h1>Test</h1>')->saveAs('test.pdf');
Caching: Cache generated PDFs to avoid reprocessing:
if (!file_exists($cachedPath)) {
$pdf->saveAs($cachedPath);
}
Headers/Footers:
Use header-html/footer-html options for consistent branding:
$pdf->setOptions([
'header-html' => view('pdf.header')->render(),
'footer-html' => view('pdf.footer')->render(),
]);
Laravel Mix Integration: Process CSS/JS assets with Laravel Mix and embed them in Blade:
<link href="{{ mix('css/pdf.css') }}" rel="stylesheet">
<script src="{{ mix('js/pdf.js') }}"></script>
Fallback for Missing wkhtmltopdf:
Gracefully handle missing binary:
try {
$pdf->saveAs('output.pdf');
} catch (\Exception $e) {
Log::error('wkhtmltopdf not found: ' . $e->getMessage());
return back()->withError('PDF generation failed.');
}
Performance: Disable JavaScript rendering for static content:
$pdf->setOptions(['disable-javascript' => true]);
How can I help you explore Laravel packages today?