如何在 NodeMailer 的附件邮件选项中使用 PDFMake 的 pdf 输出?

How to use pdf output of PDFMake in the attachment mail options of NodeMailer?

这是 PDFMake 的代码片段之一 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 管道和流功能,但无法理解它们以满足我的要求。我觉得应该可以通过stream和pipe实现,但是不知道怎么实现。

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

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

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

然后:

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

这是我所做的。它适用于 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')
            }
        ]
    });
},
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);
}

我能够使用缓冲区让它工作,并在从 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();