Installation:
composer require bideogemu/mpdf-bundle
Ensure BideoGemu\MpdfBundle\BideoGemuMpdfBundle::class is enabled in config/bundles.php.
First Use Case: Generate a PDF in a Laravel controller:
use BideoGemu\MpdfBundle\Factory\MpdfFactory;
public function generatePdf(MpdfFactory $mpdfFactory) {
$mpdf = $mpdfFactory->createMpdfObject([
'mode' => 'utf-8',
'format' => 'A4',
]);
$mpdf->WriteHTML($this->renderView('pdf.template.twig', ['data' => $data]));
return $mpdfFactory->createDownloadResponse($mpdf, 'document.pdf');
}
Key Files to Review:
config/packages/bideogemu_mpdf.yaml (default config).vendor/bideogemu/mpdf-bundle/src/Factory/MpdfFactory.php (factory logic).resources/views/pdf/template.twig).Factory-Based Instantiation:
Always use MpdfFactory to create MPDF instances. Avoid direct instantiation of \Mpdf\Mpdf:
// Good
$mpdf = $mpdfFactory->createMpdfObject($customOptions);
// Avoid
$mpdf = new \Mpdf\Mpdf($options);
Configuration Management:
config/packages/bideogemu_mpdf.yaml:
bideogemu_mpdf:
default_options:
mode: utf-8
format: A4
margin_header: 5
margin_footer: 5
$mpdf = $mpdfFactory->createMpdfObject([
'orientation' => 'L', // Overrides default
]);
Twig Integration:
$html = $this->renderView('pdf.template.twig', ['data' => $data]);
$mpdf->WriteHTML($html);
$mpdf->SetHTMLHeader($this->renderView('pdf.header.twig'));
Response Handling:
return $mpdfFactory->createDownloadResponse($mpdf, 'filename.pdf');
return $mpdfFactory->createStreamResponse($mpdf, 'filename.pdf');
Queueing for Large PDFs: Use Laravel queues to avoid timeouts:
GeneratePdfJob::dispatch($data)->onQueue('pdfs');
Job example:
public function handle() {
$mpdf = $this->mpdfFactory->createMpdfObject([]);
$mpdf->WriteHTML($this->renderView('pdf.template.twig', ['data' => $this->data]));
Storage::put('pdfs/temp.pdf', $mpdf->Output('', 'S'));
}
Dynamic PDF Generation:
public function generateInvoice($invoiceId) {
$invoice = Invoice::findOrFail($invoiceId);
$mpdf = $this->mpdfFactory->createMpdfObject(['format' => 'A4']);
$mpdf->WriteHTML($this->renderView('invoices/pdf.twig', ['invoice' => $invoice]));
return $this->mpdfFactory->createDownloadResponse($mpdf, "invoice_{$invoiceId}.pdf");
}
Reusable PDF Components:
{# resources/views/pdf/base.twig #}
<!DOCTYPE html>
<html>
<head>
{% block head %}{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
{# resources/views/pdf/report.twig #}
{% extends 'pdf/base.twig' %}
{% block content %}
{{ include('pdf/report_content.twig') }}
{% endblock %}
Testing:
MpdfFactory in tests:
$mockMpdf = Mockery::mock(\Mpdf::class);
$mockMpdf->shouldReceive('WriteHTML')->once();
$mockMpdf->shouldReceive('Output')->once()->andReturn('PDF_CONTENT');
$factory = $this->app->make(MpdfFactory::class);
$factory->shouldReceive('createMpdfObject')->andReturn($mockMpdf);
Laravel Service Provider: Bind the factory explicitly if autowiring fails:
public function register() {
$this->app->bind(MpdfFactory::class, function ($app) {
return new MpdfFactory(
$app['config']['mpdf.default_options'],
storage_path('app/mpdf_cache')
);
});
}
Custom MPDF Extensions: Extend the factory to support custom MPDF classes:
class CustomMpdfFactory extends MpdfFactory {
protected function createMpdfInstance(array $options) {
return new CustomMpdf($options);
}
}
Register in config/services.php:
'mpdf_factory' => \App\Services\CustomMpdfFactory::class,
Environment-Specific Configs: Override defaults per environment:
# config/packages/bideogemu_mpdf.yaml
when@dev:
default_options:
format: Letter
Caching: Cache compiled Twig templates for PDFs:
$twig = $this->app->make(Twig::class);
$twig->getLoader()->setCache($this->app['path.cache'].'/twig');
Configuration Merging:
$options = array_merge($this->defaultOptions, $runtimeOptions);
$this->logger->debug('MPDF options merged:', ['options' => $options]);
Cache Directory Permissions:
cache_dir is unwritable.$cacheDir = storage_path('app/mpdf_cache');
if (!is_writable($cacheDir)) {
mkdir($cacheDir, 0755, true);
}
Twig Autoloader Conflicts:
$this->app->register(TwigServiceProvider::class);
Deprecated DI Arguments:
MpdfFactory.// Old (may fail in v2.7+)
new MpdfFactory($options);
// New
new MpdfFactory($defaultOptions, $cacheDir);
Memory Limits:
memory_limit.ini_set('memory_limit', '512M');
Enable MPDF Debugging:
Add to config/packages/bideogemu_mpdf.yaml:
debug: true
Logs errors to storage/logs/mpdf.log.
Check Output:
file_put_contents('debug.html', $htmlContent);
Symfony DI Errors:
ParameterNotFoundException for missing config.config/packages/bideogemu_mpdf.yaml exists and is loaded.Twig Errors:
{{ dump(data) }} in templates to debug variables.
How can I help you explore Laravel packages today?