Installation:
composer require 94noni/html2pdf-bundle
Enable the bundle in config/bundles.php:
Noni\Html2pdfBundle\NoniHtml2pdfBundle::class => ['all' => true],
First Use Case:
Inject Html2pdfFactory into a service/controller and generate a PDF:
use Noni\Html2pdfBundle\Factory\Html2pdfFactory;
class InvoiceController extends AbstractController
{
public function __construct(private Html2pdfFactory $factory) {}
public function generatePdf(): Response
{
$html = $this->renderView('invoice/pdf.html.twig');
$pdf = $this->factory->create()->fromHtml($html)->output();
return new BinaryFileResponse($pdf, 200, ['Content-Type' => 'application/pdf']);
}
}
Key Files:
config/packages/noni_html2pdf.yaml (for customization)invoice/pdf.html.twig) for HTML content.HTML Generation:
Use Twig templates (*.html.twig) to structure PDF content. Example:
{# invoice/pdf.html.twig #}
<html>
<body>
<h1>Invoice #{{ invoice.number }}</h1>
<table>
{% for item in invoice.items %}
<tr><td>{{ item.description }}</td><td>{{ item.price }}</td></tr>
{% endfor %}
</table>
</body>
</html>
PDF Creation:
// Controller/Service
$html = $this->renderView('invoice/pdf.html.twig', ['invoice' => $invoice]);
$pdf = $this->factory
->create('P', 'A4', 'en', true, 'UTF-8', [10, 15, 10, 15])
->fromHtml($html)
->output();
Response Handling:
return new BinaryFileResponse(
$pdf,
200,
['Content-Disposition' => 'attachment; filename="invoice.pdf"']
);
PdfGenerator service to encapsulate logic:
class PdfGenerator
{
public function __construct(private Html2pdfFactory $factory) {}
public function generate(string $template, array $data, array $options = []): string
{
$html = $this->renderView($template, $data);
$pdf = $this->factory->create(...$options)->fromHtml($html);
return $pdf->output();
}
}
config/packages/noni_html2pdf.yaml to set defaults:
noni_html2pdf:
orientation: 'L' # Default landscape
margin: [20, 20, 20, 20]
Abandoned Package:
spipu/html2pdf.CSS Limitations:
html2pdf's CSS support docs.Memory Issues:
Dependency Conflicts:
spipu/html2pdf (v6+) is installed as a dev dependency if extending:
composer require spipu/html2pdf --dev
file_put_contents('debug.html', $html);
Html2pdf options with:
$pdf = $this->factory->create('P', 'A4'); // Explicit defaults
try {
$pdf = $this->factory->create()->fromHtml($html);
} catch (\Exception $e) {
$this->addFlash('error', 'PDF generation failed: ' . $e->getMessage());
return $this->redirectToRoute('home');
}
Custom Factories:
Extend Html2pdfFactory to add project-specific defaults:
class CustomHtml2pdfFactory extends Html2pdfFactory
{
protected function getDefaultOptions(): array
{
return array_merge(parent::getDefaultOptions(), [
'defaultHeader' => $this->renderView('pdf/header.html.twig'),
'defaultFooter' => $this->renderView('pdf/footer.html.twig'),
]);
}
}
Register as a service in config/services.yaml:
services:
App\Service\CustomHtml2pdfFactory: '@noni_html2pdf.factory.custom'
Event Listeners:
Hook into Symfony events (e.g., kernel.response) to auto-generate PDFs:
// src/EventListener/PdfListener.php
class PdfListener
{
public function onKernelResponse(FilterResponseEvent $event): void
{
if ($event->getRequest()->attributes->get('pdf')) {
$response = new BinaryFileResponse($this->generatePdf());
$event->setResponse($response);
}
}
}
Twig Extensions: Add a Twig function for inline PDF generation:
// src/Twig/AppExtension.php
class AppExtension extends AbstractExtension
{
public function getFunctions(): array
{
return [
new TwigFunction('generate_pdf', [$this->factory, 'create']),
];
}
}
Usage in Twig:
{{ generate_pdf('P', 'A4')->fromHtml(content).output() }}
How can I help you explore Laravel packages today?