
SpringBoot集成JasperReports实现PDF、HTML、XML的一键生成
JasperReports作为业界主流的开源报表引擎,广泛应用于企业级系统的数据可视化与报表导出场景。结合SpringBoot的自动配置与敏捷开发特性,能够高效构建支持多格式输出的报表服务。本文将系统阐述两者的整合机制与核心代码实现,提供标准化的一键生成解决方案。
一、引入核心依赖
在SpringBoot项目的pom.xml中,需引入JasperReports的基础依赖库,确保报表引擎的正常运转。
<dependency> <groupId>net.sf.jasperreports</groupId> <artifactId>jasperreports</artifactId> <version>6.20.0</version> </dependency>
二、报表生成服务实现
构建统一的报表服务类,负责加载模板、填充数据及格式导出。核心逻辑通过JasperFillManager填充数据生成JasperPrint对象,随后根据请求的目标格式匹配对应的导出器,将结果写入字节流返回。
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.export.HtmlExporter;
import net.sf.jasperreports.engine.export.XmlExporter;
import net.sf.jasperreports.export.*;
import org.springframework.stereotype.Service;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class JasperReportService {
public byte[] generateReport(InputStream templateStream, String format, List dataList) throws JRException {
// 编译报表模板
JasperReport jasperReport = JasperCompileManager.compileReport(templateStream);
// 构建数据源
JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(dataList);
Map<String, Object> parameters = new HashMap<>();
// 填充报表数据
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// 根据格式一键导出
switch (format.toLowerCase()) {
case "pdf":
JasperExportManager.exportReportToPdfStream(jasperPrint, outputStream);
break;
case "html":
HtmlExporter htmlExporter = new HtmlExporter();
htmlExporter.setExporterInput(new SimpleExporterInput(jasperPrint));
htmlExporter.setExporterOutput(new SimpleHtmlExporterOutput(outputStream));
htmlExporter.exportReport();
break;
case "xml":
XmlExporter xmlExporter = new XmlExporter();
xmlExporter.setExporterInput(new SimpleExporterInput(jasperPrint));
xmlExporter.setExporterOutput(new SimpleXmlExporterOutput(outputStream));
xmlExporter.exportReport();
break;
default:
throw new IllegalArgumentException("Unsupported report format: " + format);
}
return outputStream.toByteArray();
}
}三、控制器接口层
在Controller层提供RESTful接口,接收前端的报表生成请求,调用服务层方法并设置相应的HTTP响应头,实现文件流的前端响应与下载。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.io.InputStream;
import java.util.Collections;
@RestController
@RequestMapping("/api/reports")
public class ReportController {
@Autowired
private JasperReportService jasperReportService;
@GetMapping("/{format}")
public ResponseEntity<byte[]> exportReport(@PathVariable String format) {
try {
ClassPathResource resource = new ClassPathResource("templates/report.jrxml");
InputStream templateStream = resource.getInputStream();
byte[] reportBytes = jasperReportService.generateReport(templateStream, format, Collections.emptyList());
HttpHeaders headers = new HttpHeaders();
String fileName = "report." + format;
headers.setContentDispositionFormData("attachment", fileName);
MediaType mediaType = MediaType.APPLICATION_OCTET_STREAM;
if ("pdf".equalsIgnoreCase(format)) {
mediaType = MediaType.APPLICATION_PDF;
} else if ("html".equalsIgnoreCase(format)) {
mediaType = MediaType.TEXT_HTML;
} else if ("xml".equalsIgnoreCase(format)) {
mediaType = MediaType.APPLICATION_XML;
}
return ResponseEntity.ok()
.headers(headers)
.contentType(mediaType)
.body(reportBytes);
} catch (Exception e) {
return ResponseEntity.internalServerError().build();
}
}
}通过上述架构设计,SpringBoot与JasperReports的集成实现了高度解耦。系统在运行时动态解析报表模板,根据前端传入的格式标识,利用策略模式匹配对应的Exporter,实现了PDF、HTML、XML格式的一键导出,满足复杂业务场景下的多维度报表输出需求。