Node.js — Create a PDF from HTML with Puppeteer and Handlebars

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.

Puppeteer works with so-called “pages” and allows you to inject your own HTML onto a page. From there, generate a PDF file from this page and save it to a file.

Node.js Series Overview

  1. String Replace All Appearances
  2. Remove All Whitespace From a String in JavaScript
  3. Generate a Random ID or String in Node.js or JavaScript
  4. Remove Extra Spaces From a String in JavaScript or Node.js
  5. Remove Numbers From a String in JavaScript or Node.js
  6. Get the Part Before a Character in a String in JavaScript or Node.js
  7. Get the Part After a Character in a String in JavaScript or Node.js
  8. How to Check if a Value is a String in JavaScript or Node.js
  9. Check If a String Includes All Strings in JavaScript/Node.js/TypeScript
  10. Check if a Value is a String in JavaScript and Node.js
  11. Limit and Truncate a String to a Given Length in JavaScript and Node.js
  12. Split a String into a List of Characters in JavaScript and Node.js
  13. How to Generage a UUID in Node.js
  14. Reverse a String in JavaScript or Node.js
  15. Split a String into a List of Lines in JavaScript or Node.js
  16. Split a String into a List of Words in JavaScript or Node.js
  17. Detect if a String is in camelCase Format in Javascript or Node.js
  18. Check If a String Is in Lowercase in JavaScript or Node.js
  19. Check If a String is in Uppercase in JavaScript or Node.js
  20. Get the Part After First Occurrence in a String in JavaScript or Node.js
  21. Get the Part Before First Occurrence in a String in JavaScript or Node.js
  22. Get the Part Before Last Occurrence in a String in JavaScript or Node.js
  23. Get the Part After Last Occurrence in a String in JavaScript or Node.js
  24. How to Count Words in a File
  25. How to Shuffle the Characters of a String in JavaScript or Node.js
  26. Append Characters or Words to a String in JavaScript or Node.js
  27. Check if a String is Empty in JavaScript or Node.js
  28. Ensure a String Ends with a Given Character in JavaScript or Node.js
  29. Left-Trim Characters Off a String in JavaScript or Node.js
  30. Right-Trim Characters Off a String in JavaScript or Node.js
  31. Lowercase the First Character of a String in JavaScript or Node.js
  32. Uppercase the First Character of a String in JavaScript or Node.js
  33. Prepend Characters or Words to a String in JavaScript or Node.js
  34. Check if a String is a Number
  35. Convert a String to Buffer
  36. Prevent Line Breaks in String Template Literals

Generate an Invoice PDF from HTML

This tutorial illustrates the PDF creation from HTML using the example of an invoice. We extracted code from the Future Studio platform to make it approachable 😃

Let’s start off with this Postmark invoice template. Save the HTML template to your project’s location on your computer. You’ll need it in a minute.

A Dedicated Invoice Class

This tutorial uses an ES2015 class called Invoice that handles the PDF creation from HTML. Let’s say the Invoice class consists of two methods: html and pdf.

The html method reads the mentioned invoice HTML template from local disk. From here, it compiles the file content with Handlebars which returns a function. The resulting compile function from Handlebars can then take data which ultimately renders data into the placeholders resulting in the final HTML.

The pdf function of your Invoice class uses Puppeteer to create a new browser page, sets the HTML content for this page using the Invoice’s html method and generates the PDF content from the Puppeteer page.

const Fs = require('fs')  
const Path = require('path')  
const Util = require('util')  
const Puppeteer = require('puppeteer')  
const Handlebars = require('handlebars')  
const ReadFile = Util.promisify(Fs.readFile)

class Invoice {  
  async html() {
    try {
      const data = {
        your: 'data'
      }

      const templatePath = Path.resolve('path', 'to', 'invoice.html')
      const content = await ReadFile(templatePath, 'utf8')

      // compile and render the template with handlebars
      const template = Handlebars.compile(content)

      return template(data)
    } catch (error) {
      throw new Error('Cannot create invoice HTML template.')
    }
  }

  async pdf() {
    const html = await this.html()

    const browser = await Puppeteer.launch()
    const page = await browser.newPage()
    await page.setContent(html)

    return page.pdf()
  }
}

This is all you need for the PDF creation from HTML. Puppeteer does the difficult handling and gives you the methods to work on top of Chrome.

By default, Puppeteer generates a PDF using the print CSS media. If you want to print with screen CSS, call await page.emulateMedia('screen') before page.pdf().

The PDF Invoice from HTML

This is a sample receipt printed with Puppeteer:

PDF Invoice from HTML

Handlebars and Puppeteer are a powerful combination for PDF files from HTML. Handlebars gives you the flexibility to render data into placeholders and Puppeteer uses the HTML to generate a PDF.

Summary

Puppeteer as a Node.js library to control a headless Chrome browser provides a convenient interface to generate PDF files from HTML. You can render complex HTML with template engines like Handlebars. All libraries combined are a powerful toolset to integrate on-the-fly PDF creation in your Node.js apps.


Mentioned Resources

Explore the Library

Find interesting tutorials and solutions for your problems.