# How to Convert HTML to PDF with PHP - Best Libraries & API (2026)

> Dompdf, TCPDF, mPDF, and Snappy - compared with working code, so you pick the right one the first time.

- **Author**: Pedro Campos
- **Published**: 2024-01-27
- **Updated**: 2026-04-07
- **Category**: Tutorials
- **Tags**: how-to, php, api
- **Read time**: 15 min read
- **URL**: https://templated.io/blog/how-to-convert-html-to-pdf-with-php/

---

## TL;DR

**What this guide covers:** Choosing the right PHP library to convert HTML to PDF - with working code for each one and a look at when an API makes more sense than a self-hosted library.

**Key points:**

- Dompdf is the easiest to set up - pure PHP, no binaries, good enough for most invoices and reports
- TCPDF is low-level but handles barcodes, digital signatures, and form fields that other libraries can't
- mPDF has the best CSS rendering of any pure-PHP option - slower, but worth it for styled or multilingual documents
- Snappy uses a real browser engine (WebKit) for near-perfect output, but needs wkhtmltopdf installed on your server
- For production-scale generation, a PDF Generator API removes the infrastructure headache entirely

**Best for:** PHP developers who need to generate invoices, certificates, or reports - and want to pick the right tool without trial and error.

## Introduction

Generating PDFs from PHP sounds simple until you're debugging why your table borders disappeared, why your custom font isn't loading, or why your server ran out of memory generating 50 documents at once.

The libraries are free. The setup time isn't - and neither is the maintenance once you're in production. For teams generating invoices, certificates, or reports at scale, that's usually what drives them toward a [PDF Generator API](https://templated.io/pdf-generator-api/) instead.

But if you're evaluating your options, here's the honest breakdown. Four PHP libraries worth knowing, what they're actually good at, where they fall short, and code you can use today.

## Why Convert HTML to PDF?

Here are compelling reasons why HTML to PDF conversion is valuable:

- **Universal Format:** PDFs maintain consistent formatting across different devices and operating systems
- **Professional Documents:** Generate invoices, reports, certificates, and contracts with professional appearance
- **Archival Purpose:** Create permanent records that won't change over time
- **Print-Ready Output:** Ensure documents print exactly as intended
- **Security Features:** PDFs can be password-protected and have restricted permissions
- **Offline Access:** Users can access documents without internet connectivity
- **Legal Compliance:** Many industries require documents in PDF format for compliance
- **CSS Styling:** Leverage existing CSS knowledge for document design

## HTML to PDF using PHP Libraries

Let's explore the most popular and effective PHP libraries for converting HTML to PDF, each with their unique strengths and use cases.

### 1. Dompdf: The Popular Choice

Dompdf is one of the most popular PHP libraries for HTML to PDF conversion. It's pure PHP, requires no external dependencies, and supports CSS styles, making it an excellent choice for most projects.

#### Step 1: Install Dompdf

Use Composer to install Dompdf in your project:

```bash
composer require dompdf/dompdf
```

#### Step 2: Basic HTML to PDF Conversion

```php
<?php
require 'vendor/autoload.php';
use Dompdf\Dompdf;
use Dompdf\Options;

// Configure options
$options = new Options();
$options->set('defaultFont', 'Arial');
$options->set('isRemoteEnabled', true);

// Initialize Dompdf
$dompdf = new Dompdf($options);

// HTML content
$html = '
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        body { font-family: Arial, sans-serif; }
        .header { background-color: #f0f0f0; padding: 20px; }
        .content { margin: 20px; }
    </style>
</head>
<body>
    <div class="header">
        <h1>Invoice #12345</h1>
    </div>
    <div class="content">
        <p>Date: ' . date('Y-m-d') . '</p>
        <p>Customer: John Doe</p>
        <p>Amount: $150.00</p>
    </div>
</body>
</html>';

$dompdf->loadHtml($html);
$dompdf->setPaper('A4', 'portrait');
$dompdf->render();

// Output PDF
$dompdf->stream("invoice.pdf", array("Attachment" => 0));
?>
```

