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

Node.js+PDFKit从Firebase生成PDF时写入图片遇stream.push() after EOF错误

解决PDF生成时的stream.push() after EOF错误(Firebase图片写入问题)

我帮你分析下这个问题哈,你遇到的Error: stream.push() after EOF本质是PDF文档的输出流已经关闭,但还有图片写入操作在尝试向流中推送数据,所以触发了这个错误。核心问题是你的代码里异步操作没有被正确等待,导致PDF生成流程和图片请求/写入的节奏乱了。

问题出在哪?

你的代码里有两个关键的异步坑:

  • forEach遍历Firebase的querySnapshot时,forEach本身不支持异步等待,里面的axios.get是异步任务,循环会直接走完,完全不等图片请求和写入完成;
  • axios.get用了.then回调但没配合await,导致图片数据还没拿到,后续的PDF操作甚至可能已经把文档流关闭了,这时候再执行pdf_doc.image()就会往已经关闭的流里写数据,触发EOF错误。

解决方案

调整代码的异步逻辑,确保所有异步操作都按顺序完成后再继续PDF的生成流程:

  1. 把forEach换成for...of循环,因为for...of支持异步等待,能保证每一个文档的处理都完成后再处理下一个;
  2. 对axios.get请求添加await,确保图片数据完全获取后再写入PDF;
  3. 把所有嵌套的.then回调改成await写法,让代码的执行顺序更清晰。

修改后的代码示例

// 主函数
async function getPDF() {
  // ... 其他代码 ...

  // 处理Firebase数据和图片写入的部分
  const querySnapshot = await questionNumber.get();
  let i = 0;
  // 用for...of替代forEach,支持异步等待
  for (const doc of querySnapshot.docs) {
    i++;
    const exteriorQuestionsData = doc.data();
    const exteriorImages = extFormDataAnswers[i-11]?.exteriorQuestionsImages;
    // 先判断数组是否存在且不为空
    if (exteriorImages && exteriorImages.length > 0) {
      // 遍历图片数组,同样用for...of保证顺序
      for (const imgItem of exteriorImages) {
        const img_url = imgItem.uri;
        // await等待图片请求完成
        const response = await axios.get(img_url, { responseType: 'arraybuffer' });
        const my_img = Buffer.from(response.data);
        // 图片写入PDF的操作要在await之后,确保数据已就绪
        pdf_doc.image(my_img, { fit: [300, 300] })
          .fontSize(18)
          .fillColor('#426998')
          .font('Helvetica-Bold')
          .moveDown(0.2)
          .lineWidth(0.5);
      }
    }
  }

  // ... 后续的PDF生成/保存代码 ...
}

额外说明

  • 我还优化了图片数组的判断逻辑,用?.可选链和length > 0替代原来的!= undefined || != [](原来的判断有逻辑问题,!= []永远为true);
  • 所有异步操作都用await包裹后,能保证PDF的写入操作是严格按顺序执行的,不会出现“流已经关闭但还在写数据”的情况。

内容的提问来源于stack exchange,提问作者Vipin Raj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:28:17