【问题标题】:Node PDFKit pipe to multiple targets节点 PDFKit 管道到多个目标
【发布时间】:2019-11-27 11:32:45
【问题描述】:

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

响应控制器:

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 的文档是一个流),但没有成功。

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

【问题讨论】:

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


    【解决方案1】:

    我使用两个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
    

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

    【讨论】:

      猜你喜欢
      • 2014-07-09
      • 1970-01-01
      • 2019-01-28
      • 1970-01-01
      • 2018-02-14
      • 1970-01-01
      • 1970-01-01
      • 2016-09-01
      • 1970-01-01
      相关资源
      最近更新 更多