从NestJS下载一个文件(不保存)



我想让客户端下载从我的后端生成的pdf文件。我使用pdfkit-lib来生成我的pdf文件。从NestJs文档中,我决定使用DuplexStream中的StreamableFile(pdfkit-lib与WritableStreamStreamableFile一起使用ReadableStream):

@Get('/generate-file')
generateFile(): StreamableFile {
const fileStream = new stream.Duplex();
const doc = new pdfkit()
doc.pipe(fileStream);
// do stuff
doc.end();
return new StreamableFile(fileStream);
}

但是我最终得到了这个错误:

Error: The _write() method is not implemented
at new NodeError (node:internal/errors:371:5)
at Duplex.Writable._write (node:internal/streams/writable:588:11)
at writeOrBuffer (node:internal/streams/writable:389:12)
at _write (node:internal/streams/writable:330:10)
at Duplex.Writable.write (node:internal/streams/writable:334:10)
at PDFDocument.ondata (node:internal/streams/readable:754:22)
at PDFDocument.emit (node:events:390:28)
at PDFDocument.Readable.read (node:internal/streams/readable:527:10)
at flow (node:internal/streams/readable:1012:34)
at resume_ (node:internal/streams/readable:993:3)

它可以使它与fs.createWriteStreamfs.createReadStream一起工作,但我不想在我的服务器上创建文件(并且在StreamableFile上没有回调来删除)。你知道吗?

应该可以做到这一点,而不需要写入临时文件的开销。您可以尝试直接流式传输到res流,如:

@Get('/generate-file')
generateFile(@Res() res: Response): void {
const filename = 'SomeFileName.pdf';
const doc = new PDFDocument({ bufferPages: true });
const stream = res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-disposition': `attachment;filename=${filename}.pdf`,
});
doc.on('data', (chunk) => stream.write(chunk));
doc.on('end', () => stream.end());
doc
.font('Times-Roman')
.fontSize(12)
.text(`just a test`);
doc.end();
}

通过删除创建的文件,我最终使用fs.createWriteStreamfs.createReadStream:

@Get('/generate-file')
generateFile(@Res({ passthrough: true }) res: Response): StreamableFile {
const fileName = '';
const filePath = '';

const doc = new pdfkit()
doc.pipe(fs.createWriteStream(filePath));
// do stuff
doc.end();
const fileStream = fs.createReadStream(filePath);
fileStream.on('end', () => {
try {
fs.unlinkSync(filePath);
} catch (error) {
throw new BadRequestException('An error occurred while removing the file.');
}
});
res.set({
'Content-Type': 'application/pdf',
'Content-Disposition': `attachment; filename="${fileName}"`,
});
return new StreamableFile(fileStream);
}

相关内容

最新更新