【问题标题】:How to use pdf output of PDFMake in the attachment mail options of NodeMailer?如何在 NodeMailer 的附件邮件选项中使用 PDFMake 的 pdf 输出?
【发布时间】:2015-10-22 16:16:44
【问题描述】:

这是一个 PDFMake 的代码 sn-p 到create pdf file:

var pdfDoc = printer.createPdfKitDocument(docDefinition);
pdfDoc.pipe(fs.createWriteStream('pdfs/absolute.pdf'));
pdfDoc.end();

这是attachment option in NodeMailer之一:

{
  // stream as an attachment
  filename: 'text4.txt',
  content: fs.createReadStream('file.txt')
}

我能够创建 pdf 并将其保存到目录中的文件中,并将保存的文件附加到电子邮件中,但 我想直接将 pdf 的输出发送到电子邮件的附件内容中,而不将 pdf 输出保存到文件中

我试图了解 nodejs 管道和流功能,但无法理解它们以满足我的要求。我认为应该可以通过流和管道实现,但不知道如何实现。

我想阻止将 pdf 输出保存到文件,因为可能有多个用户使用创建 pdf 文件和发送电子邮件的功能。可能会出现一个用户创建的 pdf 文件会被另一个用户覆盖的情况。

【问题讨论】:

    标签: node.js email pdf nodemailer pdfmake


    【解决方案1】:

    您可以代替管道,将整个 pdfdoc 传递给附件

    var pdfDoc = printer.createPdfKitDocument(docDefinition); 
    pdfDoc.end();
    

    然后:

    attachments: {
        // stream as an attachment
        filename: 'text4.pdf',
        content: pdfDoc
    }
    

    【讨论】:

    • 未捕获错误 { 文件名:未定义,行:NaN,行:NaN,消息:'将循环结构转换为 JSON',类型:'TypeError',堆栈:'TypeError:将循环结构转换为 JSON\ n 在 JSON.stringify ()\n 在 mandrill (C:\\Users\\MITVJADEV011\\Desktop\\react\\manyuBackEnd\\node_modules\\node-mandrill\\mandrill.js:28:39) \n 在 Object.sendMail (C:\\Users\\MITVJADEV011\\Desktop\\react\\manyuBackEnd\\services\\auth.service.js:87:2)
    • 你好@Anil。如果我错了,请纠正我。你在使用带有山魈传输/插件的节点邮件程序吗?我还没有真正测试过该设置,我将这种方法用于开箱即用的节点邮件设置。你介意分享一下你的情况吗?
    • var mandrill = require('node-mandrill')('mykey'); var pdfDoc = 打印机.createPdfKitDocument(docDefinition);pdfDoc.end(); mailData['fileName'] = 'WoorOrderReminder.pdf'; mailData['fileType'] = 'application/pdf' mailData['fileContent'] = pdfDoc;附件:[{ "type": mailData.fileType, "name": mailData.fileName, "content": mailData.fileContent }] 这是我上面的代码错误
    • @Anil 好吧,伙计,第一件事:这个问题和答案是关于 node-mailer 模块的,您使用的是完全不同的 node-mandrill。不用担心,看看你正在使用的模块的自述文件,它说它使用 mandrill api 的开销最小,我看了一点源代码,只是有点 wapper,没有用于处理来自流的文件的实用程序或光盘位置。正如模块所说,您应该阅读官方 mandrill api 文档,其中说附件必须是 base64 字符串内容。个人说明:如果 api 有官方模块,请使用它。是mandrill-api
    • @Anil 也请去 devRant,很高兴有你在那里 :)
    【解决方案2】:

    我能够使用缓冲区使其工作,并在发送带有 PDFMake 附件的电子邮件后结束缓冲区。如果您在发送电子邮件之前结束缓冲区,它将不起作用:

    const printer = new pdfMakePrinter(fontDescriptors);
    const doc = printer.createPdfKitDocument(docDefinition);
    let buffers = [];
    doc.on('data', buffers.push.bind(buffers));
    doc.on('end', () => {
        let pdfData = Buffer.concat(buffers);
    
        let mailOptions = {
            from: '"John Doe" <email@gmail.com>', // sender address
            to: 'receiver@gmail.com', // list of receivers
            subject: 'stuff' // Subject line
            text: '',
            html: '', // html body
            attachments: [{
                filename: 'attachment.pdf',
                content: pdfData
            }]
        };
    
        transporter.sendMail(mailOptions, (error, info) => {
            if (error) {
                return console.log(error);
            }
            console.log('Message sent: %s', info.messageId);
            console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
        });
    
    });
    
    //end buffer
    doc.end();
    

    【讨论】:

      【解决方案3】:

      这就是我所做的。它适用于 Meteor 应用程序。

      客户端:

      var docDefinition = {
          content: [
              'First paragraph'
          ]
      };
      
      var data;
      pdfMake.createPdf(docDefinition).getBase64(function(encodedString) {
          data = encodedString;
          Meteor.call("sendPDFEmail", data);
      });
      

      服务器端

      sendPDFEmail: function(thepdf){
          Email.send({
              to: "receiver",
              from: "sender",
              subject: "Test",
              html: "text",
              attachments: [
                  {
                      filename: "test.pdf",
                      type: "application/pdf",
                      content: Buffer.from(thepdf, 'base64')
                  }
              ]
          });
      },
      

      【讨论】:

        【解决方案4】:
        var pdfMake = require('pdfmake/build/pdfmake.js');
        var pdfFonts = require('pdfmake/build/vfs_fonts.js');
        pdfMake.vfs = pdfFonts.pdfMake.vfs;
        //var base64 = require('base64-js');
        
        var docDefinition = function(json) {
          return {
            content: [
              'PARAGRAPH 1',
              'paragraph 2', {
                columns: [
                  'first column is a simple text', {
                    stack: [
                      // second column consists of paragraphs
                      'paragraph A',
                      'paragraph B',
                      'these paragraphs will be rendered one below another inside the column'
                    ],
                    fontSize: 15
                  }]}]};};
        
        const pdfDocGenerator = pdfMake.createPdf(docDefinition);
        pdfDocGenerator.getBuffer((pdfBuffer) => {
            // HERE YOU HAVE THE PDF BUFFER 
            //var pdfbase64 = base64.fromByteArray(buffer);
            //console.log("pdfDocGenerator.getBuffer OK" + pdfbase64);
            fs.writeFileSync('foo.pdf', buffer);
        }
        

        【讨论】:

        • 点评来源: 您好,请不要只用源代码回答。尝试对您的解决方案如何工作提供一个很好的描述。请参阅:How do I write a good answer?。谢谢
        猜你喜欢
        • 2016-06-13
        • 2020-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 2016-03-30
        • 2016-05-13
        相关资源
        最近更新 更多