React+Node环境下如何将生成的PDF存入数据库并动态获取
解决方案
1. 获取@react-pdf生成的PDF二进制数据
@react-pdf/renderer不止能生成临时BLOB链接,你可以直接获取PDF的原始二进制数据,步骤如下:
- 使用
renderToBlob方法生成Blob对象,再将其转换为可存储的格式(如Base64字符串或ArrayBuffer):
import { Document, Page, renderToBlob } from '@react-pdf/renderer'; // 定义你的PDF文档组件 const AssessmentPDF = ({ data }) => ( <Document> <Page> {/* 你的表格和计算结果内容 */} </Page> </Document> ); // 生成并获取PDF二进制数据 const generateAndGetPDFData = async (patientData) => { const blob = await renderToBlob(<AssessmentPDF data={patientData} />); // 转换为Base64字符串(适合前端传给后端) const reader = new FileReader(); return new Promise((resolve) => { reader.onloadend = () => resolve(reader.result.split(',')[1]); // 去掉data:application/pdf;base64,前缀 reader.readAsDataURL(blob); }); };
2. 将PDF数据存入数据库
- 数据库字段类型选择:根据你使用的数据库,对应设置存储二进制的字段:
- MySQL/MariaDB:
LONGBLOB - PostgreSQL:
BYTEA - MongoDB:
Binary(Buffer.from(base64Data, 'base64'))
- MySQL/MariaDB:
- 后端接收前端传来的Base64数据,转换为二进制后存入数据库:
// 示例Node.js后端(Express + MySQL) app.post('/save-assessment', async (req, res) => { const { patientData, pdfBase64 } = req.body; const pdfBuffer = Buffer.from(pdfBase64, 'base64'); // 存入数据库,假设assessment表有pdf_data字段(LONGBLOB类型) const [result] = await db.query( 'INSERT INTO assessments (patient_data, pdf_data) VALUES (?, ?)', [JSON.stringify(patientData), pdfBuffer] ); res.json({ assessmentId: result.insertId }); });
3. 从数据库读取并打开PDF
- 后端提供接口,根据评估ID返回PDF二进制数据:
app.get('/assessment-pdf/:id', async (req, res) => { const { id } = req.params; const [rows] = await db.query('SELECT pdf_data FROM assessments WHERE id = ?', [id]); if (!rows.length) return res.status(404).send('评估不存在'); const pdfBuffer = rows[0].pdf_data; // 设置响应头,让浏览器直接打开PDF res.setHeader('Content-Type', 'application/pdf'); res.setHeader('Content-Disposition', 'inline; filename="体能评估报告.pdf"'); res.send(pdfBuffer); });
- 前端“追踪您的评估”菜单点击事件:
const openAssessmentPDF = (assessmentId) => { window.open(`/assessment-pdf/${assessmentId}`, '_blank'); };
注意事项
- 如果PDF文件较大,Base64会增加30%左右的体积,建议前端直接用FormData传Blob对象给后端,更高效:
// 前端修改生成数据的逻辑 const generateAndSendPDF = async (patientData) => { const blob = await renderToBlob(<AssessmentPDF data={patientData} />); const formData = new FormData(); formData.append('patientData', JSON.stringify(patientData)); formData.append('pdfFile', blob, 'assessment.pdf'); // 用fetch发送FormData const res = await fetch('/save-assessment', { method: 'POST', body: formData }); const { assessmentId } = await res.json(); // 跳转主页等逻辑 };
- 后端接收FormData时,用
multer等中间件处理文件:
const multer = require('multer'); const upload = multer({ storage: multer.memoryStorage() }); app.post('/save-assessment', upload.single('pdfFile'), async (req, res) => { const patientData = JSON.parse(req.body.patientData); const pdfBuffer = req.file.buffer; // 存入数据库逻辑同上 });
内容的提问来源于stack exchange,提问作者Vitor CP
相关产品推荐
相关产品推荐

