如何创建生成含数据库数据及图表的PDF后端接口?
后端生成带XY图表的PDF接口入门指导
一、核心思路
你之前用iText的PDFPTable只能做表格展示,要实现图表需求,需要搭配图表生成工具和iText整合:要么用第三方图表库生成图片再嵌入PDF,要么直接用iText 7的原生Chart模块(更推荐)。下面是具体入门步骤:
二、技术选型建议
两种可行方案:
- 方案1:JFreeChart(生成图表图片)+ iText(嵌入PDF):适合熟悉传统图表库的开发者
- 方案2:iText 7 Charts模块:原生支持PDF内嵌图表,无需额外图片转换,更轻量化
三、分步实现指南
1. 数据解析处理
数据库返回的profileRollStartDiameter和profileRollStartAdvanceDistance是字符串格式的数组,先转成Java可操作的数值数组:
// 解析Y轴数据(直径) String diameterStr = processData.get("profileRollStartDiameter").toString(); double[] yData = Arrays.stream(diameterStr.replaceAll("[\\[\\]]", "").split(",")) .map(String::trim) .mapToDouble(Double::parseDouble) .toArray(); // 解析X轴数据(进给距离) String distanceStr = processData.get("profileRollStartAdvanceDistance").toString(); double[] xData = Arrays.stream(distanceStr.replaceAll("[\\[\\]]", "").split(",")) .map(String::trim) .mapToDouble(Double::parseDouble) .toArray();
2. 生成XY图表
方案1:JFreeChart生成图表图片
先在Maven中引入依赖:
<dependency> <groupId>org.jfree</groupId> <artifactId>jfreechart</artifactId> <version>1.5.3</version> </dependency>
然后生成折线图(匹配你需要的XY坐标图):
// 创建XY数据集 XYSeries series = new XYSeries("辊型数据"); for (int i = 0; i < xData.length; i++) { series.add(xData[i], yData[i]); } XYSeriesCollection dataset = new XYSeriesCollection(series); // 生成图表 JFreeChart chart = ChartFactory.createXYLineChart( "进给距离 vs 起始直径", "进给距离", "起始直径", dataset, PlotOrientation.VERTICAL, true, // 显示图例 true, // 显示数据提示 false ); // 转为BufferedImage,方便嵌入PDF BufferedImage chartImage = chart.createBufferedImage(600, 400);
方案2:iText 7原生Chart模块(推荐)
引入iText Charts依赖:
<dependency> <groupId>com.itextpdf</groupId> <artifactId>charts</artifactId> <version>7.2.5</version> </dependency>
直接生成PDF内嵌的XY折线图:
// 构建图表数据集 XYChartData chartData = new XYChartData(); XYChartData.Series series = new XYChartData.Series("辊型数据"); for (int i = 0; i < xData.length; i++) { series.add(new XYChartData.XY(xData[i], yData[i])); } chartData.addSeries(series); // 配置图表样式 XYChart chart = new XYChart(chartData, new Rectangle(600, 400)); chart.setTitle(new Paragraph("进给距离 vs 起始直径")); chart.getXAxis().setTitle(new Paragraph("进给距离")); chart.getYAxis().setTitle(new Paragraph("起始直径"));
3. 整合PDF生成
用iText把图表和其他业务数据整合到PDF中:
// 初始化PDF文档,输出到响应流 PdfDocument pdfDoc = new PdfDocument(new PdfWriter(response.getOutputStream())); Document doc = new Document(pdfDoc); // 添加业务文本信息 doc.add(new Paragraph("工序ID: " + processData.get("id_process"))); doc.add(new Paragraph("磨床编号: " + processData.get("tag_rollgrinder"))); doc.add(new Paragraph("辊子编号: " + processData.get("tag_roll"))); doc.add(new Paragraph("开始时间: " + processData.get("datetime_begin"))); doc.add(new Paragraph("结束时间: " + processData.get("datetime_end"))); doc.add(new Paragraph("\n")); // 换行分隔 // 方案1:插入JFreeChart生成的图片 Image chartImg = Image.getInstance(chartImage, null); doc.add(chartImg); // 方案2:插入iText原生图表 // doc.add(chart); // 关闭文档 doc.close();
4. 暴露API接口
在Spring Boot中写接口供Postman测试:
@RestController @RequestMapping("/api/pdf") public class PdfExportController { @GetMapping("/roll-profile") public void generateRollProfilePdf(HttpServletResponse response) throws IOException { // 1. 从数据库查询目标工序数据(这里用模拟数据示例) Map<String, Object> processData = getProcessDataFromDb(); // 2. 执行数据解析、图表生成、PDF整合逻辑(上面的代码) // ... 省略具体实现代码 ... // 设置响应头,让浏览器下载PDF response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "attachment; filename=\"roll_profile.pdf\""); } // 模拟数据库查询 private Map<String, Object> getProcessDataFromDb() { Map<String, Object> data = new HashMap<>(); data.put("id_process", "87"); data.put("final_state", "FINISHED"); data.put("tag_rollgrinder", "LM_170A"); data.put("tag_roll", "LM170A123"); data.put("datetime_begin", "2022-09-30T18:15:00Z"); data.put("datetime_end", "2022-09-30T18:35:00Z"); data.put("profileRollStartDiameter", "[1, 2, 3]"); data.put("profileRollStartAdvanceDistance", "[1, 2, 3]"); return data; } }
四、Postman测试步骤
- 请求方式选择
GET - 输入接口URL:
http://localhost:8080/api/pdf/roll-profile - 在"Headers"中可设置
Accept: application/pdf - 发送请求后,Postman会自动触发PDF文件下载,打开即可查看带图表的内容
内容的提问来源于stack exchange,提问作者Tiago Severo
相关产品推荐
相关产品推荐

