Installation:
composer require knplabs/knp-snappy-bundle
Add to config/bundles.php (Symfony 4.4+ auto-discovers, but explicit inclusion ensures clarity):
Knp\Bundle\SnappyBundle\KnpSnappyBundle::class => ['all' => true],
Configuration:
Edit config/packages/knp_snappy.yaml to specify the binary path (default: wkhtmltopdf):
knp_snappy:
pdf:
enabled: true
binary: '/usr/local/bin/wkhtmltopdf' # Adjust path
options: []
timeout: 60000
image:
enabled: true
binary: '/usr/local/bin/wkhtmltoimage'
options: []
timeout: 60000
First Use Case: Generate a PDF from a Twig template in a controller:
use Knp\Snappy\Pdf;
public function generatePdf(Pdf $pdfGenerator)
{
$html = $this->renderView('pdf/template.html.twig', ['data' => $data]);
$pdf = $pdfGenerator->generateFromHtml($html);
return new Response($pdf, 200, ['Content-Type' => 'application/pdf']);
}
PDF Generation:
Pdf service with generateFromHtml().$pdf = $pdfGenerator->generateFromFile('path/to/template.html.twig');
options:
knp_snappy:
pdf:
options: ['--margin-top', '20mm', '--orientation', 'Landscape']
Image Generation:
use Knp\Snappy\Image;
$image = $imageGenerator->generateFromHtml($html, 'screenshot.png');
Streaming Large Files:
$response = new Response();
$pdfGenerator->generateFromHtml($html)->stream($response, 'invoice.pdf');
return $response;
Dynamic Templates:
embed for reusable components:
{% embed 'base_pdf_layout.html.twig' %}
{{ include('content/' ~ section ~ '.html.twig') }}
{% endembed %}
$formView = $this->renderView('form.html.twig', ['form' => $form->createView()]);
$this->messageBus->dispatch(new GeneratePdfJob($html, $userId));
$cachedHtml = $this->get('twig')->createTemplate($template)->render($context);
Binary Path Issues:
Command not found or Failed to execute binary.wkhtmltopdf/wkhtmltoimage is installed and path is correct. Use absolute paths in config./usr/local/bin/wkhtmltopdf --version
Memory Limits:
Allowed memory size exhausted for large PDFs.ini_set('memory_limit', '2G')) or stream output.Font/Encoding Issues:
options: ['--enable-local-file-access', '--custom-header', 'Accept-Encoding', 'gzip']
Twig Auto-escaping:
|raw filter:
{{ content|raw }}
Log WKHTMLTOPDF Output: Redirect stderr to a log file in config:
options: ['--quiet', '--debug-javascript']
Or use Symfony’s logger:
$pdfGenerator->getBinary()->setLogger($this->get('logger'));
Validate HTML: Use browser dev tools to test HTML rendering before PDF generation.
Custom Binary Wrapper:
Extend Knp\Snappy\Binary\Binary to add pre/post-processing:
class CustomBinary extends Binary
{
protected function getCommand(array $options)
{
$options[] = '--custom-flag';
return parent::getCommand($options);
}
}
Register as a service:
knp_snappy.pdf.binary: '@custom_binary'
Event Listeners: Hook into PDF generation lifecycle (e.g., modify content before conversion):
use Knp\Snappy\Event\GenerateEvent;
public function onGenerate(GenerateEvent $event)
{
$event->setHtml($this->modifyHtml($event->getHtml()));
}
Bind in services.yaml:
Knp\SnappyBundle\EventListener\GenerateListener:
tags:
- { name: kernel.event_listener, event: knp_snappy.generate, method: onGenerate }
Async Generation:
Use Symfony’s Process component to run WKHTMLTOPDF asynchronously:
$process = new Process(['/usr/local/bin/wkhtmltopdf', '--quiet', $input, $output]);
$process->start();
enabled: false for PDF/image generation if using only one feature.timeout for large documents (default: 60s):
timeout: 120000 # 2 minutes
%kernel.project_dir% or environment variables:
binary: '%env(WKHTMLTOPDF_BINARY)%'
How can I help you explore Laravel packages today?