Installation:
composer require nucleos/dompdf-bundle
Ensure the bundle is enabled in config/bundles.php:
return [
// ...
Nucleos\DompdfBundle\NucleosDompdfBundle::class => ['all' => true],
];
Basic Usage:
Inject the Dompdf service into a controller or service:
use Nucleos\DompdfBundle\Service\Dompdf;
class PdfController extends AbstractController
{
public function generatePdf(Dompdf $dompdf): Response
{
$dompdf->loadHtml('<h1>Hello, Dompdf!</h1>');
$dompdf->render();
return new Response($dompdf->getContent(), 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'inline; filename="example.pdf"',
]);
}
}
First Use Case: Generate a PDF from a Twig template:
$dompdf->loadHtml($this->renderView('pdf/template.html.twig', ['data' => $data]));
Dynamic PDF Generation: Use Twig templates for reusable PDF layouts:
$html = $this->renderView('emails/invoice.html.twig', ['invoice' => $invoice]);
$dompdf->loadHtml($html);
Streaming PDFs: Stream PDFs directly to the browser without saving to disk:
return new StreamedResponse(function () use ($dompdf) {
echo $dompdf->getContent();
}, 200, [
'Content-Type' => 'application/pdf',
'Content-Disposition' => 'attachment; filename="report.pdf"',
]);
Styling and Assets: Configure Dompdf to handle CSS and assets:
# config/packages/nucleos_dompdf.yaml
nucleos_dompdf:
options:
isRemoteEnabled: true
isHtml5ParserEnabled: true
Queueing PDF Jobs: Use Symfony Messenger to offload PDF generation:
$this->messageBus->dispatch(new GeneratePdfJob($data, $template));
Handler:
public function __invoke(GeneratePdfJob $job, Dompdf $dompdf)
{
$dompdf->loadHtml($this->renderView($job->template, $job->data));
return new Response($dompdf->getContent(), 200, [
'Content-Disposition' => 'attachment; filename="job.pdf"',
]);
}
Customizing Headers/Footers: Use Dompdf’s built-in features or extend the bundle:
$dompdf->getDompdf()->setOption('defaultFont', 'Arial');
$dompdf->getDompdf()->setOption('isPhpEnabled', true);
CSS Limitations:
flexbox, grid).!important sparingly; Dompdf may not respect it as expected.Memory Issues:
memory_limit in php.ini).Asset Loading:
isRemoteEnabled: true in config.nucleos_dompdf.options.isRemoteEnabled and ensure allow_url_fopen is enabled in php.ini.Twig Caching:
flush() before rendering:
$this->get('twig')->getEnvironment()->clearCacheFile($templatePath);
Dependency Conflicts:
dompdf/dompdf.composer why-not to resolve conflicts or pin versions in composer.json.Inspect HTML: Use Dompdf’s debug mode to see how HTML is rendered:
$dompdf->getDompdf()->setOption('isDebugMode', true);
Output will include warnings about unsupported CSS/HTML.
Logging: Enable Dompdf logging to track issues:
nucleos_dompdf:
options:
isDebugMode: true
Check Symfony logs for Dompdf-related errors.
Font Handling:
font-metrics option to specify custom fonts:
$dompdf->getDompdf()->setOption('fontDir', [__DIR__.'/fonts']);
$dompdf->getDompdf()->setOption('fontCache', __DIR__.'/cache/fontcache');
Custom Dompdf Configuration: Override default options via DI:
services:
Nucleos\DompdfBundle\Service\Dompdf:
arguments:
$options:
defaultFont: 'DejaVu Sans'
defaultFontSize: 10
Event Listeners: Extend the bundle by listening to Dompdf events (e.g., pre-render hooks):
$dompdf->getDompdf()->listen('pre_render', function ($dompdf) {
$dompdf->setPaper('A4', 'portrait');
});
Service Decorators:
Decorate the Dompdf service to add pre/post-processing:
class CustomDompdfDecorator implements DompdfInterface
{
public function __construct(private DompdfInterface $dompdf) {}
public function loadHtml(string $html): void
{
// Add custom logic (e.g., inject headers/footers)
$this->dompdf->loadHtml($html);
}
}
Register in services.yaml:
services:
Nucleos\DompdfBundle\Service\Dompdf:
decorates: Nucleos\DompdfBundle\Service\Dompdf
arguments:
$dompdf: '@Nucleos\DompdfBundle\Service\Dompdf.inner'
Command-Line Usage: Use the bundle in console commands for batch PDF generation:
use Nucleos\DompdfBundle\Service\Dompdf;
class GenerateBatchPdfCommand extends Command
{
public function __construct(private Dompdf $dompdf) {}
protected function execute(InputInterface $input, OutputInterface $output): int
{
$data = $this->fetchData();
foreach ($data as $item) {
$this->dompdf->loadHtml($this->renderView('batch_template.twig', ['item' => $item]));
file_put_contents("pdf_{$item->id}.pdf", $this->dompdf->getContent());
}
return Command::SUCCESS;
}
}
Testing:
Mock the Dompdf service in tests to avoid rendering:
$this->mockBuilder()
->disableOriginalConstructor()
->getMock()
->method('getContent')
->willReturn(file_get_contents(__DIR__.'/fixtures/test.pdf'));
How can I help you explore Laravel packages today?