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));
额外排查点
- 验证Base64格式:确保传给
doc.image的是完整的Data URL,必须以data:image/png;base64,开头,控制台打印时可以检查前缀是否存在。 - 避免全局变量:全局变量的赋值是异步的,无法保证在
doc.image调用时已经拿到正确值,直接用await或Promise链式调用传递结果更可靠。 - 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
相关产品推荐
相关产品推荐

