2

好的,我在这里看到了这个问题的几个版本,但我认为我的问题比其他一些版本更深入,而且我没有看到令人满意的答案。

我想要的是:

我在网站上有一个页面,用户经常更改其内容,我希望他们点击“生成 PDF”按钮,并能够将页面上的相关信息转换为漂亮的 PDF 报告。

我正在尝试使用 NodeJS、Express 和 Heroku 上的部署来做到这一点。

一般来说,这就是我试图做到这一点的方式:

我的计划:

  1. 发起 GET 请求
  2. 查询数据库以获得相关结果
  3. 将数据加载到 EJS 模板中
  4. 保存生成的 HTML
  5. 使用 npm 模块HTML-pdf将其流式传输到浏览器中

其他重要细节:

  1. 这个文件是短暂的。我不想把它保存在任何地方。
  2. 我什至不想在任何地方写它,因为它只意味着当时存在于浏览器中。
  3. 这个应用程序部署在 Heroku 上,需要在其结构中工作。我不喜欢使用像 S3 这样的文件存储。

我的代码:

router.get('/formulas/:id/pdf', function(req, res){
  var db = req.db.collection('users');
  var id = new ObjectID(req.params.id);
  var pointer = {"formulas.$": 1, "_id": 0};
//query database, get the info out
db.aggregate([
  {$match: {"formulas.f_id": id}},
  {$unwind: "$formulas"},
  {$match: {"formulas.f_id": id}},
  {$project : {"formulas": 1, "_id": 0}}
]).toArray(function(e, doc){
  if (e) {
  throw e;
} else {
  var html = null;
  ejs.renderFile('./views/pdf.ejs', { //create template from db query
    project: doc[0].formulas,
    title: 'Formula Info Report',
    description:  'PDF Report For Your Formula by Nutraceutical Pro',
    ID: 'pdf',
    keywords: 'PDF, PDF generator, Formula Info Report',
    user: req.user,
    loggedIn: req.isAuthenticated()
  }, function(err, results){
    if (err) {
      console.log(err);
      }
      html = results; //save results of HTML output
    });
    var options = { format: 'Letter' };
    var path = './public/pdf/formula-' + req.params.id + '.pdf';
    pdf.create(html, options).toStream(function(err, stream) {//initiate stream
      if (err) {
        return console.log(err);
      }
      if (stream) {
        console.log(stream);
        stream.pipe(fs.createWriteStream(path));
        console.log("the pdf was streamed.");
        res.end();
        }
      });
    }
  });
});

GET我使用 AJAX 调用发起请求,如下所示:

 $('.getPDF').click(function(){
   var filepath = 'https://my-domain.herokuapp.com/pdf/formula-' + this.id + '.pdf';
 $.ajax({
   url: '/formulas/'+ this.id +'/pdf',
   type: 'GET',
   success: function () {window.open(filepath);}
 });

当我运行脚本时,我生成了一个流,控制台记录了 PDF 的创建。如果我只是将生成的文件保存到我的本地系统,它会很好,但在我的应用程序中,我收到以下错误消息:

Cannot GET /pdf/formula-59cc38992fb99b00045832ad.pdf

因此,就像正在创建 PDF 的原材料一样,但它并没有被记录并以允许应用程序读取它的方式创建。

我对此持开放态度,因此如果有更简单的方法可以做到这一点,我会全力以赴。不过,我更愿意坚持使用我当前的堆栈。

4

0 回答 0