DEV Community

Cover image for Stop Wasting Hours on PDF Generation: A Fast, Clean JavaScript Setup with reportgen.io
Ethan from reportgen.io
Ethan from reportgen.io

Posted on

Stop Wasting Hours on PDF Generation: A Fast, Clean JavaScript Setup with reportgen.io

Generating PDFs in a JS app used to mean fragile Puppeteer scripts, bloated code, or expensive third-party services. We hated it. So we built reportgen.io. A faster, simpler way to generate dynamic documents with real templates and real data.

Whether you’re building invoicing software, generating reports, or creating marketing materials, reportgen.io makes it easy to create dynamic, high-quality PDFs.

Before You Begin

To follow along, make sure you have:

  • A JavaScript or TypeScript project set up.
  • An Access key from reportgen.io.
  • Basic familiarity with REST APIs and how to make HTTP requests.
  • Node.js installed on your system.

You can also use tools like Postman or curl to test the API before diving into code. Postman is a powerful API testing tool that simplifies debugging. Download Postman to get started.

In this guide for dynamic PDF generation with Javascript, we will be using the EJS templating engine. EJS is a simple templating language that lets you generate HTML markup with plain JavaScript. If you’re new to EJS, you can learn more about it in the official documentation.
There are other templating engines like Handlebars, GoTempl and Raw that you can use with reportgen.io. Learn more about templating engines.

Step 1: Set Up Your Project and Install Dependencies

First, create a folder structure for your project. Here’s a suggested layout:

/project-root
    /templates
        invoice.ejs
    /src
        reportgen.js
    index.js
    package.json
Enter fullscreen mode Exit fullscreen mode

Initialize Your Project and Install Dependencies

Run the following command to initialize your project:

npm init -y
Enter fullscreen mode Exit fullscreen mode

Install Required Dependencies

npm install node-fetch
Enter fullscreen mode Exit fullscreen mode

Step 2: Create your dynamic HTML template

Create an HTML template in the /templates folder. For example, name it invoice.ejs and include:

<!DOCTYPE html>
<html>
<head>
  <title>Invoice</title>
</head>
<body>
  <h1>Invoice for <%= Name %></h1>
  <p>Total Due: $<%= Total %></p>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

Save this file as invoice.ejs. This template will be processed server-side by reportgen.io using the EJS templating engine.

Step 3: Integrate with the reportgen.io API

Create a new file in the /src directory, e.g., reportgen.js. Add the following code which will interact with reportgen API (the core function that you will call across your project):

import { readFileSync } from "fs";
import path from "path";
import fetch from "node-fetch";

export const generatePDF = async (templateKey, data) => {
    const apiUrl = "https://reportgen.io/api/v1/generate-pdf-sync";
    const accessKey = process.env.REPORTGEN_ACCESS_KEY;

    // Load the HTML template
    const htmlTemplate = readFileSync(
        path.resolve("templates", `${templateKey}.ejs`),
        "utf8"
    );

    const payload = {
        html_template: htmlTemplate,
        data: data,
        engine: "ejs", // Also supports "handlebars, gotempl and raw"
    };

    try {
        const response = await fetch(apiUrl, {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                "X-API-Key": accessKey,
            },
            body: JSON.stringify(payload),
        });

        if (!response.ok) {
            const error = await response.json();
            throw new Error(`API error: ${error.message}`);
        }

        const pdfBuffer = await response.arrayBuffer();

        return pdfBuffer;
    } catch (err) {
        throw new Error(`Error generating PDF: ${err}`);
    }
};
Enter fullscreen mode Exit fullscreen mode

Explanation of the Code:

  1. File Read: The fs module reads your template file.
  2. Payload: Prepares the payload for the API request.
  3. Fetch API: Makes an HTTP POST request to the reportgen.io endpoint.
  4. Error Handling: Outputs helpful messages if something goes wrong.

Step 4: Prepare the last pieces for your integration

Set your access key in the environment

Usually you would have .env file in the project root directory. Add your access key to the .env file like this:

REPORTGEN_ACCESS_KEY=your_access_key_here
Enter fullscreen mode Exit fullscreen mode

But you can also simply set the environment variable in your terminal with export:

export REPORTGEN_ACCESS_KEY=your_access_key
Enter fullscreen mode Exit fullscreen mode

Create the main file that will call the function

Create an index.js file where you'll call the new function:

import { generatePDF } from "./src/reportgen.js";
import fs from "fs";

const data = {
    Name: "John Doe",
    Total: 120,
}

generatePDF("invoice", data)
    .then((pdfArrayBuffer) => {
        fs.writeFileSync("invoice_for_john.pdf", Buffer.from(pdfArrayBuffer));
        console.log('PDF successfully generated and saved as invoice_for_john.pdf');
    })
    .catch((err) => {
        console.log(`Error generating PDF: ${err}`);
    });
Enter fullscreen mode Exit fullscreen mode

Explanation of the Code:

  1. Data Object: Contains the "dynamic" data to be injected into the template.
  2. Function Call: Invokes the generatePDF function with the template key and data.
  3. Write PDF: Saves the generated PDF to a file.
  4. Console Log: Displays a success message or error.

Step 5: Test your integration ✅

Run your script:

node index.js
Enter fullscreen mode Exit fullscreen mode

Upon success, the console will display a message that the PDF has been generated and saved. You can find the freshly generated PDF in your project directory under the name invoice_for_john.pdf.

Extra: Testing with tools like Postman

Before coding, you can use testing tools like Postman to validate your API calls:

  1. Set the method to POST and the URL to https://reportgen.io/api/v1/generate-pdf-sync.
  2. Add the X-API-Key header with your access key.
  3. In the body, set the payload as raw JSON:
{
  "html_template": "<h1>Hello <%= Name %></h1>",
  "data": { "Name": "John Doe" },
  "engine": "ejs"
}
Enter fullscreen mode Exit fullscreen mode
  1. Check the response for errors or success.

Learn more about using Postman in their documentation.

Next Steps

Ready to stop wasting time on document generation? Sign up at reportgen.io and create your first PDF in under 5 minutes.

  • 💻 Source code: On GitHub, plus a lot more examples.
  • 👉 Create an Account: Sign up if you haven’t already.

👥 Have a better way to write this code? Drop it in the comments below. I always love a good code review!

Top comments (0)