React-PDF与CockroachDB集成:从CockroachDB生成PDF
React-PDF与CockroachDB集成:从CockroachDB生成PDF
【免费下载链接】react-pdf 📄 Create PDF files using React 项目地址: https://gitcode.com/gh_mirrors/re/react-pdf
在现代Web应用开发中,将数据库数据转化为PDF文档是常见需求。本文将介绍如何结合React-PDF和CockroachDB,实现从CockroachDB数据库提取数据并生成专业PDF文档的完整流程。
技术栈概述
React-PDF是一个基于React的PDF生成库,允许开发者使用熟悉的JSX语法创建PDF文档。CockroachDB则是一个分布式SQL数据库,提供强一致性和高可用性。两者结合可构建可靠的PDF生成系统。
React-PDF核心组件包括:
<Document>:PDF文档容器<Page>:页面组件- 基础排版组件:
<Text>、<View>、<Image>等 - 样式系统:StyleSheet
CockroachDB提供:
- 分布式SQL能力
- 强一致性事务
- 与PostgreSQL兼容的API
集成架构设计
以下是React-PDF与CockroachDB集成的基本架构:
集成流程主要包含三个步骤:
- 从CockroachDB查询数据
- 使用React-PDF创建PDF模板
- 渲染并输出PDF文档
环境准备
首先确保安装必要的依赖:
# 安装React-PDF核心包
npm install @react-pdf/renderer
# 安装CockroachDB客户端
npm install pg
项目结构建议:
src/
├── db/
│ └── cockroach.js # 数据库连接配置
├── pdf/
│ ├── templates/ # PDF模板组件
│ └── generator.js # PDF生成逻辑
└── server.js # 后端服务入口
数据库连接配置
创建CockroachDB连接配置文件db/cockroach.js:
const { Pool } = require('pg');
// CockroachDB连接配置
const pool = new Pool({
user: 'your-user',
host: 'your-cockroachdb-host',
database: 'your-db',
password: 'your-password',
port: 26257,
ssl: {
rejectUnauthorized: false // 生产环境需配置CA证书
}
});
// 测试连接
pool.query('SELECT NOW()', (err, res) => {
if (err) {
console.error('CockroachDB连接失败:', err.stack);
} else {
console.log('CockroachDB连接成功:', res.rows[0].now);
}
});
module.exports = pool;
创建PDF模板
使用React-PDF创建一个基本的PDF模板pdf/templates/invoice.js:
import React from 'react';
import { Document, Page, Text, View, StyleSheet } from '@react-pdf/renderer';
// 创建样式表
const styles = StyleSheet.create({
page: {
padding: 30,
},
title: {
fontSize: 24,
marginBottom: 20,
textAlign: 'center',
},
section: {
marginBottom: 15,
},
table: {
display: 'table',
width: '100%',
borderStyle: 'solid',
borderWidth: 1,
borderRightWidth: 0,
borderBottomWidth: 0,
},
tableRow: {
flexDirection: 'row',
},
tableCell: {
width: '25%',
borderStyle: 'solid',
borderWidth: 1,
borderLeftWidth: 0,
borderTopWidth: 0,
padding: 5,
},
});
// PDF文档组件
const InvoiceTemplate = ({ data }) => (
<Document>
<Page size="A4" style={styles.page}>
<Text style={styles.title}>发票 #{data.invoiceNumber}</Text>
<View style={styles.section}>
<Text>客户: {data.customer.name}</Text>
<Text>日期: {new Date(data.date).toLocaleDateString()}</Text>
</View>
<View style={styles.table}>
<View style={styles.tableRow}>
<Text style={styles.tableCell}>产品</Text>
<Text style={styles.tableCell}>数量</Text>
<Text style={styles.tableCell}>单价</Text>
<Text style={styles.tableCell}>金额</Text>
</View>
{data.items.map((item, index) => (
<View style={styles.tableRow} key={index}>
<Text style={styles.tableCell}>{item.name}</Text>
<Text style={styles.tableCell}>{item.quantity}</Text>
<Text style={styles.tableCell}>${item.price.toFixed(2)}</Text>
<Text style={styles.tableCell}>${(item.quantity * item.price).toFixed(2)}</Text>
</View>
))}
</View>
<View style={styles.section}>
<Text>总计: ${data.total.toFixed(2)}</Text>
</View>
</Page>
</Document>
);
export default InvoiceTemplate;
实现PDF生成服务
创建PDF生成服务pdf/generator.js:
const { renderToFile } = require('@react-pdf/renderer');
const fs = require('fs');
const path = require('path');
const pool = require('../db/cockroach');
const InvoiceTemplate = require('./templates/invoice');
// 从CockroachDB获取发票数据
async function getInvoiceData(invoiceId) {
const query = `
SELECT i.*, c.name as customer_name, c.email as customer_email,
json_agg(json_build_object(
'name', p.name,
'quantity', ii.quantity,
'price', ii.price
)) as items,
SUM(ii.quantity * ii.price) as total
FROM invoices i
JOIN customers c ON i.customer_id = c.id
JOIN invoice_items ii ON i.id = ii.invoice_id
JOIN products p ON ii.product_id = p.id
WHERE i.id = $1
GROUP BY i.id, c.name, c.email
`;
const result = await pool.query(query, [invoiceId]);
return result.rows[0];
}
// 生成PDF发票
async function generateInvoicePDF(invoiceId, outputPath) {
try {
// 1. 从CockroachDB获取数据
const invoiceData = await getInvoiceData(invoiceId);
if (!invoiceData) {
throw new Error(`未找到ID为${invoiceId}的发票`);
}
// 2. 格式化数据
const formattedData = {
invoiceNumber: invoiceData.invoice_number,
date: invoiceData.invoice_date,
customer: {
name: invoiceData.customer_name,
email: invoiceData.customer_email
},
items: invoiceData.items,
total: parseFloat(invoiceData.total)
};
// 3. 使用React-PDF渲染PDF
await renderToFile(
<InvoiceTemplate data={formattedData} />,
outputPath
);
console.log(`PDF生成成功: ${outputPath}`);
return outputPath;
} catch (error) {
console.error('PDF生成失败:', error);
throw error;
}
}
module.exports = { generateInvoicePDF };
创建API接口
在server.js中创建API接口:
const express = require('express');
const fs = require('fs');
const path = require('path');
const { generateInvoicePDF } = require('./pdf/generator');
const app = express();
const PORT = process.env.PORT || 3000;
const PDF_OUTPUT_DIR = path.join(__dirname, '..', 'pdfs');
// 确保PDF输出目录存在
if (!fs.existsSync(PDF_OUTPUT_DIR)) {
fs.mkdirSync(PDF_OUTPUT_DIR);
}
// 生成发票PDF的API接口
app.get('/api/invoices/:id/pdf', async (req, res) => {
try {
const invoiceId = req.params.id;
const outputPath = path.join(PDF_OUTPUT_DIR, `invoice-${invoiceId}.pdf`);
// 生成PDF
await generateInvoicePDF(invoiceId, outputPath);
// 返回PDF文件
res.download(outputPath, `invoice-${invoiceId}.pdf`, (err) => {
if (err) {
console.error('文件下载错误:', err);
}
// 可选:删除临时文件
// fs.unlinkSync(outputPath);
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(PORT, () => {
console.log(`服务器运行在 http://localhost:${PORT}`);
});
性能优化策略
对于大规模PDF生成,考虑以下优化策略:
-
数据库查询优化:
- 为常用查询创建适当索引
- 使用
LIMIT分页处理大量数据 - 考虑使用CockroachDB的分布式查询优化
-
PDF渲染优化:
- 使用流式渲染(renderToStream)处理大型文档
- 避免在PDF中使用过多高分辨率图片
- 考虑使用缓存机制存储重复使用的PDF片段
-
并发处理:
- 使用任务队列(如Bull)管理PDF生成任务
- 限制同时渲染的PDF数量,避免资源耗尽
部署与扩展
在生产环境部署时需考虑:
-
CockroachDB集群配置:
- 确保适当的副本数量
- 配置自动负载均衡
- 设置数据备份策略
-
应用扩展:
- 考虑使用容器化部署(Docker + Kubernetes)
- 实现无状态服务设计,便于水平扩展
- 使用共享存储或对象存储保存生成的PDF
-
监控与日志:
- 监控数据库连接池状态
- 记录PDF生成性能指标
- 设置错误报警机制
完整示例与演示
以下是使用Postman测试API的示例截图:
API测试截图
成功生成的PDF文档示例:
PDF示例截图
总结与最佳实践
React-PDF与CockroachDB的集成提供了强大而灵活的PDF生成解决方案。关键最佳实践包括:
- 分离关注点:将数据获取、模板设计和PDF渲染分离
- 错误处理:全面处理数据库错误和PDF渲染异常
- 安全性:保护数据库凭证,验证所有用户输入
- 测试:为PDF模板和数据处理逻辑编写单元测试
- 文档:维护清晰的API文档和模板说明
通过这种架构,您可以构建可靠、可扩展的PDF生成系统,满足从简单报表到复杂文档的各种需求。
要了解更多细节,请参考:
【免费下载链接】react-pdf 📄 Create PDF files using React 项目地址: https://gitcode.com/gh_mirrors/re/react-pdf
更多推荐



所有评论(0)