Generate report PDFs with charts using the “htmlTemplate” option.
htmlTemplate
option for swift document generation.
The htmlTemplate
uses Handlebars
to render your HTML together with the provided templateData
.
See Templating for more info.
curl --request POST 'https://api.doczilla.app/v1/pdf' \
--header 'Authorization: Bearer <your token>' \
--header 'Content-Type: application/json' \
--output 'doczilla.pdf' \
--data '{
"pdf": {
"format": "a4"
},
"page": {
"htmlTemplate": "PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9IlVURi04Ij4KICAgIDxtZXRhIG5hbWU9InZpZXdwb3J0IiBjb250ZW50PSJ3aWR0aD1kZXZpY2Utd2lkdGgsIGluaXRpYWwtc2NhbGU9MS4wIj4KICAgIDx0aXRsZT5Nb250aGx5IFNhbGVzIFJlcG9ydDwvdGl0bGU+CiAgICA8c2NyaXB0IHNyYz0iaHR0cHM6Ly9jZG4udGFpbHdpbmRjc3MuY29tIj48L3NjcmlwdD4KICAgIDxzY3JpcHQgc3JjPSJodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL2VjaGFydHNANS40LjIvZGlzdC9lY2hhcnRzLm1pbi5qcyI+PC9zY3JpcHQ+CiAgPC9oZWFkPgogIDxib2R5IGNsYXNzPSJiZy13aGl0ZSI+CiAgICA8ZGl2IGNsYXNzPSJtYXgtdy0zeGwgbXgtYXV0byI+CiAgICAgIDxhcnRpY2xlIGNsYXNzPSJvdmVyZmxvdy1oaWRkZW4iPgogICAgICAgIDxkaXYgY2xhc3M9ImJnLXdoaXRlIHJvdW5kZWQtYi1tZCI+CiAgICAgICAgICA8ZGl2IGNsYXNzPSJwLTkiPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJzcGFjZS15LTYgdGV4dC1zbGF0ZS03MDAiPgogICAgICAgICAgICAgIDxpbWcgY2xhc3M9Im9iamVjdC1jb3ZlciBoLTEyIiBzcmM9Imh0dHBzOi8vYXNzZXRzLmRvY3ppbGxhLmFwcC9leGFtcGxlcy9pbnZvaWNlLWV4YW1wbGUtbG9nby5wbmciCiAgICAgICAgICAgICAgICAgICBhbHQ9IkNvbXBhbnkgTG9nbyI+CiAgICAgICAgICAgICAgPHAgY2xhc3M9InRleHQteGwgZm9udC1leHRyYWJvbGQgdHJhY2tpbmctdGlnaHQgZm9udC1ib2R5Ij4KICAgICAgICAgICAgICAgIE1vbnRobHkgU2FsZXMgUmVwb3J0OiA8c3Bhbj57eyBudW1iZXIgfX08L3NwYW4+CiAgICAgICAgICAgICAgPC9wPgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgIDwvZGl2PgoKICAgICAgICAgIDxkaXYgY2xhc3M9InB4LTkiPgogICAgICAgICAgICA8ZGl2IGNsYXNzPSJmbGV4IGZsZXgtY29sIG14LTAgbXQtOCI+CiAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPSJtaW4tdy1mdWxsIGRpdmlkZS15IGRpdmlkZS1zbGF0ZS01MDAiPgogICAgICAgICAgICAgICAgPHRoZWFkPgogICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPSJjb2wiCiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPSJweS0zLjUgcGwtNCBwci0zIHRleHQtbGVmdCB0ZXh0LXNtIGZvbnQtbm9ybWFsIHRleHQtc2xhdGUtNzAwIHNtOnBsLTYgbWQ6cGwtMCI+CiAgICAgICAgICAgICAgICAgICAgICBNb250aAogICAgICAgICAgICAgICAgICAgIDwvdGg+CiAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPSJjb2wiCiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPSJoaWRkZW4gcHktMy41IHB4LTMgdGV4dC1yaWdodCB0ZXh0LXNtIGZvbnQtbm9ybWFsIHRleHQtc2xhdGUtNzAwIHNtOnRhYmxlLWNlbGwiPgogICAgICAgICAgICAgICAgICAgICAgU2FsZXMgKCQpCiAgICAgICAgICAgICAgICAgICAgPC90aD4KICAgICAgICAgICAgICAgICAgICA8dGggc2NvcGU9ImNvbCIKICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9InB5LTMuNSBwbC0zIHByLTQgdGV4dC1yaWdodCB0ZXh0LXNtIGZvbnQtbm9ybWFsIHRleHQtc2xhdGUtNzAwIHNtOnByLTYgbWQ6cHItMCI+CiAgICAgICAgICAgICAgICAgICAgICBHcm93dGggKCUpCiAgICAgICAgICAgICAgICAgICAgPC90aD4KICAgICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgIDwvdGhlYWQ+CiAgICAgICAgICAgICAgICA8dGJvZHk+CiAgICAgICAgICAgICAgICAgICAge3sjZWFjaCBzYWxlc319CiAgICAgICAgICAgICAgICAgICAgICAgIDx0ciBjbGFzcz0iYm9yZGVyLWIgYm9yZGVyLXNsYXRlLTIwMCI+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9InB5LTQgcGwtNCBwci0zIHRleHQtc20gc206cGwtNiBtZDpwbC0wIj4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPSJmb250LW1lZGl1bSB0ZXh0LXNsYXRlLTcwMCI+e3tsYWJlbH19PC9kaXY+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9ImhpZGRlbiBweC0zIHB5LTQgdGV4dC1zbSB0ZXh0LXJpZ2h0IHRleHQtc2xhdGUtNTAwIHNtOnRhYmxlLWNlbGwiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgJHt7c2FsZXN9fQogICAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD4KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9InB5LTQgcGwtMyBwci00IHRleHQtc20gdGV4dC1yaWdodCB0ZXh0LXNsYXRlLTUwMCBzbTpwci02IG1kOnByLTAiPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7I2lmIGdyb3d0aH19CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7Z3Jvd3RofX0lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3tlbHNlfX0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7L2lmfX0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+CiAgICAgICAgICAgICAgICAgICAgICAgIDwvdHI+CiAgICAgICAgICAgICAgICAgICAge3svZWFjaH19CiAgICAgICAgICAgICAgICA8L3Rib2R5PgogICAgICAgICAgICAgICAgPHRmb290PgogICAgICAgICAgICAgICAgICA8dHI+CiAgICAgICAgICAgICAgICAgICAgPHRoIHNjb3BlPSJyb3ciIGNvbHNwYW49IjIiCiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPSJoaWRkZW4gcHQtNiBwbC02IHByLTMgdGV4dC1zbSBmb250LW5vcm1hbCB0ZXh0LXJpZ2h0IHRleHQtc2xhdGUtNzAwIHNtOnRhYmxlLWNlbGwgbWQ6cGwtMCI+CiAgICAgICAgICAgICAgICAgICAgICBUb3RhbCBTYWxlcwogICAgICAgICAgICAgICAgICAgIDwvdGg+CiAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPSJwdC02IHBsLTMgcHItNCB0ZXh0LXNtIGZvbnQtbm9ybWFsIHRleHQtcmlnaHQgdGV4dC1zbGF0ZS03MDAgc206cHItNiBtZDpwci0wIj4KICAgICAgICAgICAgICAgICAgICAgICR7eyB0b3RhbFNhbGVzIH19CiAgICAgICAgICAgICAgICAgICAgPC90ZD4KICAgICAgICAgICAgICAgICAgPC90cj4KICAgICAgICAgICAgICAgIDwvdGZvb3Q+CiAgICAgICAgICAgICAgPC90YWJsZT4KICAgICAgICAgICAgPC9kaXY+CiAgICAgICAgICA8L2Rpdj4KCiAgICAgICAgICA8ZGl2IGNsYXNzPSJwLTkiPgogICAgICAgICAgICA8aDIgY2xhc3M9InRleHQtMnhsIGZvbnQtZXh0cmFib2xkIHRleHQtc2xhdGUtNzAwIj5TYWxlcyBHcm93dGggQ2hhcnQ8L2gyPgogICAgICAgICAgICA8ZGl2IGlkPSJzYWxlc0NoYXJ0IiBzdHlsZT0id2lkdGg6IDEwMCU7IGhlaWdodDogMzAwcHgiPjwvZGl2PgogICAgICAgICAgPC9kaXY+CgogICAgICAgICAgPGRpdiBjbGFzcz0icHgtOSI+CiAgICAgICAgICAgIDxkaXYgY2xhc3M9ImJvcmRlci10IGJvcmRlci1zbGF0ZS0yMDAiPgogICAgICAgICAgICAgIDxkaXYgY2xhc3M9InRleHQtc20gcHQtNCBmb250LWxpZ2h0IHRleHQtc2xhdGUtNzAwIj4KICAgICAgICAgICAgICAgIDxwPgogICAgICAgICAgICAgICAgICBUaGlzIHNhbGVzIHJlcG9ydCBwcm92aWRlcyBhbiBvdmVydmlldyBvZiBvdXIgbW9udGhseSBwZXJmb3JtYW5jZSBmcm9tIAogICAgICAgICAgICAgICAgICB7eyNlYWNoIHNhbGVzfX0KICAgICAgICAgICAgICAgICAgICB7eyNpZiBAZmlyc3R9fQogICAgICAgICAgICAgICAgICAgICAgICB7e2xhYmVsfX0KICAgICAgICAgICAgICAgICAgICB7ey9pZn19CiAgICAgICAgICAgICAgICAgICAge3sjaWYgQGxhc3R9fQogICAgICAgICAgICAgICAgICAgICAgICB0byB7e2xhYmVsfX0uCiAgICAgICAgICAgICAgICAgICAge3svaWZ9fQogICAgICAgICAgICAgICAgICB7ey9lYWNofX0KICAgICAgICAgICAgICAgICAgVGhlIGNvbnNpc3RlbnQgZ3Jvd3RoIGluIHNhbGVzIGRlbW9uc3RyYXRlcyB0aGUgZWZmZWN0aXZlbmVzcyBvZiBvdXIgc3RyYXRlZ2llcyBhbmQgdGhlCiAgICAgICAgICAgICAgICAgIGRlZGljYXRpb24gb2Ygb3VyIHRlYW0uIFdlIGxvb2sgZm9yd2FyZCB0byBtYWludGFpbmluZyB0aGlzIHBvc2l0aXZlIHRyZW5kIGluIHRoZSBjb21pbmcgbW9udGhzLgogICAgICAgICAgICAgICAgPC9wPgogICAgICAgICAgICAgIDwvZGl2PgogICAgICAgICAgICA8L2Rpdj4KICAgICAgICAgIDwvZGl2PgogICAgICAgIDwvZGl2PgogICAgICA8L2FydGljbGU+CiAgICA8L2Rpdj4KCiAgICA8c2NyaXB0PgogICAgICB2YXIgbXlDaGFydCA9IGVjaGFydHMuaW5pdChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2FsZXNDaGFydCcpLCBudWxsLCB7IHJlbmRlcmVyOiAnc3ZnJyB9KQogICAgCiAgICAgIG15Q2hhcnQuc2V0T3B0aW9uKHsKICAgICAgICBhbmltYXRpb246IGZhbHNlLAogICAgICAgIHRvb2x0aXA6IHsKICAgICAgICAgIHRyaWdnZXI6ICdheGlzJywKICAgICAgICAgIGZvcm1hdHRlcjogZnVuY3Rpb24ocGFyYW1zKSB7CiAgICAgICAgICAgIHJldHVybiBwYXJhbXNbMF0ubmFtZSArICc8YnIvPicgKwogICAgICAgICAgICAgICAgICAgcGFyYW1zWzBdLnNlcmllc05hbWUgKyAnOiAkJyArIHBhcmFtc1swXS52YWx1ZS50b0xvY2FsZVN0cmluZygpCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICB4QXhpczoge3t7anNvbiBjaGFydERhdGEueEF4aXN9fX0sCiAgICAgICAgeUF4aXM6IHsKICAgICAgICAgIHR5cGU6ICd2YWx1ZScsCiAgICAgICAgICBheGlzTGFiZWw6IHsKICAgICAgICAgICAgZm9ybWF0dGVyOiAnJHt2YWx1ZX0nCiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICBzZXJpZXM6IHt7e2pzb24gY2hhcnREYXRhLnNlcmllc319fQogICAgICB9KQogICAgPC9zY3JpcHQ+CiAgPC9ib2R5Pgo8L2h0bWw+",
"templateData": {
"sales": [
{ "label": "January", "sales": "10.000", "growth": null },
{ "label": "February", "sales": "12.500", "growth": 25 },
{ "label": "March", "sales": "15.000", "growth": 20 },
{ "label": "April", "sales": "18.000", "growth": 20 },
{ "label": "May", "sales": "22.000", "growth": 22 }
],
"number": "SR-2024-05",
"chartData": {
"xAxis": {
"data": ["January", "February", "March", "April", "May"],
"type": "category"
},
"series": [
{
"data": [10000, 12500, 15000, 18000, 22000],
"name": "Sales",
"type": "bar",
"itemStyle": { "color": "#3498db" }
}
]
},
"totalSales": "77.500"
},
}
}'
HTML report template using Tailwind CSS
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Monthly Sales Report</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.2/dist/echarts.min.js"></script>
</head>
<body class="bg-white">
<div class="max-w-3xl mx-auto">
<article class="overflow-hidden">
<div class="bg-white rounded-b-md">
<div class="p-9">
<div class="space-y-6 text-slate-700">
<img class="object-cover h-12" src="https://assets.doczilla.app/examples/invoice-example-logo.png"
alt="Company Logo">
<p class="text-xl font-extrabold tracking-tight font-body">
Monthly Sales Report: <span>{{ number }}</span>
</p>
</div>
</div>
<div class="px-9">
<div class="flex flex-col mx-0 mt-8">
<table class="min-w-full divide-y divide-slate-500">
<thead>
<tr>
<th scope="col"
class="py-3.5 pl-4 pr-3 text-left text-sm font-normal text-slate-700 sm:pl-6 md:pl-0">
Month
</th>
<th scope="col"
class="hidden py-3.5 px-3 text-right text-sm font-normal text-slate-700 sm:table-cell">
Sales ($)
</th>
<th scope="col"
class="py-3.5 pl-3 pr-4 text-right text-sm font-normal text-slate-700 sm:pr-6 md:pr-0">
Growth (%)
</th>
</tr>
</thead>
<tbody>
{{#each sales}}
<tr class="border-b border-slate-200">
<td class="py-4 pl-4 pr-3 text-sm sm:pl-6 md:pl-0">
<div class="font-medium text-slate-700">{{label}}</div>
</td>
<td class="hidden px-3 py-4 text-sm text-right text-slate-500 sm:table-cell">
${{sales}}
</td>
<td class="py-4 pl-3 pr-4 text-sm text-right text-slate-500 sm:pr-6 md:pr-0">
{{#if growth}}
{{growth}}%
{{else}}
-
{{/if}}
</td>
</tr>
{{/each}}
</tbody>
<tfoot>
<tr>
<th scope="row" colspan="2"
class="hidden pt-6 pl-6 pr-3 text-sm font-normal text-right text-slate-700 sm:table-cell md:pl-0">
Total Sales
</th>
<td class="pt-6 pl-3 pr-4 text-sm font-normal text-right text-slate-700 sm:pr-6 md:pr-0">
${{ totalSales }}
</td>
</tr>
</tfoot>
</table>
</div>
</div>
<div class="p-9">
<h2 class="text-2xl font-extrabold text-slate-700">Sales Growth Chart</h2>
<div id="salesChart" style="width: 100%; height: 300px"></div>
</div>
<div class="px-9">
<div class="border-t border-slate-200">
<div class="text-sm pt-4 font-light text-slate-700">
<p>
This sales report provides an overview of our monthly performance from
{{#each sales}}
{{#if @first}}
{{label}}
{{/if}}
{{#if @last}}
to {{label}}.
{{/if}}
{{/each}}
The consistent growth in sales demonstrates the effectiveness of our strategies and the
dedication of our team. We look forward to maintaining this positive trend in the coming months.
</p>
</div>
</div>
</div>
</div>
</article>
</div>
<script>
var myChart = echarts.init(document.getElementById('salesChart'), null, { renderer: 'svg' })
myChart.setOption({
animation: false,
tooltip: {
trigger: 'axis',
formatter: function(params) {
return params[0].name + '<br/>' +
params[0].seriesName + ': $' + params[0].value.toLocaleString()
}
},
xAxis: {{{json chartData.xAxis}}},
yAxis: {
type: 'value',
axisLabel: {
formatter: '${value}'
}
},
series: {{{json chartData.series}}}
})
</script>
</body>
</html>
Was this page helpful?