A framework-agnostic PHP library for generating PDFs from Twig templates, with support for a swappable driver interface.
This library provides a PDF generation pipeline for PHP applications, converting Twig templates to PDF documents through an extensible driver interface. Dompdf and Browsershot drivers are included, with support for custom drivers via a simple contract.
- PHP: Version 8.3 or higher is required.
- Composer: Dependency management tool for PHP.
- Twig: Version ^3.27 is required.
composer require andrewdyer/pdf-generatorCreate an HTML template in the application's templates directory:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<style>
body {
font-family: Arial, sans-serif;
font-size: 14px;
color: #333;
padding: 40px;
}
h1 {
font-size: 28px;
color: #1a1a2e;
}
</style>
</head>
<body>
<h1>Invoice #{{ order.id }}</h1>
<p>{{ order.customer.name }}</p>
</body>
</html>Extend PdfDocument and implement options() to configure the output and content() to define the template and data:
use AndrewDyer\PdfGenerator\PdfDocument;
use AndrewDyer\PdfGenerator\Values\Content;
use AndrewDyer\PdfGenerator\Values\Options;
class InvoicePdf extends PdfDocument
{
public function __construct(private readonly Order $order) {}
public function options(): Options
{
return new Options(
filename: sprintf('invoice-%s.pdf', $this->order->id),
);
}
public function content(): Content
{
return new Content(
view: 'pdfs/invoice.html.twig',
data: ['order' => $this->order],
);
}
}Instantiate PdfGenerator with a Twig\Environment and a driver:
use AndrewDyer\PdfGenerator\PdfGenerator;
use AndrewDyer\PdfGenerator\Drivers\DompdfDriver;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
$twig = new Environment(new FilesystemLoader('/path/to/templates'));
$generator = new PdfGenerator(
twig: $twig,
driver: new DompdfDriver(),
);Returns the full path of the written file:
$path = $generator->save(new InvoicePdf($order), '/storage/invoices');Streams the PDF directly in the browser for preview:
$generator->inline(new InvoicePdf($order));Sends the PDF as a browser download:
$generator->download(new InvoicePdf($order));Returns the raw PDF bytes for further processing, such as attaching to an email:
$bytes = $generator->generate(new InvoicePdf($order));A pure PHP driver requiring no external services or binaries.
composer require dompdf/dompdfInstantiate the driver directly, or pass a pre-configured Options instance:
use AndrewDyer\PdfGenerator\Drivers\DompdfDriver;
use Dompdf\Options;
$options = new Options();
$options->set('isRemoteEnabled', true);
$driver = new DompdfDriver($options);A driver backed by headless Chromium via Puppeteer, producing pixel-perfect output. Best suited for complex layouts, modern CSS, and web fonts.
Requires Node.js and Puppeteer:
npm install puppeteerThen install the driver via Composer:
composer require spatie/browsershotPass optional binary paths if they are not on the system path:
use AndrewDyer\PdfGenerator\Drivers\BrowsershotDriver;
$driver = new BrowsershotDriver(
nodeBinary: '/usr/local/bin/node',
npmBinary: '/usr/local/bin/npm',
chromiumPath: '/usr/bin/chromium',
);Any class implementing DriverInterface can be used as a driver, accepting rendered HTML and returning raw PDF bytes:
use AndrewDyer\PdfGenerator\Contracts\DriverInterface;
use AndrewDyer\PdfGenerator\Values\Options;
class CustomDriver implements DriverInterface
{
public function generate(string $html, Options $options): string
{
// Convert $html to PDF bytes and return them...
}
}A value object passed to the driver alongside the rendered HTML. All properties have sensible defaults:
use AndrewDyer\PdfGenerator\Values\Options;
use AndrewDyer\PdfGenerator\Enums\Orientation;
use AndrewDyer\PdfGenerator\Enums\PaperSize;
new Options(
filename: 'document.pdf',
paperSize: PaperSize::A4,
orientation: Orientation::Portrait,
);Licensed under the MIT licence and is free for private or commercial projects.