#### Step 3: Advanced Dompdf Usage

```php
<?php
require 'vendor/autoload.php';
use Dompdf\Dompdf;
use Dompdf\Options;

function generatePdfReport($data) {
    $options = new Options();
    $options->set('defaultFont', 'Arial');
    $options->set('isRemoteEnabled', true);
    $options->set('isHtml5ParserEnabled', true);
    
    $dompdf = new Dompdf($options);
    
    $html = '
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <style>
            @page { margin: 1cm; }
            body { font-family: Arial, sans-serif; font-size: 12px; }
            .header { text-align: center; border-bottom: 2px solid #333; padding-bottom: 10px; }
            .table { width: 100%; border-collapse: collapse; margin-top: 20px; }
            .table th, .table td { border: 1px solid #ddd; padding: 8px; text-align: left; }
            .table th { background-color: #f2f2f2; }
            .footer { position: fixed; bottom: 0; width: 100%; text-align: center; font-size: 10px; }
        </style>
    </head>
    <body>
        <div class="header">
            <h1>Sales Report</h1>
            <p>Generated on ' . date('Y-m-d H:i:s') . '</p>
        </div>
        
        <table class="table">
            <thead>
                <tr>
                    <th>Product</th>
                    <th>Quantity</th>
                    <th>Price</th>
                    <th>Total</th>
                </tr>
            </thead>
            <tbody>';
    
    foreach ($data as $item) {
        $html .= '
                <tr>
                    <td>' . htmlspecialchars($item['product']) . '</td>
                    <td>' . htmlspecialchars($item['quantity']) . '</td>
                    <td>$' . number_format($item['price'], 2) . '</td>
                    <td>$' . number_format($item['quantity'] * $item['price'], 2) . '</td>
                </tr>';
    }
    
    $html .= '
            </tbody>
        </table>
        
        <div class="footer">
            <p>Page 1 of 1</p>
        </div>
    </body>
    </html>';
    
    $dompdf->loadHtml($html);
    $dompdf->setPaper('A4', 'portrait');
    $dompdf->render();
    
    return $dompdf->output();
}

// Example usage
$salesData = [
    ['product' => 'Laptop', 'quantity' => 2, 'price' => 999.99],
    ['product' => 'Mouse', 'quantity' => 5, 'price' => 25.50],
    ['product' => 'Keyboard', 'quantity' => 3, 'price' => 75.00]
];

$pdf = generatePdfReport($salesData);
file_put_contents('sales_report.pdf', $pdf);
?>
```

### 2. TCPDF: Advanced PDF Generation

TCPDF is a powerful PHP library that supports a wide range of PDF features, including barcodes, digital signatures, and advanced formatting options.

#### Step 1: Install TCPDF

```bash
composer require tecnickcom/tcpdf
```

#### Step 2: Basic TCPDF Usage

```php
<?php
require_once('vendor/autoload.php');

class CustomTCPDF extends TCPDF {
    public function Header() {
        $this->SetFont('helvetica', 'B', 15);
        $this->Cell(0, 15, 'My Company Report', 0, false, 'C', 0, '', 0, false, 'M', 'M');
        $this->Ln();
    }
    
    public function Footer() {
        $this->SetY(-15);
        $this->SetFont('helvetica', 'I', 8);
        $this->Cell(0, 10, 'Page ' . $this->getAliasNumPage() . '/' . $this->getAliasNbPages(), 0, false, 'C');
    }
}

$pdf = new CustomTCPDF();
$pdf->SetCreator('My Application');
$pdf->SetAuthor('John Doe');
$pdf->SetTitle('HTML to PDF Example');

$pdf->AddPage();
$pdf->SetFont('helvetica', '', 12);

$html = '
<h2>Welcome to TCPDF</h2>
<p>This is a sample HTML content converted to PDF using TCPDF.</p>
<table border="1" cellpadding="5">
    <tr style="background-color: #cccccc;">
        <th>Name</th>
        <th>Email</th>
        <th>Role</th>
    </tr>
    <tr>
        <td>John Doe</td>
        <td>john@example.com</td>
        <td>Developer</td>
    </tr>
    <tr>
        <td>Jane Smith</td>
        <td>jane@example.com</td>
        <td>Designer</td>
    </tr>
</table>';

$pdf->writeHTML($html, true, false, true, false, '');
$pdf->Output('tcpdf_example.pdf', 'I');
?>
```

