node.js - Node PDFKit 管道到多个目标

标签 node.js pdf nodemailer node-streams node-pdfkit

我遇到了一个问题,当我必须将创建的文档pipe() 发送到多个目标时,在我的例子中是 HTTP 响应和使用 node-mailer 的电子邮件附件。在电子邮件附件中首次使用后,没有任何内容通过管道传输到响应(从客户端调用它时,PDF 有 0 字节)。

响应 Controller :

const doc = await createPdf(course.name, lastRecordDate, ctx);   

// Send a notificiation email with attachment
if (query.hasOwnProperty('sendEmail') && query.sendEmail === 'true') {
  await sendNotificationEmail(doc, course, ctx);   
}

doc.pipe(res);
res.contentType('application/pdf');

发送邮件的函数:

async function sendNotificationEmail(doc: any, course: Course, ctx: Context) {
  const attachment = {
    filename: `${course.name}-certificate.pdf`,
    contentType: 'application/pdf',
    content: doc
  };
  return SMTPSendTemplateWithAttachments(
    ctx,
    ['somememail@test.si'],
    `${course.name}`,
    'en-report-created',
    {
      firstName: ctx.user.firstName,
      courseName: course.name
    },
    [attachment]
  );
}

如果我删除发送电子邮件的功能,PDF 通常会通过管道传输到响应,我可以从客户端下载它。

我试图找到一种克隆流的方法(据我所知,PDFKit 的文档是一个流),但没有成功。

任何解决方案都会非常有帮助。

最佳答案

我使用两个 PassThrough 流解决了这个问题,两个是我通过管道传输 PDFKitdocument Stream,然后是 data 事件 我将 chunks 写入两个单独的缓冲区。在 end 事件中,我通过电子邮件发送数据并创建一个新的 PassThrough 流并将其通过管道传输到响应。

这是代码。

// Both PassThrough streams are defined before in order to use them in the createPdf function
streamCopy1 = new PassThrough();
streamCopy2 = new PassThrough();

const buffer1 = [];
const buffer2 = [];

streamCopy1
  .on('data', (chunk) => {
    buffer1.push(chunk);
  })
  .on('end', () => {
    const bufferFinished = Buffer.concat(buffer1);
    if (query.hasOwnProperty('sendEmail') && query.sendEmail === 'true') {
      sendNotificationEmail(bufferFinished, course, ctx);
    }
  });

streamCopy2
  .on('data', (chunk) => {
    buffer2.push(chunk);
  })
  .on('end', () => {
    const bufferFinished = Buffer.concat(buffer2);
    const stream = new PassThrough();
    stream.push(bufferFinished);
    stream.end();
    stream.pipe(res);
    res.contentType('application/pdf');
  });

创建PDF的函数。

// function declaration
const doc = new pdfDocument();
doc.pipe(streamCopy1).pipe(streamCopy2);
// rest of the code

这个解决方案并不是最好的,欢迎任何建议。

关于node.js - Node PDFKit 管道到多个目标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57096070/

相关文章:

javascript - 找不到方法node.js模块

javascript - 如何避免 NodeJs、Express 中的 If else hell

java - 编辑 iText PDF Java

javascript - 使用 Nodemailer 发布 JSON 来发送电子邮件要么发送邮件,但挂起或引发错误

javascript - 解析数据数组并使用 nodemailer 发送?

node.js - 无法使用 SES/Lambda 发送电子邮件,但代码可以在容器上运行

node.js - gulp 在安装 semantic-ui 时找不到 semantic.json

node.js - 使用 Karma 加载 HTML 文件

matlab - 将 PDF 与 Matlab 相结合

node.js - 将 PDF 内容上传到 S3 存储桶