Node.js使用PDFMake生成PDF后下载无法打开问题求助
问题分析与解决方案
我帮你排查下这个PDF无法打开的问题——核心原因是文件还没完全写入磁盘,你就触发了下载操作,导致拿到的是不完整的损坏文件。
为什么会出问题?
你的代码里,fs.createWriteStream('name.pdf') 是异步写入本地文件的操作,pdfDoc.end() 只是标记PDF生成逻辑结束,但实际文件内容写入磁盘还需要一点时间。这时候立刻调用 res.download('name.pdf'),下载的是一个还在写入中的半成品文件,自然会提示"Failed to load PDF document."。
两种可行的修复方案
方案一:监听文件写入完成事件后再下载
通过监听写入流的finish事件,确保文件完全写入后再触发下载,还可以在下载完成后清理临时文件:
var docDefinition = { content: 'test' }; var pdfDoc = printer.createPdfKitDocument(docDefinition); const writeStream = fs.createWriteStream('name.pdf'); pdfDoc.pipe(writeStream); pdfDoc.end(); // 等待文件写入完成后再执行下载 writeStream.on('finish', () => { res.download('name.pdf', (err) => { // 下载完成后删除本地临时文件(可选,避免磁盘占用) if (!err) { fs.unlinkSync('name.pdf'); } }); });
方案二:直接将PDF流输出到响应(更推荐)
跳过本地文件写入步骤,直接把PDF生成的流pipe到响应对象,既高效又避免异步问题:
var docDefinition = { content: 'test' }; var pdfDoc = printer.createPdfKitDocument(docDefinition); // 设置响应头,告诉浏览器这是可下载的PDF文件 res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'attachment; filename="name.pdf"'); // 直接将PDF流传递给客户端 pdfDoc.pipe(res); pdfDoc.end();
方案二更适合Web服务场景,省去了服务器本地IO操作,也不会留下临时文件,是更优的实践方式。
内容的提问来源于stack exchange,提问作者Jerrold
相关产品推荐
相关产品推荐

