点击上方“程序员蜗牛g”,选择“设为星标”
跟蜗牛哥一起,每天进步一点点
程序员蜗牛g
大厂程序员一枚 跟蜗牛一起 每天进步一点点
33篇原创内容
**
公众号
本文将完整演示如何在 Spring Boot 项目中整合 JasperReports,从环境配置、模板设计到接口开发,逐步实现用户数据报表的导出。
集成 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;
@SpringBootApplicationpublic 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: 8080spring: application: name: springboot-jasperreport-demo
jasperreports.properties
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactorynet.sf.jasperreports.extension.simple.font.families.simhei=fonts/fonts.xml
首先,在 Linux 系统中,将 Windows 的 黑体字体文件 simhei.ttf 拷贝到项目目录:
src/main/resources/fonts/simhei.ttf
fonts/fonts.xml
* * * * * * * * * * * * * * *
<?xml version="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 version="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 的多格式一键导出。整个过程涵盖了 依赖引入、字体配置、模板设计、数据填充、接口实现 等关键环节。
如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。
关注公众号:woniuxgg,在公众号中回复:笔记 就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!