Tutorial : Generate a PDF in NodeJS

A new way to created PDFs from a web application using Puppeteer!

Article publié le 17/05/2021, dernière mise à jour le 22/09/2023

If you're looking to create a pdf in Javascript within NodeJS, you've got 2 solutions :

  • You can either create, by hand, a PDF using a library like PDFKit for example
  • Or you can generate a PDF from a HTML document

I'm going to show you the second solution because it's faster, it allows you to easily edit the document layout and you benefit from the rendering power of HTML/CSS.

Using Puppeteer

It's possible to generate a pdf directly from the browser, by combining the library html2canvas to transform the DOM into an image, and then insert the resulting image into a PDF file.

But this solution has a wobbly rendering, is browser-dependant (looks different on different browsers) and the text can't be selected, because it's only available as an image.

By using Puppeteer, we're simply going to use the "Print as PDF" feature availble under Chromium, but in an automated way to get a perfectly rendered document !

As a reminder, Puppeteer is an headless browser, meaning it is able to do anything a regular browser can do, without displaying anything on the screen, which is allow us to automate many tasks like this one.

Puppeteer can also be used to crawl web pages as I explain in this other post I wrote on the blog (in French).

The code

First you'll need to install Puppeteer, to do so, we will use the following command:

npm install puppeteer
# or with yarn
yarn add puppeteer

Next, you will need to create the script that will load a web page (I personally chose one of my blog posts), then inject some CSS to hide some unwanted elements (header, cookie-bar, etc...) and finally generate our PDF!

//index.js
const puppeteer = require('puppeteer')
 
async function generatePDF() {

  //We start a new browser, without showing UI
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  const url = 'https://blog.nicolas.brondin-bernard.com/comment-resoudre-les-problemes-daccents-dans-vos-pages-web/';

  //We load the page, one of my blog post (networkidle0 means we're waiting for the network to stop making new calls for 500ms
  await page.goto(url, {waitUntil: 'networkidle0'});
  //We add style to hide some UI elements we don't want to see on our pdf
  await page.addStyleTag({ content:
    `header.site-header,
    #cookie-band,
    .post-full-image,
    .post-full-comments,
    .read-next,
    .site-footer { 
      display: none !important;
    }`
  });

  //Let's generate the pdf and close the browser
  const pdf = await page.pdf({ path: "article.pdf", format: 'A4' });
  await browser.close();
  return pdf;
}

generatePDF();

Thanks to this method, you can create a pdf generator, either based on an existing web application, or from a special web app only available from the back-end which will be loaded by Puppeteer!


Hamed Daram sur Unsplash

Vous avez terminé l'article ?

Commentaires (0)

pour laisser un commentaire

Aucun commentaire pour l'instant