SpringBoot集成JasperReports实现PDF、HTML、XML的一键生成
作者:程序员蜗牛
本文详解SpringBoot集成JasperReports流程,包含依赖配置、字体处理、模板设计、数据填充及接口开发,实现用户数据多格式(PDF/HTML/XML)报表导出,覆盖项目结构搭建与测试访问地址
JasperReports 是一个基于 Java 的开源报表工具,支持多种输出格式(如 PDF、HTML、XML 等),广泛应用于 Java 开发中生成动态报表。本文将完整演示如何在 Spring Boot 项目中整合 JasperReports,从环境配置、模板设计到接口开发,逐步实现用户数据报表的导出。
核心原理
工作流程
- JRXML:XML 格式的报表模板文件,通过设计器(如 Jaspersoft Studio)创建。
- Jasper:编译 JRXML 生成的二进制文件,用于数据填充。
- Jrprint:填充数据后的报表对象,最终通过导出器生成目标格式文件。
技术特点
- 支持多种数据源(JDBC、JavaBeans、XML 等)。
- 可生成带水印的报表和子报表。
集成JasperReports步骤
项目目录结构
引入依赖
在 pom.xml
中添加 JasperReports 相关依赖:
<dependencies> <!-- JasperReports 核心依赖 --> <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>7.0.3</version> </dependency> <!-- JasperReports PDF 支持 --> <dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports-pdf</artifactId> <version>7.0.3</version> </dependency> <!-- Spring Boot Web --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- Lombok 简化实体类代码 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>
核心代码实现
启动类
package com.icoderoad; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringbootJasperreportApplication { public static void main(String[] args) { SpringApplication.run(SpringbootJasperreportApplication.class, args); } }
User 实体类
package com.icoderoad.entity; public class User { private Long id; private String name; private Integer age; private String email; private String address; public User(Long id, String name, Integer age, String email, String address) { this.id = id; this.name = name; this.age = age; this.email = email; this.address = address; } public User() {} // Getter 和 Setter public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
报表生成工具类
package com.icoderoad.report; import com.icoderoad.entity.User; import net.sf.jasperreports.engine.*; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import org.springframework.core.io.ClassPathResource; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; public class ReportGenerator { public static byte[] generate(List<User> users, String format) throws Exception { // 1. 加载并编译报表模板 ClassPathResource resource = new ClassPathResource("templates/user.jrxml"); JasperReport jasperReport = JasperCompileManager.compileReport(resource.getInputStream()); // 2. 准备数据源和参数 JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(users); Map<String, Object> parameters = new HashMap<>(); parameters.put("title", "用户列表"); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource); // 3. 导出不同格式 return switch (format) { case "pdf" -> JasperExportManager.exportReportToPdf(jasperPrint); case "xml" -> JasperExportManager.exportReportToXml(jasperPrint).getBytes(); case "html" -> { String path = "/tmp/user.html"; JasperExportManager.exportReportToHtmlFile(jasperPrint, path); yield Files.readAllBytes(Paths.get(path)); } default -> throw new IllegalArgumentException("不支持的格式: " + format); }; } }
控制层
package com.icoderoad.controller; import com.icoderoad.entity.User; import com.icoderoad.report.ReportGenerator; import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.Resource; import org.springframework.http.*; import org.springframework.web.bind.annotation.*; import java.util.*; @RestController @RequestMapping("/users") public class ReportController { @GetMapping("/export/{format}") public ResponseEntity<Resource> export(@PathVariable String format) throws Exception { // 模拟数据 List<User> users = new ArrayList<>(); for (int i = 0; i < 10; i++) { users.add(new User((long) i, "姓名-" + i, new Random().nextInt(100), i + "@qq.com", "地址-" + i)); } // 生成报表 byte[] content = ReportGenerator.generate(users, format); ByteArrayResource resource = new ByteArrayResource(content); return ResponseEntity.ok() .contentType(MediaType.APPLICATION_OCTET_STREAM) .header(HttpHeaders.CONTENT_DISPOSITION, ContentDisposition.attachment() .filename("user-report." + format) .build().toString()) .contentLength(resource.contentLength()) .body(resource); } }
配置文件
server: port: 8080 spring: application: name: springboot-jasperreport-demo
jasperreports.properties
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory net.sf.jasperreports.extension.simple.font.families.simhei=fonts/fonts.xml
首先,在 Linux 系统中,将 Windows 的 黑体字体文件 simhei.ttf
拷贝到项目目录:
src/main/resources/fonts/simhei.ttf
fonts/fonts.xml
<?xml versinotallow="1.0" encoding="UTF-8"?> <fontFamilies> <fontFamily name="黑体"> <normal>fonts/simhei.ttf</normal> <bold>fonts/simhei.ttf</bold> <italic>fonts/simhei.ttf</italic> <boldItalic>fonts/simhei.ttf</boldItalic> <pdfEncoding>Identity-H</pdfEncoding> <pdfEmbedded>true</pdfEmbedded> <exportFonts> <export key="net.sf.jasperreports.html">'黑体', Arial, Helvetica, sans-serif</export> <export key="net.sf.jasperreports.xhtml">'黑体', Arial, Helvetica, sans-serif</export> </exportFonts> </fontFamily> </fontFamilies>
user.jrxml 示例模板
<?xml versinotallow="1.0" encoding="UTF-8"?> <!-- 用户列表报表模板 --> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="user_report" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="123e4567-e89b-12d3-a456-426614174000"> <!-- 报表参数 --> <parameter name="title" class="java.lang.String"/> <!-- 字段定义 --> <field name="id" class="java.lang.Long"/> <field name="name" class="java.lang.String"/> <field name="age" class="java.lang.Integer"/> <field name="email" class="java.lang.String"/> <field name="address" class="java.lang.String"/> <!-- 报表标题 --> <title> <band height="50"> <staticText> <reportElement x="0" y="10" width="555" height="30"/> <textElement textAlignment="Center"> <font fontName="黑体" size="16" isBold="true"/> </textElement> <text><![CDATA[$P{title}]]></text> </staticText> </band> </title> <!-- 表头 --> <columnHeader> <band height="20"> <staticText><reportElement x="0" y="0" width="50" height="20"/><text><![CDATA[ID]]></text></staticText> <staticText><reportElement x="50" y="0" width="100" height="20"/><text><![CDATA[姓名]]></text></staticText> <staticText><reportElement x="150" y="0" width="50" height="20"/><text><![CDATA[年龄]]></text></staticText> <staticText><reportElement x="200" y="0" width="150" height="20"/><text><![CDATA[邮箱]]></text></staticText> <staticText><reportElement x="350" y="0" width="205" height="20"/><text><![CDATA[地址]]></text></staticText> </band> </columnHeader> <!-- 数据体 --> <detail> <band height="20"> <textField><reportElement x="0" y="0" width="50" height="20"/><textFieldExpression><![CDATA[$F{id}]]></textFieldExpression></textField> <textField><reportElement x="50" y="0" width="100" height="20"/><textFieldExpression><![CDATA[$F{name}]]></textFieldExpression></textField> <textField><reportElement x="150" y="0" width="50" height="20"/><textFieldExpression><![CDATA[$F{age}]]></textFieldExpression></textField> <textField><reportElement x="200" y="0" width="150" height="20"/><textFieldExpression><![CDATA[$F{email}]]></textFieldExpression></textField> <textField><reportElement x="350" y="0" width="205" height="20"/><textFieldExpression><![CDATA[$F{address}]]></textFieldExpression></textField> </band> </detail> </jasperReport>
测试接口
启动服务后,分别访问以下地址即可获取不同格式的报表:
- PDF 报表:http://localhost:8080/users/export/pdf
- XML 报表:http://localhost:8080/users/export/xml
- HTML 报表:http://localhost:8080/users/export/html
结论
通过本文的实践,我们基于 Spring Boot + JasperReports 搭建了一套完整的报表生成解决方案,实现了 PDF、HTML、XML 的多格式一键导出。整个过程涵盖了 依赖引入、字体配置、模板设计、数据填充、接口实现 等关键环节。
到此这篇关于SpringBoot集成JasperReports实现PDF、HTML、XML的一键生成的文章就介绍到这了,更多相关Java实现PDF、HTML、XML一键生成内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!