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

pdfkit插入QRCode.toDataURL生成的Base64图片为空问题求助

问题分析与解决方案

核心问题是异步操作的时序错误:你调用QRCode.toDataURL生成二维码是异步的,但可能在二维码还没生成完成时就已经结束了PDF文档流,或者提前执行了doc.image导致传入的是未就绪的数据。

错误原因示例

你之前的代码大概率是类似这样的时序错误:

const QRCode = require('qrcode');
const PDFDocument = require('pdfkit');
const fs = require('fs');

const doc = new PDFDocument();
doc.pipe(fs.createWriteStream('output.pdf'));

// 异步生成二维码,但后续代码不等它完成就执行
QRCode.toDataURL('12345')
  .then(url => {
    console.log(url);
    doc.image(url, 50, 50); // 此时PDF流可能已经关闭
  });

doc.end(); // 这里先执行,直接结束了PDF,后续的image无法写入

正确的处理方式

用async/await来确保异步操作完成后再执行后续步骤,这是最直观的写法:

const QRCode = require('qrcode');
const PDFDocument = require('pdfkit');
const fs = require('fs');

async function generatePDF() {
  const doc = new PDFDocument();
  const outputStream = fs.createWriteStream('output.pdf');
  doc.pipe(outputStream);

  // 等待二维码生成完成,拿到正确的Base64 URL
  const qrBase64Url = await QRCode.toDataURL('12345');
  console.log(qrBase64Url);

  // 此时插入图片才有效,可指定宽高确保显示正常
  doc.image(qrBase64Url, 50, 50, { width: 100 });

  // 所有内容添加完成后,再结束文档流
  doc.end();

  // 可选:等待文件写入完成后提示
  await new Promise(resolve => outputStream.on('finish', resolve));
  console.log('PDF生成成功');
}

// 执行并捕获错误
generatePDF().catch(err => console.error('生成失败:', err));

额外排查点

  1. 验证Base64格式:确保传给doc.image的是完整的Data URL,必须以data:image/png;base64,开头,控制台打印时可以检查前缀是否存在。
  2. 避免全局变量:全局变量的赋值是异步的,无法保证在doc.image调用时已经拿到正确值,直接用await或Promise链式调用传递结果更可靠。
  3. Promise链式调用写法:如果不想用async/await,也可以把doc.end()放在Promise的最后一个then里:
QRCode.toDataURL('12345')
  .then(url => {
    doc.image(url, 50, 50);
    doc.end();
  })
  .catch(err => {
    console.error(err);
    doc.end(); // 出错也要结束文档,避免流挂起
  });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:28:24