Installation:
composer require chrisandchris/mpdf-port-bundle
Add the bundle to config/bundles.php (Symfony 4.4+):
return [
// ...
ChrisAndChris\MpdfPortBundle\TFoxMpdfPortBundle::class => ['all' => true],
];
First Use Case: Inject the service in a controller and generate a PDF:
use Symfony\Component\HttpFoundation\Response;
class PdfController extends AbstractController
{
public function generatePdf(): Response
{
$mpdf = $this->get('tfox.mpdfport');
$html = '<h1>Hello PDF!</h1><p>Generated via MPDF.</p>';
return $mpdf->generatePdfResponse($html);
}
}
Route it:
# config/routes.yaml
pdf_generate:
path: /generate-pdf
controller: App\Controller\PdfController::generatePdf
Dynamic PDF Generation:
Use generatePdfResponse() for inline PDFs (e.g., invoices, reports):
$response = $mpdf->generatePdfResponse($this->renderView('emails/invoice.html.twig', ['data' => $invoice]));
File Downloads: Force downloads with custom filenames:
$response = $mpdf->generatePdfResponse($html, 'filename.pdf');
$response->headers->set('Content-Disposition', 'attachment; filename="custom_name.pdf"');
Twig Integration: Pass Twig variables directly:
$html = $this->renderView('templates/report.twig', ['user' => $user]);
$response = $mpdf->generatePdfResponse($html);
Streaming Large PDFs:
For memory efficiency, use generatePdfStream():
$stream = $mpdf->generatePdfStream($html);
return new StreamedResponse(function () use ($stream) {
echo $stream;
});
Custom MPDF Configuration: Override defaults via dependency injection:
# config/services.yaml
services:
tfox.mpdfport:
arguments:
$options:
format: 'A4'
orientation: 'Landscape'
defaultFont: 'dejavusans'
Event Listeners: Hook into PDF generation lifecycle (e.g., logging, watermarking):
// src/EventListener/MpdfListener.php
public function onMpdfGenerate(GeneratePdfEvent $event)
{
$event->getMpdf()->SetWatermarkText('Draft');
}
Register in config/services.yaml:
services:
App\EventListener\MpdfListener:
tags:
- { name: 'kernel.event_listener', event: 'tfox.mpdfport.generate_pdf', method: 'onMpdfGenerate' }
Batch Processing: Generate multiple PDFs in a loop (e.g., for bulk exports):
foreach ($users as $user) {
$html = $this->renderView('user_profile.pdf.twig', ['user' => $user]);
$response = $mpdf->generatePdfResponse($html, "user_{$user->id}.pdf");
$this->saveResponseToStorage($response, $user->id);
}
Memory Limits:
memory_limit..env:
PHP_MEMORY_LIMIT=512M
Or use generatePdfStream() for chunked processing.Font Paths:
config/packages/tfox_mpdf_port.yaml:
tfox_mpdfport:
options:
fontDir: ['%kernel.project_dir%/public/fonts']
Caching:
$response->setSharedMaxAge(0);
$response->setPublic();
Symfony 5+ Deprecations:
get() service container access is deprecated.autowire: true in services.yaml:
services:
App\Controller\PdfController:
autowire: true
Inspect MPDF Object: Dump the MPDF instance to debug settings:
$mpdf = $this->get('tfox.mpdfport');
dump($mpdf->getMpdf()->getProperties());
HTML Validation:
<h1>Test</h1>).Log Errors: Enable MPDF error logging:
tfox_mpdfport:
options:
debug: true
Custom Templates:
Override the base template (resources/views/base_pdf.html.twig) for consistent headers/footers.
Post-Processing: Modify the PDF after generation using MPDF’s methods:
$response = $mpdf->generatePdfResponse($html);
$mpdfInstance = $response->getMpdf();
$mpdfInstance->SetCompression(true);
Headless Chrome Rendering: For dynamic content (e.g., JavaScript-rendered HTML), pre-render with Puppeteer and pass the static HTML to MPDF.
Queue Workers: Offload PDF generation to a queue (e.g., Symfony Messenger) for long-running tasks:
$this->messageBus->dispatch(new GeneratePdfMessage($html, $userId));
How can I help you explore Laravel packages today?