You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:49:45