我遇到了一个问题,当我必须将创建的文档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
流解决了这个问题,两个是我通过管道传输 PDFKit
document 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/