### 3. mPDF: Feature-Rich Solution

mPDF is a PHP library that writes PDF files from UTF-8 encoded HTML. It supports most CSS properties and offers excellent Unicode support.

#### Step 1: Install mPDF

```bash
composer require mpdf/mpdf
```

#### Step 2: Generate PDF with mPDF

```php
<?php
require_once 'vendor/autoload.php';

use Mpdf\Mpdf;

$mpdf = new Mpdf([
    'mode' => 'utf-8',
    'format' => 'A4',
    'orientation' => 'P',
    'margin_left' => 15,
    'margin_right' => 15,
    'margin_top' => 20,
    'margin_bottom' => 20,
]);

$html = '
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        body { font-family: "DejaVu Sans", sans-serif; }
        .header { background: linear-gradient(45deg, #3498db, #2980b9); color: white; padding: 20px; text-align: center; }
        .content { padding: 20px; }
        .highlight { background-color: #f39c12; color: white; padding: 5px; }
        .table { width: 100%; border-collapse: collapse; }
        .table th, .table td { border: 1px solid #ddd; padding: 12px; }
        .table th { background-color: #34495e; color: white; }
    </style>
</head>
<body>
    <div class="header">
        <h1>Professional Invoice</h1>
        <p>Invoice #INV-2024-001</p>
    </div>
    
    <div class="content">
        <p>Date: <span class="highlight">' . date('F j, Y') . '</span></p>
        
        <table class="table">
            <thead>
                <tr>
                    <th>Description</th>
                    <th>Quantity</th>
                    <th>Rate</th>
                    <th>Amount</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>Web Development Services</td>
                    <td>40 hrs</td>
                    <td>$75.00</td>
                    <td>$3,000.00</td>
                </tr>
                <tr>
                    <td>Design Consultation</td>
                    <td>10 hrs</td>
                    <td>$85.00</td>
                    <td>$850.00</td>
                </tr>
            </tbody>
        </table>
        
        <p style="text-align: right; font-size: 18px; font-weight: bold;">
            Total: $3,850.00
        </p>
    </div>
</body>
</html>';

$mpdf->WriteHTML($html);
$mpdf->Output('mpdf_invoice.pdf', 'I');
?>
```

### 4. Snappy (wkhtmltopdf wrapper)

Snappy is a PHP wrapper for the wkhtmltopdf binary, which uses WebKit to render HTML into PDF with excellent CSS and JavaScript support.

#### Step 1: Install Snappy and wkhtmltopdf

First, install wkhtmltopdf on your system:

```bash
# Ubuntu/Debian
sudo apt-get install wkhtmltopdf

# macOS
brew install wkhtmltopdf

# Or download from: https://wkhtmltopdf.org/downloads.html
```

Then install Snappy:

```bash
composer require knplabs/knp-snappy
```

#### Step 2: Generate PDF with Snappy

