Skip to content

How to convert HTML to PDF using puppeteer

    The Idea is to use headless chrome in-built pdf print from rendered dom and save it as PDF file.

    Sounds interesting and straight forward right, with puppeteer its almost simple.

    Puppeteer is nodejs library, provides high-level api to control headless chrome.

    So steps are as below

    Install puppeteer

    npm install puppeteer

    Include it in your script

    const fs = require('fs')
    const path = require('path')
    const utils = require('util')
    const puppeteer = require('puppeteer')
    const readFile = utils.promisify(fs.readFile)

    We also need fs, path and util to read html file locally, this blog focus more on converting local html file into pdf, we can also do the same with url, refer to note at the end of the blog to convert pdf from url.

    Read and Load HTML file

    async function getHtmlFile() {
    
        console.log("Loading template file in memory")
        try {
            const htmlFile= path.resolve("./test.html");
            return await readFile(htmlFile, 'utf8');
        } catch (err) {
            return Promise.reject("Could not load html file");
        }
    }

    Let’s generate PDF using puppeteer

       getHtmlFile()
            .then(async (res) => {
                const html = res;
                const browser = await puppeteer.launch(); //launch browser
                const page = await browser.newPage() // create new page
                await page.setContent(html) // load html content in new page
                await page.pdf({ 
                 path: 'testpdf.pdf', 
                 format: 'A4', 
                 printBackground:true, 
                 scale:0.75, 
                 displayHeaderFooter: true,
                 headerTemplate: "<div style=\"text-align: center;width: 297mm;font-size:  8px;\">Some Header Title</div>",
                 footerTemplate: "<div style=\"text-align: center;width: 297mm;font-size: 8px;\"><span style=\"margin-right: 1cm\"><span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></span></div>"
     }) //generate pdf using in-build chrome pdf functionality
                await browser.close(); //don't forgot to close browser after task is done
                console.log("PDF Generated")
            })
            .catch(err => {
                console.error(err)
            });

    refer to https://devdocs.io/puppeteer/index#pagepdfoptions to know more about options available

    Above set of options give a good view of my test html and i allowed background graphics to show tables and images in html and used custom header and footer html to get page numbers also. Ofcourse you cannot do them in your chrome UI. That why i love api and sdks, they give you freedom.

    What we can do from here?

    Build a scalable html to pdf app on large scale.

    Use it in offline conversions in your products.

    Build a screenshot from url app.

    Ideas are endless. Let me know what idea you get in your mind.