3

I'm writing a nodejs method which I want to convert an ejs file to a pdf file

router.get("/uknow", (req, res) => {
    ejs.renderFile(path.join(__dirname, "../../views/resultat.ejs"),  (err, data) => {
    if (err) {
          res.send(err);
    } else {
        
        pdf.create(data).toFile("report.pdf", function (err, data) {
            if (err) {
                res.send(err);
            } else {
                res.send("File created successfully");
            }
        });
    }
});
})

this is the method which I wrote and I get this response in post man

{
    "path": "C:\\Users\\HP\\Desktop\\exemple CRUD\\blog_api\\views\\resultat.ejs"
}

i print the error and this is what i get ReferenceError:

C:\Users\HP\Desktop\exemple CRUD\blog_api\views\resultat.ejs:41
    39| </head>
    40| <body class="spacer">
 >> 41|     <h2 class="text-center my-3"><%= data[0].imei.name %></h2>
    42|     <h5 class="text-center my-3">Imei -<%= data[0].imei.name %> </h5>
    43|     <h3 class="text-center my-3">Resultat des tests</h3>
    44|     <hr>

data is not defined
    at eval (eval at compile (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\ejs\lib\ejs.js:661:12), <anonymous>:10:26)
    at resultat (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\ejs\lib\ejs.js:691:17)
    at tryHandleCache (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\ejs\lib\ejs.js:272:36)
    at Object.exports.renderFile (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\ejs\lib\ejs.js:489:10)
    at C:\Users\HP\Desktop\exemple CRUD\blog_api\routes\apis\post.js:121:9
    at Layer.handle [as handle_request] (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\route.js:137:13)
    at Route.dispatch (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\route.js:112:3)
    at Layer.handle [as handle_request] (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\layer.js:95:5)
    at C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\index.js:281:22
    at Function.process_params (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\index.js:335:12)
    at next (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\index.js:275:10)
    at Function.handle (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\index.js:174:3)
    at router (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\index.js:47:12)
    at Layer.handle [as handle_request] (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\layer.js:95:5)
    at trim_prefix (C:\Users\HP\Desktop\exemple CRUD\blog_api\node_modules\express\lib\router\index.js:317:13) {
  path: 'C:\\Users\\HP\\Desktop\\exemple CRUD\\blog_api\\views\\resultat.ejs'
}

and nothing in the console. I need some help.

2 Answers 2

0

Render the file first (with your data), then pass the rendered HTML to the pdf'er

Untested, try this:

router.get("/uknow", (req, res) => {

  // your missing data, wheres it coming from?
  // it should also look like:
  // let data = { data: [{ imei: { name: '', ...}}, ...], ...}

  // render the ejs file
  ejs.renderFile(path.join(__dirname, '..', '..', 'views', 'resultat.ejs'), data, {}, function(err, str) {
    if (err) return res.send(err);

    // str now contains your rendered html
    pdf.create(str).toFile("report.pdf", function(err, data) {
      if (err) return res.send(err);

      res.send("File created successfully");
    });
  });
});
Sign up to request clarification or add additional context in comments.

3 Comments

i have no data i just want to change the ejs file to pdf that's it
then remove all the variables or pass empty values, no undefined vars in ejs
thank you it works i will check how to add data but with empty it's good but it did not take the real size wich try in html
0

I was in similar need, i already had configured express-ejs-layouts so i used the default res.render with Google's puppeteer

npm install puppeteer or yarn add puppeteer

My Utility Function
async function generatePDF(ejsContextData) {
      const browser = await puppeteer.launch();
      const page = await browser.newPage();

      const html = await new Promise((resolve, reject) => {
        res.render(
          "my-document-html",
          contextData,
          (err, html) => {
            if (err) {
              reject(err);
            } else {
              resolve(html);
            }
          }
        );
      });

      await page.setContent(html);

      const pdfBuffer = await page.pdf({
        format: "Letter",
        path: "document.pdf",
      });

      await browser.close();
      return pdfBuffer;
    }

I believe you can choose to stream the Buffer to the browser directly or alternatively write to disk if you intend to save this. In my case i needed to show it on the browser. However, if an immediate download is the goal, you may configure your "Content-Disposition" to be an attachment instead

generatePDF(contextData)
      .then((pdfBuffer) => {
        res.setHeader("Content-Type", "application/pdf");
        res.setHeader("Content-Disposition", "inline; filename=document.pdf");

        res.write(pdfBuffer);
        res.end();
      })
      .catch((error) => {
        console.error(error);
        res.status(500).json({
          status: false,
          error: "Failed to generate PDF.",
        });
      });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.