```php
<?php
require_once 'vendor/autoload.php';

use Knp\Snappy\Pdf;

// Initialize Snappy
$snappy = new Pdf('/usr/local/bin/wkhtmltopdf'); // Adjust path as needed

// Configure options
$snappy->setOptions([
    'page-size' => 'A4',
    'orientation' => 'Portrait',
    'margin-top' => '10mm',
    'margin-right' => '10mm',
    'margin-bottom' => '10mm',
    'margin-left' => '10mm',
    'encoding' => 'UTF-8',
    'enable-local-file-access' => true,
]);

$html = '
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Snappy PDF Example</title>
    <style>
        body { font-family: Arial, sans-serif; }
        .container { max-width: 800px; margin: 0 auto; }
        .header { background: #2c3e50; color: white; padding: 20px; text-align: center; }
        .content { padding: 30px; }
        .footer { background: #ecf0f1; padding: 15px; text-align: center; font-size: 12px; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>Contract Agreement</h1>
            <p>Document generated with Snappy</p>
        </div>
        
        <div class="content">
            <h2>Terms and Conditions</h2>
            <p>This agreement is entered into on ' . date('F j, Y') . ' between the parties.</p>
            
            <h3>Scope of Work</h3>
            <ul>
                <li>Web application development</li>
                <li>Database design and implementation</li>
                <li>User interface design</li>
                <li>Testing and deployment</li>
            </ul>
            
            <h3>Payment Terms</h3>
            <p>Payment is due within 30 days of invoice date.</p>
        </div>
        
        <div class="footer">
            <p>Generated on ' . date('Y-m-d H:i:s') . ' | Page 1</p>
        </div>
    </div>
</body>
</html>';

// Generate PDF from HTML string
$pdf = $snappy->getOutputFromHtml($html);
file_put_contents('snappy_contract.pdf', $pdf);

// Or generate from URL
// $snappy->generate('https://example.com', 'webpage.pdf');

echo "PDF generated successfully!";
?>
```

### 5. PhantomPHP (PhantomJS wrapper)

PhantomPHP is a PHP wrapper for PhantomJS, which provides excellent JavaScript support for dynamic content rendering.

#### Step 1: Install PhantomJS and PhantomPHP

First, install PhantomJS:

```bash
# Using npm
npm install -g phantomjs-prebuilt

# Or download from: http://phantomjs.org/download.html
```

Then install PhantomPHP:

```bash
composer require jonnyw/php-phantomjs
```

#### Step 2: Generate PDF with PhantomPHP

```php
<?php
require_once 'vendor/autoload.php';

use JonnyW\PhantomJs\Client;

$client = Client::getInstance();
$client->setPhantomJs('/usr/local/bin/phantomjs'); // Adjust path as needed

$request = $client->getMessageFactory()->createPdfRequest();
$request->setUrl('file://' . __DIR__ . '/template.html');
$request->setOutputFile('phantomjs_output.pdf');
$request->setFormat('A4');
$request->setOrientation('portrait');
$request->setMargin('1cm');

// Create HTML template
$htmlTemplate = '
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <style>
        body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
        .invoice-header { background: #3498db; color: white; padding: 20px; text-align: center; }
        .invoice-body { padding: 20px; }
        .table { width: 100%; border-collapse: collapse; margin: 20px 0; }
        .table th, .table td { border: 1px solid #ddd; padding: 12px; text-align: left; }
        .table th { background-color: #f2f2f2; }
        .total { text-align: right; font-size: 18px; font-weight: bold; margin-top: 20px; }
    </style>
    <script>
        // JavaScript will be executed by PhantomJS
        document.addEventListener("DOMContentLoaded", function() {
            console.log("PDF generation with JavaScript support");
        });
    </script>
</head>
<body>
    <div class="invoice-header">
        <h1>Dynamic Invoice</h1>
        <p>Generated with PhantomJS</p>
    </div>
    
    <div class="invoice-body">
        <p><strong>Invoice Date:</strong> <span id="current-date"></span></p>
        
        <table class="table">
            <thead>
                <tr>
                    <th>Item</th>
                    <th>Description</th>
                    <th>Price</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>Service A</td>
                    <td>Web Development</td>
                    <td>$500.00</td>
                </tr>
                <tr>
                    <td>Service B</td>
                    <td>SEO Optimization</td>
                    <td>$200.00</td>
                </tr>
            </tbody>
        </table>
        
        <div class="total">
            Total: $700.00
        </div>
    </div>
    
    <script>
        document.getElementById("current-date").textContent = new Date().toLocaleDateString();
    </script>
</body>
</html>';

file_put_contents('template.html', $htmlTemplate);

$response = $client->getMessageFactory()->createResponse();
$client->send($request, $response);

if($response->getStatus() === 200) {
    echo "PDF generated successfully with PhantomJS!";
} else {
    echo "Error generating PDF: " . $response->getContent();
}

// Clean up
unlink('template.html');
?>
```

