How to create a pdf using html in nodejs

1.8k views Asked by At

I am trying to convert html into pdf and i wanted to pass some dynamic value inside it and after that i wanted to generate a pdf when i am using this code where i have created an external html file and then i am able to convert the pdf here is the code of that

invoice.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h2>Approve Page ,</h2>
</body>
</html>

and here is the pdf.js file

const fs = require("fs");
const path = require("path");
const utils = require("util");
const puppeteer = require("puppeteer");
const hb = require("handlebars");
const readFile = utils.promisify(fs.readFile);

async function getTemplateHtml() {
  console.log("Loading template file in memory");
  try {
    const invoicePath = path.resolve("./invoice.html");
    return await readFile(invoicePath, "utf8");
  } catch (err) {
    console.log(err);
  }
}

async function generatePdf() {
  let data = {};

  getTemplateHtml()
    .then(async (res) => {
      console.log("Compiing the template with handlebars");
      const template = hb.compile(res, { strict: true });

      const result = template(data);

      const html = result;

      const browser = await puppeteer.launch();
      const page = await browser.newPage();

      await page.setContent(html);

      await page.pdf({ path: "invoice.pdf", format: "A4" });

      await browser.close();
      console.log("PDF Generated");
      return;
    })
    .catch((err) => {
      console.error(err);
    });
}

generatePdf();

but i wanted to implement in this manner

const fs = require("fs");
const path = require("path");
const utils = require("util");
const puppeteer = require("puppeteer");
const hb = require("handlebars");
const readFile = utils.promisify(fs.readFile);
const A = "invoice";
const html = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h2>Approve Page ,${A}</h2>
</body>
</html>
`;

async function getTemplateHtml() {
  console.log("Loading template file in memory");
  try {
    return await readFile(html, "text/html utf8");
  } catch (err) {
    console.log(err);
  }
}

async function generatePdf() {
  let data = {};

  getTemplateHtml()
    .then(async (res) => {
      console.log("Compiing the template with handlebars");
      const template = hb.compile(res, { strict: true });

      const result = template(data);

      const html = result;

      const browser = await puppeteer.launch();
      const page = await browser.newPage();

      await page.setContent(html);

      await page.pdf({ path: "invoice.pdf", format: "A4" });

      await browser.close();
      console.log("PDF Generated");
      return;
    })
    .catch((err) => {
      console.error(err);
    });
}

generatePdf();

but getting this error

message: 'You must pass a string or Handlebars AST to Handlebars.compile. You passed undefined', name: 'Error',

1

There are 1 answers

0
ramb tumber On

I am able to solve this problem with very less code but wanted to ask is it possible to convert it into base64 instead of creating a pdf file. here is the solution

const fs = require("fs");
const path = require("path");
const utils = require("util");
const puppeteer = require("puppeteer");
const hb = require("handlebars");
const readFile = utils.promisify(fs.readFile);
(async () => {
const A = "invoice";
const htmlContent = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h2>Approve Page ,${A}</h2>
</body>
</html>
`;
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setContent(htmlContent);
  await page.pdf({ path: "html.pdf", format: "A4" });

  await browser.close();
})();