Blog Post

How to Generate PDFs from HTML with Node.js

Illustration: How to Generate PDFs from HTML with Node.js
Information

This article was first published in June 2021 and was updated in September 2024.

This guide explains how to generate PDFs from HTML using Node.js and PSPDFKit’s Document Engine. It includes steps for setting up the Document Engine, preparing HTML content, and converting it to PDF.

Getting Started with Document Engine

Requirements

Before we begin, ensure your system meets the following requirements:

  • Operating Systems:

    • macOS Ventura, Monterey, Mojave, Catalina, or Big Sur.

    • Ubuntu, Fedora, Debian, or CentOS (64-bit Intel and ARM processors supported).

  • Memory: At least 4 GB of RAM.

Installing Docker

Document Engine is distributed via Docker. Install Docker by following the appropriate instructions for your OS:

Setting Up Document Engine

To start Document Engine, you’ll need to configure Docker. Save the following docker-compose.yml file:

version: "3.8"
services:
  document_engine:
    image: pspdfkit/document-engine:1.5.0
    environment:
      PGUSER: de-user
      PGPASSWORD: password
      PGDATABASE: document-engine
      PGHOST: db
      PGPORT: 5432
      API_AUTH_TOKEN: secret
      SECRET_KEY_BASE: secret-key-base
      JWT_PUBLIC_KEY: |
        -----BEGIN PUBLIC KEY-----
        MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2gzhmJ9TDanEzWdP1WG+
        0Ecwbe7f3bv6e5UUpvcT5q68IQJKP47AQdBAnSlFVi4X9SaurbWoXdS6jpmPpk24
        QvitzLNFphHdwjFBelTAOa6taZrSusoFvrtK9x5xsW4zzt/bkpUraNx82Z8MwLwr
        t6HlY7dgO9+xBAabj4t1d2t+0HS8O/ed3CB6T2lj6S8AbLDSEFc9ScO6Uc1XJlSo
        rgyJJSPCpNhSq3AubEZ1wMS1iEtgAzTPRDsQv50qWIbn634HLWxTP/UH6YNJBwzt
        3O6q29kTtjXlMGXCvin37PyX4Jy1IiPFwJm45aWJGKSfVGMDojTJbuUtM+8P9Rrn
        AwIDAQAB
        -----END PUBLIC KEY-----
      JWT_ALGORITHM: RS256
      DASHBOARD_USERNAME: dashboard
      DASHBOARD_PASSWORD: secret
    ports:
      - 5000:5000
    depends_on:
      - db
  db:
    image: postgres:16
    environment:
      POSTGRES_USER: de-user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: document-engine
    volumes:
      - pgdata:/var/lib/postgresql/data

volumes:
  pgdata:

Starting Document Engine

Open a terminal, navigate to the directory containing the docker-compose.yml file, and run:

docker-compose up

Wait until you see the message:

document_engine_1  | Access the web dashboard at http://localhost:5000/dashboard

Visit http://localhost:5000/dashboard and authenticate using the following credentials:

  • Username: dashboard

  • Password: secret

Document engine dashboard

Generating PDFs from HTML with Document Engine

PSPDFKit’s Document Engine simplifies the process of generating PDFs directly from HTML. Here’s how to do it step by step.

Step 1 - Prepare Your HTML Template

First, create an HTML template for your content. Use Mustache to dynamically inject data into the template. Save this template as template.mustache:

<!DOCTYPE html>
<html>
  <body>
    <div class="address">
      John Smith<br/>
      123 Smith Street<br/>
      90568 TA<br/>
      <br/>
      {{date}}
    </div>
    <div class="subject">Subject: PDF Generation FTW!</div>
    <div>
      <p>PDF is great!</p>
    </div>
    <div>{{name}}<br/></div>
  </body>
</html>

Step 2 - Provide the Dynamic Data

Create a data.json file with the data that will replace the placeholders in your HTML template:

{
  "name": "John Smith Jr.",
  "date": "29 February, 2020"
}

Step 3 - Render HTML Using Mustache

Next, render the HTML using Mustache:

const mustache = require("mustache");
const fs = require("fs");

const template = fs.readFileSync("template.mustache").toString();
const data = JSON.parse(fs.readFileSync("data.json").toString());

const outputHtml = mustache.render(template, data);

