Invoice PDF generation is the most common PDF use case in SaaS applications. Getting it right means professional formatting, correct page numbering, reliable email delivery, and consistent output across environments.
Designing the Invoice HTML Template
Keep the template in plain HTML with inline or embedded CSS. Avoid external stylesheets; they require network requests during rendering. Use a table for line items and flexbox for header/footer layout.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: 'Helvetica Neue', sans-serif; font-size: 13px; color: #111; padding: 40px; }
.header { display: flex; justify-content: space-between; margin-bottom: 48px; }
.logo { font-size: 24px; font-weight: 700; color: #1e40af; }
table { width: 100%; border-collapse: collapse; margin-top: 32px; }
th, td { padding: 10px 12px; text-align: left; border-bottom: 1px solid #e5e7eb; }
th { background: #f8fafc; font-weight: 600; font-size: 11px; text-transform: uppercase; }
.total { text-align: right; margin-top: 24px; font-size: 16px; font-weight: 700; }
</style>
</head>
<body>
<div class="header">
<div class="logo">Acme Inc.</div>
<div style="text-align:right;color:#555">
Invoice #{{invoice.number}}<br>
Date: {{invoice.date}}<br>Due: {{invoice.due_date}}
</div>
</div>
<p>Bill to: <strong>{{customer.name}}</strong><br>{{customer.address}}</p>
<table>
<thead><tr><th>Description</th><th>Qty</th><th>Unit Price</th><th>Total</th></tr></thead>
<tbody>
{{#each items}}
<tr><td>{{description}}</td><td>{{quantity}}</td><td>{{unit_price}}</td><td>{{total}}</td></tr>
{{/each}}
</tbody>
</table>
<div class="total">Total: {{invoice.total}}</div>
</body>
</html>Page Numbering with Footer
{
"html": "...your invoice HTML...",
"paper_size": "a4",
"orientation": "portrait",
"margin_top": 40,
"margin_bottom": 40,
"footer_html": "<div style=\"text-align:center;font-size:9px;color:#888;padding:8px 0\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
}Multi-Language Quick Reference
# PHP SDK
$pdf = (new HtmlToPdf(['api_key' => $key]))->html($html)->paperSize('a4')->generate()->content();
# Node.js
const pdf = await fetch(API_URL, { method:'POST', headers, body: JSON.stringify({html, paper_size:'a4'}) })
# Python
pdf = requests.post(API_URL, headers=headers, json={'html': html, 'paper_size': 'a4'}).content
# Ruby
res = Net::HTTP.post(URI(API_URL), {html:, paper_size: 'a4'}.to_json, headers)Sending by Email
Generate the bytes first, then pass them to your email library as an attachment. In Laravel, use attachData; in Nodemailer, set content on the attachment entry; in Python, use MIMEApplication.
The free tier includes 200 pages/day, enough for invoice generation at early-stage SaaS scale. The invoice PDF use case page has a complete Laravel SDK example with page numbering and multi-language support.