Generate a simple PDF from HTML
Wed, Jul 22, 2020
2-min
Generate a simple PDF invoice from HTML using puppeteer & handlebars.
Introduce
Puppeteer is Node.js library giving you access to a headless Chrome browser. This makes it a breeze to generate PDF files with Node.js
Handlebars provides the power necessary to let you build semantic templates effectively with no frustration
How to use
- Run
npm install
to install package in package.json - Run
node pdf.js
to generate invoice.pdf
Generate invoice
- Prepare content html (invoice.html)
- Using handlebars to binding data to content html
- Using Puppeteer to generate pdf from final html
const fs = require("fs");
const path = require("path");
const puppeteer = require('puppeteer');
const handlebars = require("handlebars");
(async () => {
var dataBinding = {
items: [{
name: "item 1",
price: 100
},
{
name: "item 2",
price: 200
},
{
name: "item 3",
price: 300
}
],
total: 600,
isWatermark: false
}
var templateHtml = fs.readFileSync(path.join(process.cwd(), 'invoice.html'), 'utf8');
var template = handlebars.compile(templateHtml);
var finalHtml = template(dataBinding);
var options = {
format: 'A4',
headerTemplate: "<p></p>",
footerTemplate: "<p></p>",
displayHeaderFooter: false,
margin: {
top: "40px",
bottom: "100px"
},
printBackground: true,
path: 'invoice.pdf'
}
const browser = await puppeteer.launch({
args: ['--no-sandbox'],
headless: true
});
const page = await browser.newPage();
await page.goto(`data: text/html,${finalHtml}`, {
waitUntil: 'networkidle0'
});
await page.pdf(options);
await browser.close();
})();
How to display paid stamp watermark on the invoice?
Using handlebars to check param isWatermark
{{#if isWatermark}}
<div style="border-width: 6px;border-style: solid; border-color: #008000;border-radius: 8px; color: #008000; opacity:0.6; position: absolute; z-index: 1; left:40%; top:30%; font-size: 60pt;-webkit-transform: rotate(-45deg);-ms-transform: rotate(-45deg);transform: rotate(-45deg); font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;">
PAID </div>
{{/if}}
Change isWatermark: true
and run node pdf.js
again
You can find the source code at Github