Developments in Digital
Developments in Digital

Converting static files website to PDF using Puppeteer

If you wish to generate a PDF output from a static file website, one option is to use Puppeteer, a headless Chrome based browser for Node.

By hosting the static web site (in this case via Express) on localhost, Puppeteer can be configured to point at the running site and export the result to a PDF file.

const express = require('express')
const path = require('path')
const puppeteer = require('puppeteer')

const serve = (folder, done) => {
  const port = process.env.PORT || 3000
  const app = express()

  app.use(express.static(folder))

  const server = app.listen(port, async () => {
    await done(port)
    server.close()
  })
}

const savePdf = async (port, outputPath) => {
  const browser = await puppeteer.launch({ headless: true })
  const page = await browser.newPage()
  await page.goto(`http://localhost:${port}`)

  const pdfConfig = {
    path: outputPath,
    format: 'A4',
    printBackground: true,
    margin: {
      top: '2.54cm',
      bottom: '2.54cm',
      left: '2.54cm',
      right: '2.54cm',
    },
  }

  await page.emulateMedia('screen')
  await page.pdf(pdfConfig)

  await browser.close()
}

const generatePdf = (webFolder, outputPath) => {
  serve(webFolder, async port => {
    await savePdf(port, outputPath)
  })
}

const main = args => {
  if (args.length !== 4) {
    throw new Error('Usage: node pdf.js <site-folder> <output-path>.')
  }

  const siteFolder = path.resolve(process.argv[2])
  const outputPath = path.resolve(process.argv[3])

  generatePdf(siteFolder, outputPath)
}

main(process.argv)

You can then invoke the conversion with, e.g:

node pdf.js ./public ./output.pdf