## Comprehensive Comparison

Here's a detailed comparison of all the PHP libraries to help you choose the best option for your needs:

| Library | Pros | Cons | Best For | Performance | Memory Usage | CSS Support | JavaScript Support | Unicode Support | Installation Complexity | Price | Active Development |
| - | - | - | - | - | - | - | - | - | - | - | - |
| **Dompdf** | Pure PHP, easy setup, good CSS support, no external dependencies | Limited JavaScript support, memory usage with large documents | Simple to medium complexity documents, shared hosting | Good | Medium | Good | No | Yes | Easy | Free | Active |
| **TCPDF** | Extensive PDF features, barcodes, digital signatures, pure PHP | Complex API, limited HTML/CSS support, steep learning curve | Complex PDFs with advanced features, forms, barcodes | Excellent | Low | Basic | No | Excellent | Easy | Free | Active |
| **mPDF** | Excellent CSS support, UTF-8, good HTML rendering, pure PHP | Memory intensive, slower than others, limited JavaScript | Professional documents with complex styling, multilingual content | Good | High | Excellent | Limited | Excellent | Easy | Free | Active |
| **Snappy** | Excellent CSS/JS support via WebKit, fast rendering, good quality output | Requires external binary installation, server dependencies | Complex layouts, JavaScript-heavy content, high-quality output | Excellent | Medium | Excellent | Excellent | Yes | Moderate | Free | Active |
| **PhantomPHP** | Full JavaScript support, dynamic content rendering, excellent compatibility | Requires PhantomJS installation, deprecated PhantomJS | Dynamic content, SPAs, JavaScript-dependent rendering | Good | Medium | Excellent | Excellent | Yes | Moderate | Free | Deprecated |

## Performance Optimization Tips

### 1. Memory Management

```php
<?php
// For large documents, process in chunks
function generateLargePDF($data) {
    $dompdf = new Dompdf();
    $dompdf->set_option('isPhpEnabled', true);
    
    // Process data in chunks to manage memory
    $chunks = array_chunk($data, 100);
    $html = '';
    
    foreach ($chunks as $chunk) {
        $html .= processChunk($chunk);
        
        // Clear memory periodically
        if (memory_get_usage() > 50 * 1024 * 1024) { // 50MB
            gc_collect_cycles();
        }
    }
    
    $dompdf->loadHtml($html);
    $dompdf->render();
    return $dompdf->output();
}
?>
```

### 2. Caching Strategy

```php
<?php
function getCachedPDF($cacheKey, $generateCallback) {
    $cacheFile = "cache/{$cacheKey}.pdf";
    
    // Check if cached version exists and is recent
    if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < 3600) {
        return file_get_contents($cacheFile);
    }
    
    // Generate new PDF
    $pdf = $generateCallback();
    
    // Cache the result
    file_put_contents($cacheFile, $pdf);
    
    return $pdf;
}

// Usage
$pdf = getCachedPDF('invoice_123', function() {
    return generateInvoicePDF($invoiceData);
});
?>
```

### 3. Batch Processing

```php
<?php
function batchGeneratePDFs($documents) {
    $results = [];
    
    foreach ($documents as $doc) {
        try {
            $pdf = generateSinglePDF($doc);
            $results[] = [
                'id' => $doc['id'],
                'status' => 'success',
                'file' => $pdf
            ];
        } catch (Exception $e) {
            $results[] = [
                'id' => $doc['id'],
                'status' => 'error',
                'message' => $e->getMessage()
            ];
        }
        
        // Memory cleanup
        if (count($results) % 10 === 0) {
            gc_collect_cycles();
        }
    }
    
    return $results;
}
?>
```

