Generating PDF documents dynamically from HTML templates is a common requirement for businesses needing to create invoices, reports, contracts, and other standardized documents. This article take ComPDF generation SDK as an example to show how to automate this process using a template-based approach that separates document structure from data.
How HTML Template-Based PDF Generation Works
The process follows a straightforward workflow that combines three key components:
- HTML Template - Defines the visual structure and layout of your document
- JSON Data - Provides the dynamic content to fill the template
- PDF Generator - Renders the combined result into a PDF document
The system first merges your HTML template with JSON data to create a complete HTML document, then converts that HTML to a polished PDF file.
Building Effective HTML Templates
Your HTML template serves as the blueprint for all generated documents. What makes this approach powerful is the ability to embed dynamic elements directly in your HTML using simple template syntax.
Key Template Features
Variables - Insert dynamic content using double curly braces:
<td>{{billNo}}</td>
<td>{{customerName}}</td>
Conditional Logic - Show or hide content based on data:
<img src="{% if premiumUser %}images/premium-logo.png{% else %}images/standard-logo.png{% endif %}">
Loops - Generate repeating elements like table rows:
{% for item in items %}
<tr>
<td>{{item.product}}</td>
<td>${{item.price}}</td>
</tr>
{% endfor %}
Calculations - Perform arithmetic directly in templates:
<td>Total: ${{round(total * (1 + taxRate * 0.01), 2)}}</td>
Variable Definition - Create and manipulate variables:
{% set subtotal = 0 %}
{% set subtotal = subtotal + item.price %}
HTML Template Example
<!doctype html>
<html>
<body style="margin: 0; padding: 0;">
<table cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse; margin: 0 auto">
<tr>
<td style="padding-top: 40px;">
<img
src="{% if compdfkit %}images/logo.png{% else if compdfkit2 %}images/logo2.png{% else %}images/logo3.png{% endif %}"
alt="PDF Technologies"
width="203"
height="50">
</td>
<td style="padding-top: 40px; text-align: right;">
<img src="images/invoice.png" alt="invoice" width="132">
<td style="border: 1px solid #8A8EA8; padding: 2px 10px;">{{billNo}}</td>
</td>
</tr>
</table>
<table cellpadding="0" cellspacing="0" width="100%" style="border-collapse: collapse;">
<!-- {% set totalprice = 0 %} -->
<!-- {% for item in items %} -->
<tr style="height:64px;color:#333;">
<td style="width:70px;height:70px;border-bottom: 2px solid #F3F3F3; padding-left: 10px; text-align: left;">
{{ item.index }}
</td>
<td style="width: 160px;border-bottom: 2px solid #F3F3F3; font-size: 13px; line-height: 15px; color: #121E3F;text-align:left;">
<div>
<p style="font-size: 13px; line-height: 15px; font-weight: bold; color: #121E3F; margin: 0;">
{{ item.product }}
</p>
<p style="font-size: 11px; line-height: 12px; padding-top: 4px; color: #5F6881; margin: 0;">
{{ item.startDateAndEndDate }}
</p>
</div>
</td>
<td style="width: 130px;border-bottom: 2px solid #F3F3F3; font-size: 13px; line-height: 15px; color: #121E3F;text-align:left;">
{{ item.paymentCycle }}
</td>
<td style="width: 100px;border-bottom: 2px solid #F3F3F3; font-size: 13px; line-height: 15px; color: #121E3F;text-align:left;">
{{ item.gearLevel }}
</td>
<td style="width: 100px;text-align:left;border-bottom: 2px solid #F3F3F3; font-size: 13px; line-height: 15px; color: #121E3F;">
$ {{ item.price }}
</td>
</tr>
<!-- {% set totalprice = totalprice + item.price %} -->
<!-- {% endfor %} -->
<tr>
<td style="width:70px;"></td>
<td style="width:160px;"></td>
<td colspan="2" style="width: 100px; text-align:right; font-weight: bold; font-size: 16px; line-height: 18px; color: #121E3F; padding-right: 72px;">Total:</td>
<td style="width: 100px; text-align:left; font-weight: bold; font-size: 16px; line-height: 18px; color: #121E3F;">$ {{round(totalprice * (1 + tax * 0.01), 2)}}</td>
</tr>
</table>
</body>
</html>
Preparing JSON Data
Your JSON data provides the dynamic content that populates the template. It should mirror the structure expected by your template:
{
"address": "456 Oak Avenue",
"billNo": "2345678901",
"company": "TechCorp Ltd.",
"country": "Canada",
"email": "alice.smith@techcorp.com",
"firstName": "Alice",
"gearLevel": "Pro",
"compdfkit": false,
"compdfkit2": true,
"invoiceDate": "2025-01-15",
"lastName": "Smith",
"paymentCycle": "Yearly",
"price": "1200",
"province": "Ontario",
"startDateAndEndDate": "2025-01-15 to 2025-02-15",
"tax": 8,
"zip": "K1A 0A6",
"items": [
{
"index": 1,
"product": "ComPDFKit Pro",
"startDateAndEndDate": "2025-01-15 to 2025-02-15",
"paymentCycle": "Yearly",
"gearLevel": "Pro",
"price": 800
},
{
"index": 2,
"product": "ComPDFKit API",
"startDateAndEndDate": "2025-01-15 to 2025-02-15",
"paymentCycle": "Monthly",
"gearLevel": "Basic",
"price": 400
}
]
}
Fill the Template to Generate the PDF
//HTML template file path
String templatePath = "/template_1.html";
//json file path
String jsonPath = "/data1.json";
//Output HTML path
String outHtmlPath = "/outHtml.html";
//Output PDF path
String outPdfPath = "/outPdf.pdf";
//Combine the JSON file with the HTML template to generate HTML content
CHtmlConverter.CErrorCode id = CHtmlConverter.HtmlRenderTemplate(templatePath, jsonPath, outHtmlPath);
//Convert HTML to PDF
id = CHtmlConverter.ConvertToPdf(outHtmlPath, outPdfPath);
Conclusion
HTML template-based PDF generation offers a flexible, maintainable approach to creating dynamic documents. By separating design (HTML templates) from content (JSON data), you can easily update document styles without code changes and generate professional PDFs programmatically. This method is particularly valuable for businesses that need to produce large volumes of standardized documents like invoices, reports, or contracts with consistent branding and variable content.
Top comments (0)