SpringReport API接口:二次开发集成指南
概述
SpringReport作为一款企业级开源报表系统,提供了丰富的API接口体系,支持深度二次开发和系统集成。本文将详细介绍SpringReport的API架构、核心接口功能、集成方案以及最佳实践,帮助开发者快速实现系统集成和定制化开发。
API架构设计
SpringReport采用RESTful API设计风格,基于Spring Boot框架构建,提供统一的API网关和权限控制机制。
基础API结构
核心API模块
| 模块分类 | 主要功能 | 接口前缀 |
|---|---|---|
| 报表模板管理 | 模板CRUD、设计、预览 | /springReport/api/reportTpl |
| 数据源管理 | 数据源配置、连接测试 | /springReport/api/reportDatasource |
| 用户权限管理 | 用户、角色、菜单管理 | /springReport/api/sys* |
| 协同编辑 | 多人协同操作 | /springReport/api/coedit |
| 报表填报 | 数据上报功能 | /springReport/api/reportForms |
核心API接口详解
1. 报表模板管理接口
获取报表列表
@RequestMapping(value = "/getTableList", method = RequestMethod.POST)
public Response getTableList(@RequestBody ReportTpl model)
- 功能:分页查询报表模板列表
- 参数:ReportTpl对象(包含分页和查询条件)
- 返回:分页结果集
获取模板详情
@RequestMapping(value = "/getDetail", method = RequestMethod.GET)
public Response getDetail(@RequestParam Long id)
- 功能:根据ID获取模板详细信息
- 权限:需要
reportTpl_getDetail权限 - 返回:完整的模板配置信息
保存模板设计
@RequestMapping(value = "/saveLuckySheetTpl", method = RequestMethod.POST)
public Response saveLuckySheetTpl(@RequestBody MesLuckysheetsTplDto mesLuckysheetsTplDto)
- 功能:保存Luckysheet模板设计
- 参数:模板数据DTO,包含单元格配置、公式等
- 权限:需要
reportDesign_saveLuckyTpl权限
2. 数据源管理接口
数据源连接测试
@RequestMapping(value = "/connectionTest", method = RequestMethod.POST)
public Response connectionTest(@RequestBody ReportDatasource reportDatasource)
- 功能:测试数据源连接是否正常
- 参数:数据源配置信息(类型、URL、用户名、密码等)
- 返回:连接测试结果
SQL执行接口
@RequestMapping(value = "/execSql", method = RequestMethod.POST)
public Response execSql(@RequestBody MesExecSqlDto mesExecSqlDto)
- 功能:执行SQL查询并返回结果
- 参数:数据源ID、SQL语句、参数等
- 权限:需要数据集相关操作权限
3. 报表预览与导出接口
报表数据预览
@RequestMapping(value = "/previewLuckysheetReportData", method = RequestMethod.POST)
public String previewLuckysheetReportData(@RequestBody MesGenerateReportDto mesGenerateReportDto)
- 功能:预览报表数据(支持Gzip压缩)
- 参数:模板ID、参数配置等
- 返回:压缩后的JSON格式报表数据
Excel导出接口
@RequestMapping(value = "/luckySheetExportExcel", method = RequestMethod.POST)
public void luckySheetExportExcel(@RequestBody MesGenerateReportDto mesGenerateReportDto)
- 功能:导出Excel文件
- 输出:直接写入HttpServletResponse输出流
系统集成方案
1. 单点登录集成
SpringReport支持Token-based认证集成,可通过自定义认证控制器实现与现有系统的单点登录。
集成示例代码
@RestController
@RequestMapping("/springReport")
public class SpringReportIntegrationController {
@GetMapping("/getTokenData")
public JSONObject getTokenData(@RequestParam String token) {
// 从现有系统获取用户信息
User currentUser = getCurrentUser(token);
JSONObject tokenData = new JSONObject();
tokenData.put("userId", currentUser.getId());
tokenData.put("loginName", currentUser.getUsername());
tokenData.put("showName", currentUser.getDisplayName());
tokenData.put("isAdmin", currentUser.isAdmin());
tokenData.put("token", token);
return tokenData;
}
}
2. 数据源集成方案
数据库直连集成
// 配置外部数据源
ReportDatasource externalDS = new ReportDatasource();
externalDS.setCode("EXTERNAL_DB");
externalDS.setName("外部业务数据库");
externalDS.setType(1); // MySQL
externalDS.setJdbcUrl("jdbc:mysql://external-host:3306/biz_db");
externalDS.setUserName("biz_user");
externalDS.setPassword("encrypted_password");
// 通过API创建数据源
Response response = restTemplate.postForObject(
"/springReport/api/reportDatasource/insert",
externalDS,
Response.class
);
API数据源集成
// 配置API数据源
ReportDatasource apiDS = new ReportDatasource();
apiDS.setCode("BIZ_API");
apiDS.setName("业务系统API");
apiDS.setType(13); // HTTP API
apiDS.setJdbcUrl("https://api.biz-system.com/data");
apiDS.setApiRequestType("POST");
apiDS.setApiHeaders("Authorization: Bearer {token}");
// 自动解析API响应结构
JSONArray attributes = restTemplate.postForObject(
"/springReport/api/reportDatasource/parseApiResultAttr",
apiDS,
JSONArray.class
);
3. 权限集成方案
SpringReport支持细粒度的权限控制,可与现有权限系统进行集成。
权限映射表
| SpringReport权限 | 业务系统权限 | 描述 |
|---|---|---|
reportTpl_search | REPORT_VIEW | 报表查看权限 |
reportTpl_insert | REPORT_CREATE | 报表创建权限 |
reportTpl_update | REPORT_EDIT | 报表编辑权限 |
reportDesign_saveLuckyTpl | REPORT_DESIGN | 报表设计权限 |
二次开发实践
1. 自定义报表函数
// 注册自定义函数
@Component
public class CustomReportFunctions {
@Autowired
private BusinessService businessService;
// 自定义业务计算函数
public Object calculateBusinessMetric(Map<String, Object> params) {
String department = (String) params.get("department");
String period = (String) params.get("period");
return businessService.calculateMetric(department, period);
}
// 注册到函数库
@PostConstruct
public void registerFunctions() {
FunctionRegistry.register("BIZ_METRIC", this::calculateBusinessMetric);
}
}
2. 扩展数据源类型
// 实现自定义数据源处理器
@Component
public class CustomDataSourceHandler implements DataSourceHandler {
@Override
public boolean supports(int dataSourceType) {
return dataSourceType == 99; // 自定义类型标识
}
@Override
public List<Map<String, Object>> executeQuery(DataSourceConfig config,
String query,
Map<String, Object> params) {
// 实现自定义数据源查询逻辑
CustomDataSource customDS = createCustomConnection(config);
return customDS.executeQuery(query, params);
}
}
3. 集成消息通知
// 报表生成完成通知
@Component
public class ReportNotificationService {
@Autowired
private MessageService messageService;
@EventListener
public void onReportGenerated(ReportGeneratedEvent event) {
ReportTpl report = event.getReport();
UserInfo user = event.getUser();
NotificationMessage message = new NotificationMessage();
message.setTitle("报表生成完成");
message.setContent(String.format("报表【%s】已生成完成", report.getTplName()));
message.setRecipient(user.getUserId());
message.setLink("/report/view?id=" + report.getId());
messageService.send(message);
}
}
性能优化建议
1. API响应优化
// 启用Gzip压缩
@RequestMapping(value = "/previewLuckysheetReportData", method = RequestMethod.POST)
public String previewLuckysheetReportData(@RequestBody MesGenerateReportDto dto) {
httpServletResponse.setHeader("Content-Encoding", "gzip");
httpServletResponse.setContentType("text/html");
// 压缩响应数据
byte[] compressed = Pako_GzipUtils.compress2(resultJson);
OutputStream out = httpServletResponse.getOutputStream();
out.write(compressed);
return null;
}
2. 数据缓存策略
// 使用Redis缓存报表数据
@Component
public class ReportCacheService {
@Autowired
private RedisUtil redisUtil;
public ResPreviewData getCachedReportData(Long reportId, Map<String, Object> params) {
String cacheKey = buildCacheKey(reportId, params);
Object cached = redisUtil.get(cacheKey);
if (cached != null) {
return (ResPreviewData) cached;
}
// 生成并缓存数据
ResPreviewData data = generateReportData(reportId, params);
redisUtil.set(cacheKey, data, 300); // 缓存5分钟
return data;
}
}
安全考虑
1. API安全防护
// SQL注入防护
@RequestMapping(value = "/execSql", method = RequestMethod.POST)
public Response execSql(@RequestBody MesExecSqlDto mesExecSqlDto) {
// 验证SQL语句安全性
if (!SqlValidator.isSafe(mesExecSqlDto.getSql())) {
throw new BizException("SQL语句包含危险操作");
}
// 参数化查询
List<Map<String, Object>> result = dataSourceService.executeParameterizedQuery(
mesExecSqlDto.getDatasourceId(),
mesExecSqlDto.getSql(),
mesExecSqlDto.getParams()
);
return Response.success(result);
}
2. 权限验证增强
// 细粒度权限控制
@RequiresPermissions(value = {
"reportTpl_search",
"viewReport_Search",
"excelTemplate_search"
}, logical = Logical.OR)
@RequestMapping(value = "/getTableList", method = RequestMethod.POST)
public Response getTableList(@RequestBody ReportTpl model) {
// 业务逻辑
}
故障排查与监控
1. API监控配置
# application-monitor.yml
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
metrics:
export:
prometheus:
enabled: true
tags:
application: springreport-api
2. 日志记录策略
// 详细的操作日志记录
@MethodLog(module="ReportTpl", remark="保存模板", operateType=Constants.OPERATE_TYPE_UPDATE)
@RequestMapping(value = "/saveLuckySheetTpl", method = RequestMethod.POST)
public Response saveLuckySheetTpl(@RequestBody MesLuckysheetsTplDto dto) {
// 记录详细的操作信息
log.info("用户{}保存模板{},数据大小:{}",
userInfoDto.getUserId(),
dto.getTplId(),
dto.getData().length());
return iReportTplService.saveLuckySheetTpl(dto, userInfoDto);
}
总结
SpringReport提供了完整且灵活的API接口体系,支持深度的二次开发和系统集成。通过本文介绍的集成方案和最佳实践,开发者可以:
- 快速实现单点登录集成,统一用户认证体系
- 灵活接入多种数据源,包括数据库直连和API接口
- 深度定制报表功能,满足特定业务需求
- 确保系统安全性,通过细粒度的权限控制和输入验证
- 优化系统性能,通过缓存和压缩等技术手段
SpringReport的API设计遵循RESTful原则,接口文档完整,为二次开发提供了良好的基础。在实际集成过程中,建议先从核心的报表模板和数据源接口入手,逐步扩展其他功能模块,确保集成过程的平稳和可控。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



