Ankur Soni
Ankur Soni

Reputation: 6018

Generate PDF Report in Meteor js

I am very close to generate PDF report in Meteor js which will help many folks out there. My code runs almost till the end, but ends up having error

{ [Error: ENOENT, open 'report.pdf'] errno: 34, code: 'ENOENT', path: 'report.pdf' }

Below is code snippet which I am using to generate a PDF list.

Layout.html

<head>
    <style type="text/css">
        {{css}}
     </style>
 </head>
 <body>
      {{> Template.dynamic template=template data=data}}
 </body>

report.html

<body>
    <div class="container">
        {{#each voters}}
            <h4>{{name}}</h4><br>
         {{/each}}
    </div>
</body>

server/method.js

var total = voters.find()

Meteor.methods({'generate_pdf': function() {

console.log("--------inside PDF generation Module----------");

var fs      = Npm.require('fs'),
    Future  = Npm.require('fibers/future'),
    fut = new Future(),
    fileName = "report.pdf",
    voters = total,
    data = { voters: voters }

SSR.compileTemplate('layout', Assets.getText('layout.html'));

SSR.compileTemplate('report', Assets.getText('report.html'));

var html_string = SSR.render('layout', { template: "report", data: data });

var options = {
        "paperSize": { "format": "Letter", "orientation": "portrait", "margin": "1cm" },
          siteType: 'html'
};

console.log("------------Commencing webshot-----------");

webshot(html_string, fileName, options, function(err) {
  fs.readFile(fileName, function (err, data) {
     if (err) {
        return console.log(err);
     }

     fs.unlinkSync(fileName);
     fut.return(data);
  });
});

console.log("------------Waiting till PDF generated-----------");   

let pdfData = fut.wait();
let base64String = new Buffer(pdfData).toString('base64');

console.log("------------Return result-----------"); 

return base64String;
 }
});

Triggerpoint with button : home.html

<template name="home">
    <div class="container">
        <div class="row">
            <div class="col-sm-6 col-sm-offset-3">
                <a href="#" class="generate-pdf">Generate PDF</a>
            </div>
        </div>
    </div>
</template>

home.js

Template.home.events({
    'click .generate-pdf': function(e, tmpl) {
        e.preventDefault();

        Meteor.call('generate_pdf', function(err, res) {
          if (err) {
                console.error(err);
          } else if (res) {
                window.open("data:application/pdf;base64, " + res);
          }
        })
      }
});

ERROR LOG ON CONSOLE :

=> Meteor server restarted                    
=> Client modified -- refreshing
I20160509-16:17:04.639(5.5)? --------inside PDF generation Module----------
I20160509-16:17:14.617(5.5)? ------------Commencing webshot-----------
I20160509-16:17:14.622(5.5)? ------------Waiting till PDF generated-----------
I20160509-16:17:14.712(5.5)? { [Error: ENOENT, open 'report.pdf'] errno: 34, code: 'ENOENT', path: 'report.pdf' } 
  1. As per my understanding the error is thrown at line fs.readFile(fileName, function (err, data) { in file method.js
  2. While it is not able to read the file which might not be generated. Can anyone help me out for this, if this case is solved many would be in benefit with ready boiler plate code here.

Upvotes: 0

Views: 1378

Answers (1)

Ankur Soni
Ankur Soni

Reputation: 6018

Initially I had below meteor packages to create PDF using Phantomjs and display on seperate TAB: [For Meteor version 1.3.2.4]

1. dfischer:phantomjs

2. meteorhacks:ssr

3. jaredmartin:future

4. meteorhacks:npm

5. bryanmorgan:webshot

After hours of debugging, I found out that I had to remove package bryanmorgan:webshot and manually add a package entry for "webshot":"0.15.4" in Project/packages.json file. In short, I had to add npm's webshot into my meteor project.

Then, I had to restart meteor and it worked.

Upvotes: 1

Related Questions