## Why Choose a Managed Template-Based Solution?

PHP libraries get the job done - but they come with a cost that doesn't show up in the Composer install.

Every library you add is infrastructure you now own. You're responsible for managing dependencies, handling memory spikes, keeping binaries updated, and debugging rendering issues that only appear in production. That's before you factor in template versioning, cross-platform compatibility, and the security patches that quietly pile up over time.

The operational overhead compounds fast. Teams building document automation - whether that's invoices, compliance reports, certificates, or educational tools like an [AI Flashcard Maker](https://www.remnote.com/blog/best-flashcard-maker) that generates print-ready study cards from structured data - quickly find that the real cost isn't the library. It's the engineering hours spent keeping everything running.

The key challenges most teams underestimate:

- **Infrastructure Management** - Installing dependencies, managing server resources, handling scaling
- **Development Overhead** - Template versioning, error handling, performance optimization, memory management
- **Production Operations** - Security updates, monitoring, backup systems, cost optimization
- **Maintenance Burden** - Cross-platform compatibility, dependency updates, system patches

At a certain scale, maintaining all of this stops making sense. That's the point most teams start looking for a managed solution.

## A Better Approach: Using Templated

For production applications requiring reliable, scalable PDF generation, Templated offers a managed solution that eliminates these operational challenges.

### Key Benefits of Templated

**Visual Template Designer** - Drag-and-drop interface with real-time preview and professional design tools. No coding required for templates.

**Reliable Infrastructure** - 99.9% uptime guarantee with global CDN delivery, automatic scaling, and built-in redundancy.