// Save the rendered HTML file
fs.writeFileSync("output.html", outputHtml);
console.log("HTML generated successfully.");

Step 4 - Send HTML to the Document Engine

Instead of converting the HTML yourself, you can send it to the Document Engine’s API to generate the PDF. Here’s an example using axios to send the rendered HTML:

const axios = require('axios');
const fs = require('fs');

// Read the generated HTML
const htmlContent = fs.readFileSync('output.html', 'utf8');

// Define the PDF generation schema
const pdfGenerationSchema = {
  html: htmlContent,
  layout: {
    orientation: 'portrait', // Optional: 'landscape' or 'portrait'
    size: 'A4', // Optional: 'A4', 'Letter', or custom dimensions
    margin: {
      left: 10, // Optional: margin sizes in mm
      top: 10,
      right: 10,
      bottom: 10
    }
  }
};

// Send the HTML to the Document Engine API
axios.post('http://localhost:5000/api/documents', pdfGenerationSchema, {
  headers: {
    Authorization: 'Token token=YOUR_API_TOKEN',
    'Content-Type': 'application/json',
  }
})
.then((response) => {
  // Handle the PDF response (e.g., save the PDF file)
  fs.writeFileSync('output.pdf', response.data);
  console.log('PDF generated successfully.');
})
.catch((error) => {
  console.error('Error generating PDF:', error);
});

Step 5 - Adding Watermarks and Cover Pages

The Document Engine can add extra features like watermarks and cover pages via its API. To add a watermark, include an additional HTML block like this:

<div style="position: fixed;
  top: 50%;
  left: 50%;
  font-size: 72px;
  color: red;
  opacity: 0.5;
  transform: rotate(-45deg);
  text-align: center;
  z-index: -1;">
  My Watermark
</div>

This will place a semi-transparent watermark in the center of the PDF.

For a cover page, you can add an additional HTML block with a page break:

<div style="page-break-after: always;">
  <h1>Cover Page</h1>
  <p>This is the cover page of the PDF.</p>
</div>

Alternatively, you can upload an existing PDF as the cover page through the Document Engine API:

curl -X POST http://localhost:5000/api/documents \
  -H "Authorization: Token token=<API token>" \
  -F page.html=@/path/to/page.html \
  -F cover.pdf=@/path/to/cover.pdf \
  -F generation='{
  "html": "page.html"
}' \
  -F operations='{
  "operations": [
    {
      "type": "importDocument",
      "beforePageIndex": 0,
      "document": "cover.pdf"
    }
  ]
}'

Conclusion

You have now learned how to use Node.js and PSPDFKit’s Document Engine to generate PDFs from HTML. This process includes setting up the Document Engine, rendering HTML with dynamic data, and using API requests to generate the final PDF. This method is useful for producing documents like reports and invoices directly from HTML. For access to an API token, please contact our Sales team.

FAQ

What are the system requirements for running PSPDFKit’s Document Engine?

PSPDFKit’s Document Engine requires at least 4 GB of RAM and can be run on macOS (Ventura, Monterey, Mojave, Catalina, or Big Sur) and Linux distributions (Ubuntu, Fedora, Debian, CentOS). Docker is required to run the engine.

Do I need Puppeteer or any other tools to generate PDFs with PSPDFKit’s Document Engine?

No, PSPDFKit’s Document Engine handles the entire process of converting HTML to PDF, so you don’t need Puppeteer or any other tool to generate PDFs.

How do I add dynamic content like names and dates to my PDFs?

You can use Mustache templates to inject dynamic data into your HTML before sending it to the Document Engine. This allows you to create personalized PDFs by simply updating the data file.

Can I add watermarks or cover pages to my PDFs?

Yes, PSPDFKit’s Document Engine allows you to add watermarks and cover pages through its API. You can either add HTML for a watermark or upload a separate PDF file as a cover page.

How do I interact with the Document Engine using Node.js?

You can send an API request using Node.js and a library like axios to pass your HTML content to the Document Engine, which will return the generated PDF. The tutorial includes a sample script for making this request.

Author
Hulya Masharipov Technical Writer

Hulya is a frontend web developer and technical writer at PSPDFKit who enjoys creating responsive, scalable, and maintainable web experiences. She’s passionate about open source, web accessibility, cybersecurity privacy, and blockchain.

Explore related topics

Related products
Share post
Free trial Ready to get started?
Free trial