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

NodeJS+Express+PDFKit+node-qrcode生成PDF时二维码无法显示

问题根因

二维码无法显示是异步执行顺序错误导致的:

  • QRCode.toDataURL 是异步方法,传入的回调函数会在二维码Base64数据生成完成后才触发执行
  • 原有代码在调用QRCode.toDataURL后立刻执行了doc.end(),此时二维码还未生成完成,doc.image()插入图片的逻辑还没运行,PDF文档就已经被关闭写入,自然不会显示二维码
  • doc.text()、doc.circle()都是同步执行的API,会在doc.end()调用前完成渲染,因此可以正常显示在PDF中
修复方案

方案1:将文档关闭逻辑移到二维码生成回调内

确保二维码成功插入PDF后,再结束文档流,修正后的核心代码如下:

const doc = new PDFDocument({
  margin: 0,
  size: 'LETTER'
})

doc.pipe(fs.createWriteStream('/files/result.pdf'))
doc.pipe(res)

const opts = {
  errorCorrectionLevel: 'H',
  type: 'image/png',
  quality: 0.9,
  margin: 1,
  color: {
    dark:"#000000",
    light:"#FFFFFF"
  }
}

QRCode.toDataURL('http://link.to.website', function (err, url) {
  if (err) throw err
  doc.image(url, 50, 45, { width: 50 })
  // 所有内容绘制完成后再关闭PDF
  doc.end()
})

方案2:用async/await改写为顺序执行逻辑

如果后续还有其他异步插入的内容,可以把二维码生成方法包装为Promise,用async/await控制执行顺序,避免回调嵌套:

// 包装二维码生成方法为Promise
const getQRCodeDataURL = (content, options) => {
  return new Promise((resolve, reject) => {
    QRCode.toDataURL(content, options, (err, dataUrl) => {
      if (err) return reject(err)
      resolve(dataUrl)
    })
  })
}

// PDF生成主逻辑
const createPDF = async () => {
  const doc = new PDFDocument({
    margin: 0,
    size: 'LETTER'
  })
  doc.pipe(fs.createWriteStream('/files/result.pdf'))
  doc.pipe(res)

  const qrOptions = {
    errorCorrectionLevel: 'H',
    type: 'image/png',
    quality: 0.9,
    margin: 1,
    color: {
      dark:"#000000",
      light:"#FFFFFF"
    }
  }

  // 等待二维码生成完成后再插入PDF
  const qrDataUrl = await getQRCodeDataURL('http://link.to.website', qrOptions)
  doc.image(qrDataUrl, 50, 45, { width: 50 })

  // 所有内容绘制完毕后关闭文档
  doc.end()
}

createPDF()

提示:所有异步往PDF插入内容的操作(比如加载网络图片、读取本地文件),都需要等待操作完成、内容成功绘制到文档后,再调用doc.end(),否则都会出现对应内容丢失的问题。

内容的提问来源于stack exchange,提问作者Eirik Madland

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 10:09:46