**Developer-Friendly API** - Simple [REST API](https://templated.io/integrations/api/) with comprehensive documentation, multiple output formats, and [webhook](https://templated.io/integrations/webhooks) notifications.

### Using Templated with PHP

#### Step 1: Set Up Templated API

After creating your account at [app.templated.io](https://app.templated.io), obtain your API key and template ID.

![How to create a template from the dashboard](https://templated-assets.s3.us-east-1.amazonaws.com/site/blog/create-template-example.png)

#### Step 2: Generate PDF with Templated

```php
<?php
function generateTemplatedPDF($templateId, $data, $apiKey) {
    $url = 'https://api.templated.io/v1/render';
    
    $payload = [
        'template' => $templateId,
        'format' => 'pdf',
        'layers' => $data
    ];
    
    $options = [
        'http' => [
            'header' => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $apiKey
            ],
            'method' => 'POST',
            'content' => json_encode($payload)
        ]
    ];
    
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    
    if ($result === FALSE) {
        throw new Exception('Failed to generate PDF');
    }
    
    return $result;
}

// Example usage
try {
    $certificateData = [
        'student_name' => ['text' => 'John Doe'],
        'course_name' => ['text' => 'Advanced PHP Development'],
        'completion_date' => ['text' => date('F j, Y')],
        'instructor_signature' => ['text' => 'Dr. Jane Smith'],
        'certificate_id' => ['text' => 'CERT-' . uniqid()]
    ];
    
    $pdf = generateTemplatedPDF('your-template-id', $certificateData, 'your-api-key');
    
    // Save or output the PDF
    header('Content-Type: application/pdf');
    header('Content-Disposition: attachment; filename="certificate.pdf"');
    echo $pdf;
    
} catch (Exception $e) {
    echo 'Error: ' . $e->getMessage();
}
?>
```

#### Step 3: Advanced Usage with Error Handling

```php
<?php
class TemplatedPDFGenerator {
    private $apiKey;
    private $baseUrl = 'https://api.templated.io/v1';
    
    public function __construct($apiKey) {
        $this->apiKey = $apiKey;
    }
    
    public function generatePDF($templateId, $data, $options = []) {
        $url = $this->baseUrl . '/render';
        
        $payload = [
            'template' => $templateId,
            'format' => 'pdf',
            'layers' => $data
        ];
        
        // Add optional parameters
        if (isset($options['webhook_url'])) {
            $payload['webhook_url'] = $options['webhook_url'];
        }
        
        if (isset($options['output_format'])) {
            $payload['format'] = $options['output_format'];
        }
        
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode($payload),
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                'Authorization: Bearer ' . $this->apiKey
            ],
            CURLOPT_TIMEOUT => 30
        ]);
        
        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        
        if ($httpCode !== 200) {
            throw new Exception("API request failed with status code: $httpCode");
        }
        
        return $response;
    }
    
    public function batchGenerate($requests) {
        $results = [];
        
        foreach ($requests as $request) {
            try {
                $pdf = $this->generatePDF(
                    $request['template_id'],
                    $request['data'],
                    $request['options'] ?? []
                );
                
                $results[] = [
                    'id' => $request['id'],
                    'status' => 'success',
                    'pdf' => $pdf
                ];
            } catch (Exception $e) {
                $results[] = [
                    'id' => $request['id'],
                    'status' => 'error',
                    'message' => $e->getMessage()
                ];
            }
        }
        
        return $results;
    }
}

// Usage example
$generator = new TemplatedPDFGenerator('your-api-key');

$batchRequests = [
    [
        'id' => 'invoice_001',
        'template_id' => 'invoice-template-id',
        'data' => ['customer_name' => ['text' => 'John Doe'], 'amount' => ['text' => '$150.00']],
        'options' => ['webhook_url' => 'https://yourapp.com/webhook']
    ],
    [
        'id' => 'invoice_002',
        'template_id' => 'invoice-template-id',
        'data' => ['customer_name' => ['text' => 'Jane Smith'], 'amount' => ['text' => '$275.00']]
    ]
];

$results = $generator->batchGenerate($batchRequests);

foreach ($results as $result) {
    if ($result['status'] === 'success') {
        file_put_contents($result['id'] . '.pdf', $result['pdf']);
        echo "Generated: {$result['id']}.pdf\n";
    } else {
        echo "Error generating {$result['id']}: {$result['message']}\n";
    }
}
?>
```

### Watch our Edithor in Action

[Watch the video on YouTube](https://www.youtube.com/watch?v=WXH5XcbSLuA)

## Other Languages

If you want to learn how to convert HTML to PDF in other languages, here are other resources for you to explore:

- [How To Convert HTML to PDF with Java](https://templated.io/blog/how-to-convert-html-to-pdf-with-java/)
- [How To Convert HTML to PDF with C#](https://templated.io/blog/how-to-convert-html-to-pdf-with-c-sharp/)
- [How To Convert HTML to PDF with Python](https://templated.io/blog/how-to-convert-html-to-pdf-with-python/)
- [How To Convert HTML to PDF with Node.js](https://templated.io/blog/how-to-convert-html-to-pdf-with-nodejs/)

## Conclusion

PHP offers numerous libraries for HTML to PDF conversion, each with distinct advantages. While Dompdf and TCPDF are excellent for simple use cases, and mPDF provides superior CSS support, solutions like Snappy offer high-quality output through WebKit rendering.

However, for production applications requiring reliability, scalability, and [professional templates](https://templated.io/templates), Templated provides a managed solution that eliminates the complexities of library management, server configuration, and template maintenance.

Whether you choose a self-hosted library or a managed service like Templated depends on your specific requirements, technical expertise, and scaling needs. For most modern applications, the managed approach offers significant advantages in terms of reliability, maintenance, and developer productivity.

Ready to streamline your PDF generation? [Sign up](https://app.templated.io/signup) for Templated and start creating professional documents with our [visual editor](https://templated.io/embed-image-editor-in-your-app/) and robust API today!
