Generating PDF Invoices from HTML Templates (Free & Paid Methods)
Create professional PDF invoices from HTML templates using free tools, open-source libraries, and SaaS APIs — with real code examples.
AltoUnlockPDF Team
PDF Tools Expert
A well-formatted invoice in PDF is a cornerstone of any business. HTML is a natural template language for invoices — it gives you full layout control. In this guide, we’ll build a real PDF invoice from HTML, using both free and paid methods.
Why HTML for Invoices?
HTML + CSS gives you everything you need for invoice design:
- Tables for line items
- Flexbox/Grid for layouts
- Custom fonts and brand colors
- Conditional sections (taxes, discounts, notes)
- Easy template reuse with any templating engine
The result is a PDF that looks exactly like your HTML — no manual formatting required.
Free Method 1: Browser Print
The fastest way to create a one-off PDF invoice:
- Open your HTML invoice in Chrome
- Press Ctrl+P (Cmd+P on Mac)
- Set destination to Save as PDF
- Click Save
Best for: occasional invoices, personal use
Free Method 2: AltoUnlockPDF Online Tool
Upload your HTML invoice template and instantly get a PDF. No signup, no watermarks.
- Go to the HTML to PDF tool
- Upload or paste your HTML
- Click Convert → Download PDF
Code Method: Puppeteer (Node.js)
For automated invoice generation in a web app:
import puppeteer from 'puppeteer';
import Mustache from 'mustache';
import fs from 'fs';
const template = fs.readFileSync('invoice.html', 'utf8');
async function generateInvoicePdf(invoiceData) {
const html = Mustache.render(template, invoiceData);
const browser = await puppeteer.launch({ headless: 'new' });
const page = await browser.newPage();
await page.setContent(html, { waitUntil: 'networkidle0' });
const pdf = await page.pdf({ format: 'A4', printBackground: true });
await browser.close();
return pdf;
}
The Invoice HTML Template
Here’s a clean, ready-to-use invoice template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
body { font-family: 'Helvetica Neue', Arial, sans-serif; margin: 0; padding: 40px; color: #333; }
.invoice-header { display: flex; justify-content: space-between; align-items: flex-start; }
.company-logo { font-size: 26px; font-weight: 800; color: #dd7d24; }
.invoice-meta h1 { font-size: 36px; color: #eee; margin: 0; }
.invoice-meta p { margin: 4px 0; font-size: 13px; color: #666; }
.bill-section { display: flex; justify-content: space-between; margin: 40px 0; }
.bill-to h3, .bill-from h3 { font-size: 11px; text-transform: uppercase; color: #999; margin-bottom: 8px; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th { background: #f9f5ef; text-align: left; padding: 12px; font-size: 12px; text-transform: uppercase; color: #666; }
td { padding: 12px; border-bottom: 1px solid #f0ebe0; }
.totals { margin-top: 20px; text-align: right; }
.total-row { display: flex; justify-content: flex-end; gap: 60px; padding: 6px 0; }
.grand-total { font-size: 20px; font-weight: 700; color: #dd7d24; border-top: 2px solid #dd7d24; padding-top: 10px; margin-top: 10px; }
.footer { margin-top: 60px; font-size: 12px; color: #aaa; text-align: center; }
</style>
</head>
<body>
<div class="invoice-header">
<div class="company-logo">{{ companyName }}</div>
<div class="invoice-meta">
<h1>INVOICE</h1>
<p>Invoice #: {{ invoiceNumber }}</p>
<p>Date: {{ date }}</p>
<p>Due: {{ dueDate }}</p>
</div>
</div>
<div class="bill-section">
<div class="bill-from">
<h3>From</h3>
<strong>{{ companyName }}</strong><br>
{{ companyAddress }}<br>
{{ companyEmail }}
</div>
<div class="bill-to">
<h3>Bill To</h3>
<strong>{{ clientName }}</strong><br>
{{ clientAddress }}<br>
{{ clientEmail }}
</div>
</div>
<table>
<thead>
<tr><th>Description</th><th>Qty</th><th>Unit Price</th><th>Amount</th></tr>
</thead>
<tbody>
{{#items}}
<tr>
<td>{{ description }}</td>
<td>{{ qty }}</td>
<td>${{ price }}</td>
<td>${{ total }}</td>
</tr>
{{/items}}
</tbody>
</table>
<div class="totals">
<div class="total-row"><span>Subtotal</span><span>${{ subtotal }}</span></div>
<div class="total-row"><span>Tax ({{ taxRate }}%)</span><span>${{ tax }}</span></div>
<div class="total-row grand-total"><span>Total Due</span><span>${{ grandTotal }}</span></div>
</div>
<div class="footer">
Thank you for your business! Payment due within {{ paymentDays }} days.
</div>
</body>
</html>
Paid/SaaS Options for Volume
For businesses generating hundreds or thousands of invoices monthly:
- DocRaptor — HTML/CSS to PDF API, excellent print CSS support
- PDFShift — fast, reliable, good free tier
- HTML/2/PDF API — simple and affordable
These services handle infrastructure, scaling, and reliability — worth it at volume.
Best Practices for Invoice PDFs
- Embed fonts — don’t rely on system fonts being available
- Use absolute URLs for logos and images (or inline base64)
- Test on multiple converters — slight rendering differences exist
- Include all required legal information: company number, tax ID, payment terms
- Version your templates so old invoices can be re-generated identically
The IRS publication on invoice requirements is worth reviewing to ensure your invoices meet US legal standards.
Related Articles
HTML to PDF in Node.js with Puppeteer: Complete Tutorial
Step-by-step guide to generating high-quality PDFs from HTML in Node.js using Puppeteer, with real-world examples for invoices and reports.
Read Article
Best WordPress PDF Plugins for Web Agencies (2026 Guide)
A complete guide for WordPress agencies on the best PDF export plugins, when to use a hosted API instead, and how to pick the right solution for every client project.
Read Article
Convert HTML to PDF with JavaScript: Best Libraries Compared
A comprehensive comparison of the top JavaScript libraries for HTML-to-PDF conversion — jsPDF, Puppeteer, html2pdf.js, and more.
Read Article