DEV Community

Cover image for Use puppeteer with Node to create PDFs!
Shahid Alam
Shahid Alam

Posted on

Use puppeteer with Node to create PDFs!

How to Create a PDF Generator Using Puppeteer and Node.js

Alt Text

Generating dynamic PDFs is a common requirement in web development. Whether it's for invoices, reports, or resumes, creating a robust PDF generator is an essential skill for developers. In this article, I'll walk you through building a PDF generator using Node.js and Puppeteer, a powerful headless browser library.

As an example, I used this same method to build my CV Maker Project, which takes user input and dynamically generates a PDF. You can see the live demo of the project here: Live Demo.

This guide is written in plain, beginner-friendly language. If any part feels unclear, feel free to leave a comment, and I’ll address it as soon as possible.


Prerequisites

Before we begin, ensure you have the following:

  • Node.js installed on your machine.
  • A basic Node.js project skeleton set up.
  • Puppeteer installed as a dependency in your project:
  npm install puppeteer
Enter fullscreen mode Exit fullscreen mode

If you’d like to reference the complete source code for this tutorial, check out my GitHub repository.


Step 1: Create a POST Endpoint for Receiving Data

First, create an endpoint where the client can send data to generate a PDF. For this, we’ll define a simple POST route in our index.js (or equivalent main server file).

app.post("/data", async (req: Request, res: Response) => {
    let postData = req.body.data; // Storing the data sent from the client
});
Enter fullscreen mode Exit fullscreen mode

This endpoint will receive the data that needs to be included in the PDF.


Step 2: Create a Controller File

To keep the code organized, create a folder named controllers in your project directory. Inside this folder, create a file named PdfController.js.

The controller file is where we’ll write the logic for generating the PDF. This keeps our code modular and makes it easier to maintain.


Step 3: Write Logic for PDF Generation

In PdfController.js, add the following code to generate a PDF using Puppeteer:

export default (async function (postData) {
    try {
        const browser = await puppeteer.launch({
            headless: true,
            args: ["--no-sandbox", "--disable-gpu"],
        });

        const page = await browser.newPage();
        const content = `<html><body><h1>${postData}</h1></body></html>`;

        await page.setContent(content);
        await page.emulateMediaType('screen');
        await page.pdf({
            path: 'resume.pdf',
            format: 'A4',
            printBackground: true,
        });

        console.log('PDF created');
        await browser.close();
    } catch (err) {
        console.error('Error:', err);
    }
});
Enter fullscreen mode Exit fullscreen mode

Here’s what this code does:

  1. Launches a Puppeteer browser instance in headless mode.
  2. Opens a new page and sets the content using the data provided by the user.
  3. Converts the page content into a PDF and saves it as resume.pdf.
  4. Closes the browser to free up resources.

Step 4: Use the PdfController Function in the POST Endpoint

Now, connect the PdfController function to the POST endpoint in index.js:

import PdfController from "./controllers/controller.js";

app.post("/data", async (req: Request, res: Response) => {
    let postData = req.body.data; // Storing the data sent from the client
    await PdfController(postData);
});
Enter fullscreen mode Exit fullscreen mode

This ensures that whenever the /data endpoint is called, the logic for generating the PDF will be executed.


Step 5: Verify the PDF Generation

At this point, you can test the endpoint using Postman or any other HTTP client. When you send a POST request with the relevant text data, a PDF named resume.pdf will be created in the project’s root directory.


Step 6: Send the PDF Back to the Client

To send the generated PDF back to the client as a response, install the fs-extra package:

npm install fs-extra
Enter fullscreen mode Exit fullscreen mode

Then update the POST endpoint as follows:

import PdfController from "./controllers/controller.js";
const fs = require("fs-extra");

app.post("/data", async (req: Request, res: Response) => {
    let postData = req.body.data; // Storing data sent from the client
    await PdfController(postData);

    // Read the generated PDF file
    const file = fs.createReadStream("./resume.pdf");
    const stat = fs.statSync("./resume.pdf");

    // Set response headers for the file
    res.setHeader("Content-Length", stat.size);
    res.setHeader("Content-Type", "application/pdf");
    res.setHeader("Content-Disposition", "attachment; filename=resume.pdf");

    // Send the file back to the client
    file.pipe(res);
    console.log('PDF download sent');
});
Enter fullscreen mode Exit fullscreen mode

This code sends the resume.pdf file as a downloadable attachment to the client.


Conclusion

Alt Text

And that’s it! 🎉 You’ve built a complete PDF generator using Node.js and Puppeteer. This setup dynamically generates PDFs based on user input and sends them back as downloadable files.

Here’s what you achieved:

  • Set up a Node.js server with a POST endpoint.
  • Used Puppeteer to generate PDFs dynamically.
  • Sent the generated PDF back to the client.

Bonus

If you’d like to generate well-structured and formatted PDFs (e.g., resumes or invoices with tables and styles), let me know in the comments. I’d love to write another tutorial for advanced use cases.

Also, feel free to check out the complete project code. It’s well-documented and beginner-friendly.

Have a nice day!

Top comments (0)