如何在Node.js中使用pdfkit将MongoDB查询数据打印到PDF
如何将MongoDB查询数据通过PDFKit生成PDF
你的问题核心是异步逻辑顺序错了——现在你的pdf函数里,查询数据库和生成PDF的代码是并行执行的,PDF生成时数据还没从数据库查出来,自然没法把数据写入进去。咱们把逻辑调整一下,等数据拿到手再生成PDF内容就行。
具体修改步骤
- 把PDF生成逻辑移到查询成功的回调里:确保只有当数据库返回数据后,才开始构建PDF内容
- 调用查询到的数据字段:从返回的
r数组里取出对应的district、_division等值,插入到PDF文本中 - 处理空数据情况:如果查询结果为空,在PDF里提示或者跳过相关内容,避免报错
- 可选:直接把PDF返回给前端:如果不想只保存到服务器本地,也可以把PDF流直接pipe到response,让用户下载
修改后的完整代码
function pdf(req,res){ var pdf = require('pdfkit'); var fs = require('fs'); var query = req.body; // 先查询数据库,等数据返回后再生成PDF FormRecord.find(query).exec().then((r)=> { if(r.length === 0){ // 处理无数据的情况 res.send({'status':false, message: 'No data found'}); return; } // 拿到数据后初始化PDF文档 var doc = new pdf; // 选项1:保存到服务器本地文件 doc.pipe(fs.createWriteStream('node5.pdf')); // 选项2:直接返回给前端让用户下载(注释掉上面一行,打开下面两行) // res.setHeader('Content-Type', 'application/pdf'); // res.setHeader('Content-Disposition', 'attachment; filename="node5.pdf"'); // doc.pipe(res); // 开始写入PDF内容,使用查询到的数据 var loremIpsum = ' MEMO'; doc.fillColor('black') doc.font('Helvetica-Bold').text(loremIpsum, { paragraphGap: 30, indent: 20, align: 'center', underline: true }); doc.moveDown() doc.text(`1. District: ${r[0].district}`,{ width: 550, indent: 20, align: 'left' }); doc.moveDown() doc.text(`2. Division: ${r[0]._division}`,{ width: 410, indent: 20, align: 'left' }); // 如果有更多字段,继续添加即可,比如格式化后的创建时间 doc.moveDown() doc.text(`3. Created At: ${new Date(r[0].createdAt).toLocaleString()}`,{ width: 410, indent: 20, align: 'left' }); doc.end(); // 如果是保存到本地,返回成功状态;如果是pipe到res,这行可以去掉 res.send({ 'status' : true, message: 'PDF generated successfully'}); }).catch((e) => { console.error('Error querying data:', e); res.send({'status':false, message: 'Failed to query data'}); }); }
关键改动说明
- 把PDF的初始化和内容生成全部放到了
then回调里,确保数据r已经成功获取 - 用模板字符串
${}把查询到的字段值插入到文本中,比如${r[0].district} - 增加了无数据的判断,避免因为
r[0]不存在而抛出错误 - 提供了两种PDF输出方式,你可以根据业务需求选择保存到本地或者直接返回给前端
这样修改后,生成的PDF里就会显示从MongoDB查询到的district、division等数据啦。
内容的提问来源于stack exchange,提问作者Wanderer
相关产品推荐
相关产品推荐

