Skip to main content
LibreDTE Core provides powerful PDF generation capabilities for electronic tax documents, creating printable versions with the electronic stamp (TED) and all required information.

Overview

The RendererWorker handles PDF generation using customizable templates. It supports:
  • Standard and custom templates
  • Multiple PDF engines (mPDF, TCPDF)
  • TED barcode/QR code rendering
  • Company logos and branding
  • Detailed item listings
  • Tax calculations and totals

Basic PDF Generation

Generate a PDF from a document:
$documentComponent = $app->getPackage('billing')
    ->getComponent('document');

// Create document
$bag = $documentComponent->bill($data, $caf, $certificate);

// Generate PDF
$rendererWorker = $documentComponent->getRendererWorker();
$pdfContent = $rendererWorker->render($bag);

// Save to file
file_put_contents('/path/to/invoice.pdf', $pdfContent);

// Or output to browser
header('Content-Type: application/pdf');
header('Content-Disposition: inline; filename="invoice.pdf"');
echo $pdfContent;

Renderer Configuration

The renderer uses a strategy pattern with configurable options:
// RendererWorker.php:58-64
protected array $optionsSchema = [
    '__allowUndefinedKeys' => true,
    'strategy' => [
        'types' => 'string',
        'default' => 'template.estandar',  // Default template
    ],
];

Available Options

strategy
string
default:"template.estandar"
The rendering strategy to use. Default is the standard LibreDTE template.
template
string
default:"estandar"
Template name within the strategy.
format
string
default:"pdf"
Output format (typically ‘pdf’).

PDF Rendering Process

The rendering process follows these steps:
1

Normalize Document Data

The document is fully normalized to ensure all required data is present.
// RendererWorker.php:88
$bag = $this->documentBagManager->normalize($bag, all: true);
2

Select Template Strategy

The appropriate rendering strategy is selected based on options.
// RendererWorker.php:84
$strategy = $this->getStrategy($options->get('strategy'));
3

Render to PDF

The strategy renders the document using the configured template.
// RendererWorker.php:91
$renderedData = $strategy->render($bag);
4

Return Binary Content

The PDF binary content is returned as a string.

Working with Templates

The standard template (template.estandar) provides a professional layout:
// Use standard template
$options = [
    'renderer' => [
        'strategy' => 'template.estandar',
        'template' => 'estandar',
        'format' => 'pdf',
    ],
];

$bag = $documentComponent->bill($data, $caf, $certificate, $options);
$pdf = $rendererWorker->render($bag);

Template Features

The standard template includes:

Header Section

  • Company logo
  • Company information (RUT, name, address)
  • Document type and number
  • Issue date

Recipient Details

  • Recipient RUT and name
  • Address and location
  • Business activity

Item Details

  • Product/service descriptions
  • Quantities and units
  • Unit prices
  • Line totals

Totals & TED

  • Subtotals and taxes
  • Discounts and surcharges
  • Final total
  • TED barcode (electronic stamp)

Adding Custom Data

Include additional data in PDFs using the LibreDTE data structure:
$bag = new DocumentBag(
    inputData: $documentData,
    libredteData: [
        'extra' => [
            'logo' => '/path/to/company-logo.png',
            'footer_text' => 'Thank you for your business!',
            'payment_instructions' => 'Bank transfer to account 123456',
            'terms' => 'Net 30 days',
        ],
    ],
    caf: $caf,
    certificate: $certificate,
    options: [
        'renderer' => [
            'template' => 'estandar',
        ],
    ]
);

$pdf = $rendererWorker->render($bag);

PDF Engines

LibreDTE Core supports multiple PDF generation engines:
mPDF is the default engine, providing excellent Unicode support and advanced features.
// composer.json:49
"mpdf/mpdf": "^8.2"
Features:
  • Full UTF-8 support
  • Custom fonts
  • Header/footer templates
  • Watermarks
  • Better performance for complex layouts

Generate PDF for Multiple Documents

Create PDFs for a batch of documents:
$documents = [$data1, $data2, $data3];
$pdfFiles = [];

foreach ($documents as $index => $data) {
    try {
        // Create document
        $bag = $documentComponent->bill($data, $caf, $certificate);
        
        // Generate PDF
        $pdf = $rendererWorker->render($bag);
        
        // Save with folio number in filename
        $folio = $bag->getFolio();
        $filename = "invoice_{$folio}.pdf";
        $filepath = "/path/to/pdfs/{$filename}";
        
        file_put_contents($filepath, $pdf);
        $pdfFiles[] = $filepath;
        
        echo "Generated: {$filename}\n";
        
    } catch (\Exception $e) {
        echo "Error generating PDF for document {$index}: {$e->getMessage()}\n";
    }
}

echo "Generated " . count($pdfFiles) . " PDFs\n";

Rendering HTML Preview

