在nodejs应用程序中使用PDFKit发送动态创建的PDF作为附件

ASD*_*ASD 4 pdf blob pdfkit node.js nodemailer

我正在尝试使用 PDFkit 动态创建 pdf,并希望将其作为电子邮件中的附件发送。按照这个http://pdfkit.org/demo/browser.html示例和这个https://nodemailer.com/using-attachments/文档,我编写了以下代码:

 var doc = new PDFDocument();
            var stream = doc.pipe(blobStream());
            doc.text("Howdy!!");

            doc.on('end');

            stream.on('finish', function() {

                var htmlMailBody ='Hi' 

                    var textMailBody = 'hi';
                    var mailOptions = 
                    {
                        from: 'ASD', // sender address 
                        to: 'ecell@sfitengg.org', // list of receivers 
                        subject: 'Invitation ', // Subject line 
                        text: textMailBody, // plaintext body alt for html 
                        html: htmlMailBody,
                        attachments:[
                        {

                            filename:"TEST1.pdf",
                            path:stream.toBlobURL('application/pdf')


                        }]
                    };

                    // send mail with defined transport object 
                    transporter.sendMail(mailOptions, function(error, info){
                        if(error){
                            return console.log(error);
                        }
                        console.log('Message sent: ' + info.response);
                        res.redirect('/');
                    });



        });
Run Code Online (Sandbox Code Playgroud)

但我收到以下错误:

 TypeError: listener must be a function
at PDFDocument.addListener (events.js:197:11)
at PDFDocument.Readable.on (_stream_readable.js:665:33)
at exports.getSendReport (d:\projects\PDFChecker\server\controllers\pdf.js:159:6)
at Layer.handle [as handle_request] (d:\projects\PDFChecker\node_modules\express\lib\router\layer.js:95:5)
Run Code Online (Sandbox Code Playgroud)

我该怎么解决呢?

Dan*_*rov 7

不要使用 BlobStream。按照此处的建议写入缓冲区: how to conversion pdfkit object into buffer using nodejs

const pdf = new pdfkit();

const buffers = [];
pdf.on('data', buffers.push.bind(buffers));
pdf.on('end', () => {

    let pdfData = Buffer.concat(buffers);

    const mailOptions = {
        from: '...',
        to: '...',
        attachments: [{
            filename: 'attachment.pdf',
            content: pdfData
        }]
    };

    mailOptions.subject = 'PDF in mail';
    mailOptions.text = 'PDF attached';

    return mailTransport
        .sendMail(mailOptions)
        .then(() => {
            console.log('email sent:');
        })
        .catch(error => {
            console.error('There was an error while sending the email:', error);
        });
});

pdf.text('Hello', 100, 100);
pdf.end();
Run Code Online (Sandbox Code Playgroud)

我使用了这种方法,并且能够使用带有缓冲区 Attachment 的 Nodemailer 并发送正确的 pdf。


Pot*_*mer 7

我发现将 PDFkit 包装成一个更容易逻辑处理的承诺。

const PDFDocument = require('pdfkit');

const pdfBuffer = await new Promise(resolve => {
  const doc = new PDFDocument()

  doc.text('hello world', 100, 50)
  doc.end()

  //Finalize document and convert to buffer array
  let buffers = []
  doc.on("data", buffers.push.bind(buffers))
  doc.on("end", () => {
    let pdfData = new Uint8Array(Buffer.concat(buffers))
    resolve(pdfData)
  })
})

console.log(pdfBuffer) //contains generated pdf, which can return to output
Run Code Online (Sandbox Code Playgroud)


Jas*_*rus 6

实例pdfkit是一个流,您可以简单地将其传递给nodemailer

const doc = new pdfkit();

transport.sendMail({
  from: '...',
  to: '...',
  subject: '...',
  text: '...',
  attachments: [{
    filename: 'attachment.pdf',
    content: doc,
  }],
});
Run Code Online (Sandbox Code Playgroud)