While the default format is PDF, you can potentially render to HTML for preview:
$options = [
    'renderer' => [
        'format' => 'html',  // If supported by strategy
    ],
];

$bag = $documentComponent->bill($data, $caf, $certificate, $options);

try {
    $htmlContent = $rendererWorker->render($bag);
    echo $htmlContent;
} catch (\Exception $e) {
    echo "HTML rendering not supported by this strategy";
}
HTML rendering support depends on the specific template strategy implementation. The standard template focuses on PDF output.

Complete Example: Invoice to PDF

Full workflow from data to PDF:
use libredte\lib\Core\Package\Billing\Component\Document\DocumentComponent;

// 1. Prepare invoice data
$invoiceData = [
    'Encabezado' => [
        'IdDoc' => [
            'TipoDTE' => 33,
            'Folio' => 150,
            'FchEmis' => date('Y-m-d'),
        ],
        'Emisor' => [
            'RUTEmisor' => '12345678-5',
            'RznSoc' => 'Mi Empresa S.A.',
            'GiroEmis' => 'Servicios de TI',
            'Acteco' => 620200,
            'DirOrigen' => 'Av. Apoquindo 3000',
            'CmnaOrigen' => 'Las Condes',
        ],
        'Receptor' => [
            'RUTRecep' => '87654321-9',
            'RznSocRecep' => 'Cliente SpA',
            'GiroRecep' => 'Comercio',
            'DirRecep' => 'Calle Principal 100',
            'CmnaRecep' => 'Santiago',
        ],
    ],
    'Detalle' => [
        [
            'NmbItem' => 'Consultoría desarrollo software',
            'QtyItem' => 40,
            'UnmdItem' => 'horas',
            'PrcItem' => 50000,
        ],
        [
            'NmbItem' => 'Hosting mensual',
            'QtyItem' => 1,
            'UnmdItem' => 'mes',
            'PrcItem' => 100000,
        ],
    ],
];

// 2. Additional PDF data
$libredteData = [
    'extra' => [
        'logo' => '/var/www/assets/logo.png',
        'payment_info' => [
            'bank' => 'Banco de Chile',
            'account' => '1234567890',
            'account_type' => 'Cuenta Corriente',
        ],
        'notes' => 'Pago neto 30 días',
    ],
];

// 3. Create document
$bag = new DocumentBag(
    inputData: $invoiceData,
    libredteData: $libredteData,
    caf: $caf,
    certificate: $certificate,
    options: [
        'renderer' => [
            'template' => 'estandar',
        ],
    ]
);

// 4. Build document
$documentComponent = $app->getPackage('billing')->getComponent('document');
$parserWorker = $documentComponent->getParserWorker();
$builderWorker = $documentComponent->getBuilderWorker();

$parserWorker->parse($bag);
$document = $builderWorker->build($bag);

// 5. Generate PDF
$rendererWorker = $documentComponent->getRendererWorker();

try {
    $pdfContent = $rendererWorker->render($bag);
    
    // 6. Save PDF
    $filename = "factura_{$bag->getFolio()}.pdf";
    file_put_contents("/var/invoices/{$filename}", $pdfContent);
    
    echo "PDF generated: {$filename}\n";
    echo "Size: " . strlen($pdfContent) . " bytes\n";
    
    // 7. Optional: Email PDF to customer
    // sendEmailWithAttachment($customer->email, $filename, $pdfContent);
    
} catch (\Exception $e) {
    echo "Error generating PDF: " . $e->getMessage();
}

Troubleshooting

Check that PDF engine dependencies are installed:
composer require mpdf/mpdf
composer require tecnickcom/tcpdf
Verify PHP extensions:
php -m | grep -E 'gd|mbstring'
Ensure the document has a valid electronic stamp:
if (!$bag->getTimbre()) {
    echo "Document missing TED stamp";
}

// Check TED content
$ted = $document->getTED();
if (empty($ted)) {
    echo "TED is empty - was CAF provided?";
}
Verify logo path is accessible and format is supported:
$logoPath = '/path/to/logo.png';

if (!file_exists($logoPath)) {
    echo "Logo file not found";
}

// Supported formats: PNG, JPG, GIF
$libredteData = [
    'extra' => [
        'logo' => $logoPath,
    ],
];
Increase PHP memory limit for complex PDFs:
ini_set('memory_limit', '256M');

// Or in php.ini:
// memory_limit = 256M

Performance Tips

Cache rendered PDFs: Store generated PDFs to avoid regenerating them for the same document.
$cacheKey = "pdf_invoice_{$bag->getFolio()}";

if ($cache->has($cacheKey)) {
    $pdf = $cache->get($cacheKey);
} else {
    $pdf = $rendererWorker->render($bag);
    $cache->set($cacheKey, $pdf, 3600); // Cache for 1 hour
}

Next Steps

Creating Documents

Learn how to create electronic documents

SII Integration

Send documents to SII after generating PDFs

Build docs developers (and LLMs) love