报表作为后端服务调用的方法及 API 相关类介绍
有些需求是把报表作为纯后台服务或者不想用 Jsp 文件。后台报表结果直接被集成用于页面展现,尤其是前后端分离的项目,后端是不希望有 Jsp、Html 等前端页面的。
润乾报表在常规方式下,用 Jsp 引入标签库发布报表再被调用的方式可能就不可行了。
报表工具生成并发布的报表最终是在 Web 端呈现,实际上此时报表模板计算完生成的就是 Html 脚本,可以想到只要把 Jsp 标签库的发布方式改到后台 Api 内计算就可以了,后台算后生成 Html 脚本扔给前端去呈现。
下面就具体看下 Api 计算报表所用到的类及使用方法,实例后端采用 springboot 项目。
注意:目前 Api 计算报表仅支持普通报表(统计类的),暂不支持填报表。
一、HtmlTagApi 类
从名字上大概可以看出其含义,作用类似 Jsp 内标签库(Tag)方式计算生成 Html 的 Api。
类名:com.raqsoft.report.tag.HtmlTagApi
调用此类,设置属性参数,报表计算后返回给前端报表结果为 Html 脚本,支持分页、导出功能。
具体参考后面的内容介绍。
二、类方法(常用的)介绍及示例
HtmlTagApi 是后台替代 Jsp 标签计算及设置属性的功能,所以此类也有三种计算报表的方式。
注:Jsp 标签库发布报表的方式有三种(file、defineBean、reportBean),具体可参考:http://d.raqsoft.com.cn:6999/report/preference/htmlmsfbbb2.html
下面看在 HtmlTagApi 内的用法,本质上和 Jsp 内的 Tag 是一样的:
(1)file 方式
//报表文件,可放在类路径下,如src/main/resources/reporFiles
String rpxName = test.rpx;
String rpxHtmlStr = "";
HtmlTagApi api = **new** HtmlTagApi();
//file方式,setSrcType为file
api.setSrcType("file");
//设置计算的报表
api.setReportFileName(rpxName);
//设置报表在网页中的ID标识,实际就是html脚本内Table的name属性
api.setName("report1");
//这里可以设置报表需要的参数,格式pName1=value1;pName2=value2
api.setParams(params);
//设置报表水印
api.setGenerateWaterMark("Hyl test!!!");
//设置是否导出Excel,导出Word,可定义api.setNeedSaveAsExcel("yes");
api.setNeedSaveAsExcel("yes");
//计算报表生成Html脚本
rpxHtmlStr = api.getTagOutput(request,request.getServletContext());
//返回结果Html给调用端
return rpxHtmlStr;
(2)defineBean 方式
//报表文件,可放在类路径下,如src/main/resources/reporFiles
String rpxName = test.rpx;
//此处报表文件在springboot工程的src/main/resources/reporFiles下
ClassPathResource rpxPath = new ClassPathResource("reportFiles/"+rpxName);
//读入报表文件
ReportDefine rd = (ReportDefine)
ReportUtils.read(rpxPath.getInputStream());
//将reportDefine放在request内,建议下面的“rDefine”用随机值处理,可以保证多人同时访问的时候不会读取到同一个报表的内容
request.setAttribute("rDefine", rd);
String rpxHtmlStr = "";
HtmlTagApi api = new HtmlTagApi();
//bean方式,setSrcType为defineBean
api.setSrcType("defineBean");
//设置计算的报表,此处是在request内的defineBean对象rRdfine
api.setBeanName("rDefine");
//设置报表在网页中的ID标识,实际就是html脚本内Table的name属性
api.setName("report1");
//这里可以设置报表需要的参数,格pName1=value1;pName2=value2
api.setParams(params);
//设置报表水印
api.setGenerateWaterMark("Hyl test!!!");
//设置是否导出Excel,导出Word,可定义api.setNeedSaveAsExcel("yes");
api.setNeedSaveAsExcel("yes");
//计算报表生成Html脚本
rpxHtmlStr = api.getTagOutput(request,request.getServletContext());
//返回结果Html给调用端
return rpxHtmlStr;
(3)reportBean 方式
//报表文件,可放在类路径下,如src/main/resources/reporFiles
String rpxName = test.rpx;
//报表计算上下文环境
Context cxt = new Context();
//此处报表文件在springboot工程的src/main/resources/reporFiles下
ClassPathResource rpxPath = new ClassPathResource("reportFiles/"+rpxName);
//读入报表文件
ReportDefine rd = (ReportDefine) ReportUtils.read(rpxPath.getInputStream());
Engine engine = new Engine(rd, cxt); //构造报表引擎
IReport iReport = engine.calc(); //运算报表
session.setAttribute("report",iReport);
String rpxHtmlStr = "";
HtmlTagApi api = **new** HtmlTagApi();
//bean方式,setSrcType为reportBean
api.setSrcType("reportBean");
//设置计算的报表,此处是在session内的reportBean对象report
api.setBeanName("report ");
//设置报表在网页中的ID标识,实际就是html脚本内Table的name属性
api.setName("report1");
//这里可以设置报表需要的参数,格pName1=value1;pName2=value2
api.setParams(params);
//设置报表水印
api.setGenerateWaterMark("Hyl test!!!");
//设置是否导出Excel,导出Word,可定义api.setNeedSaveAsExcel("yes");
api.setNeedSaveAsExcel("yes");
//计算报表生成Html脚本
rpxHtmlStr = api.getTagOutput(request,request.getServletContext());
//返回结果Html给调用端
return rpxHtmlStr;
三、示例
场景
应用环境:
(1)Springboot 应用
报表访问路径(报表服务):http://localhost:8080/genRpxResult.do?rpx=test.rpx
(2)设计器自带 demo 应用(模拟前端应用)
访问路径:http://localhost:6868/demo
我们在 demo 应用内定义一个 Html 页面,调用 Springboot 的报表服务呈现及导出报表。报表服务以“二(1)”中的 file 方式为例。
实例
1、Springboot 集成润乾报表
已有文章,可参考 润乾与 springBoot 集成
2、Springboot 项目内定义访问报表的 Controller
用于访问报表的入口或服务地址,核心代码:
@RequestMapping("genRpxResult.do")
public @ResponseBody String calcRpx(HttpServletRequest request, HttpServletResponse response) {
String rpxHtml = "";
//调用计算报表的service,返回html
String reqP1 = request.getParameter("rpx");
CalcRpxServiceImpl crsi = **new** CalcRpxServiceImpl();
rpxHtml = crsi.getRpxHtml(reqP1,request);
//增加echarts的js,用于带有echarts图的,加入下面代码可支持导出echarts图形,没有或不考虑echarts图,可不加
String echartsJS = "<script type="text/javascript" src="http://localhost:8080/raqsoft/echarts/echarts.js"></script>
+ "<script type="text/javascript" src="http://localhost:8080/raqsoft/echarts/ecStat.min.js"></script>
+ "<script type="text/javascript" src="http://localhost:8080/raqsoft/echarts/echarts-gl.min.js"></script>"+ "<script type="text/javascript" src="http://localhost:8080/raqsoft/echarts/d3.v5.min.js"></script>"
+ "<script type="text/javascript" src="http://localhost:8080/raqsoft/echarts3/dist/extension/dataTool.min.js"></script>"
+ "<script type="text/javascript" src="http://localhost:8080/raqsoft/echarts3/map/js/china.js"></script>"+ "<script type="text/javascript" src="http://localhost:8080/raqsoft/echarts3/map/js/world.js"></script>"+ "<script type="text/javascript" src="http://localhost:8080/raqsoft/echarts3/dist/extension/bmap.min.js"></script>"+ "<script src="http://localhost:8080/raqsoft/echarts2/dist/echarts.js"></script>"+ "<script language=javascript>"
+ " var appmap = "http://localhost:8080";"
+ " require.config({"
+ " paths: {"
+ " echarts: 'http://localhost:8080/raqsoft/echarts2/dist',"
+ " zrender: 'http://localhost:8080/raqsoft/echarts2/dist/zrender'"
+ " },"
+ " packages: ["+ " {"
+ " name: 'BMap',"
+ " location: 'http://localhost:8080/raqsoft/echarts2/dist/extension/BMap/src',"
+ " main: 'main'"
+ " }"
+ " ]"
+ " });"
+ "</script>";
return echartsJS+rpxHtml;
3、定义报表计算类
Controller 内调用,核心代码:
public String getRpxHtml(String rpxName,HttpServletRequest request) {
Context cxt = **null**;
String rpxHtmlStr = "";
cxt = **new** Context();
try {
//返回报表计算生成的html串儿,可分页。导出打印等的js函数也都生成在页面了,可以调用js函数。 如果是跨系统调(如iframe嵌入),涉及到js跨域,自行解决即可。
HtmlTagApi api = **new** HtmlTagApi();
//bean方式,必须设定srcType,file方式可省略可指定。
api.setSrcType("file");
api.setReportFileName(rpxName);
api.setName("report1");
//api.setParams(params);
api.setGenerateWaterMark("Hyl test!!!");
api.setNeedSaveAsExcel("yes");
rpxHtmlStr = api.getTagOutput(request,request.getServletContext());
} catch (Throwable e) {
e.printStackTrace();
}
return rpxHtmlStr;
}
4、demo 应用内定义调用页面
这里直接用 iframe 模拟引用了:
<body>
<iframe src="http://localhost:8080/genRpxResult.do?rpx=test.rpx" width="100%" height="100%"/>
</body>
5、启动 Springboot 项目及 demo 应用,查看调用结果
(1) 直接访问 Springboot 的 controller
(2) demo 应用调用(模拟前端调后台服务)
附件(实例中的完整代码文件)
实例中 test.rpx、Controller 和报表计算类的完整代码参考:
报表后台服务 - 示例部分完整代码文件下载
对润乾产品感兴趣的小伙伴,一定要知道软件还能这样卖哟性价比还不过瘾? 欢迎加入好多乾计划。
这里可以低价购买软件产品,让已经亲民的价格更加便宜!
这里可以销售产品获取佣金,赚满钱包成为土豪不再是梦!
这里还可以推荐分享抢红包,每次都是好几块钱的巨款哟!
来吧,现在就加入,拿起手机扫码,开始乾包之旅
嗯,还不太了解好多乾?
使用
ReportDefine
方式 报错 指定的 reportBean–report 不存在!想问下是怎么回事
您好,可以提供下编写的代码(可能没有把 reportDefine 对象放 request 内?) 或 参考该文件(本地测试是可用的 reportBean 方式)。另外,要确保 rpx 文件确实是读到了。
CalcRpxServiceImplzip
确实是没有把 reportDefine 对象放 request 内, 改了之后可以了
然后还有几个问题, 想请教一下
1. 在前端页面点击导出 excel 后台报错:
[2021-03-29 14:59:38]
DEBUG: CacheManager get remote report entry
[2021-03-29 14:59:38]
DEBUG: 报表已分页,标识为:A_10747064
[2021-03-29 14:59:38]
DEBUG: Export report begin, total pages :1
[2021-03-29 14:59:38]
DEBUG: Page :1 OK.
java.lang.ArrayIndexOutOfBoundsException
at java.lang.System.arraycopy(Native Method)
at jxl.biff.StringHelper.getBytes(StringHelper.java:127)
at jxl.write.biff.WriteAccessRecord.(WriteAccessRecord.java:59)
at jxl.write.biff.WritableWorkbookImpl.write(WritableWorkbookImpl.java:726)
at com.raqsoft.report.view.excel.JxlWaterMarkUtil._$1(Unknown Source:159)
at com.raqsoft.report.view.excel.JxlWaterMarkUtil.appendWaterMark(Unknown Source:143)
at com.raqsoft.report.view.excelbase.BaseExcel.saveTo(Unknown Source:476)
at com.raqsoft.report.view.ReportExporter.save(Unknown Source:605)
at com.raqsoft.report.view.excel.ExcelReportServlet.service(Unknown Source:225)
at com.raqsoft.report.view.ReportServlet.service(Unknown Source:1464)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
javax.servlet.ServletException: 没有设置报表配置文件或报表应用没启动起来,请查看服务器启动日志!
at com.raqsoft.report.view.ReportServlet.loadConfig(ReportServlet.java:177)
at com.raqsoft.report.view.ReportServlet.reloadConfig(ReportServlet.java:1655)
at com.raqsoft.report.tag.HtmlTag.generateHtmlString(HtmlTag.java:1370)
at com.raqsoft.report.tag.HtmlTagApi.getTagOutput(HtmlTagApi.java:13)
怎么解决,已在
ApplicationRunner
启动时 ExtCellSet.readLicense(“xxx.xml”); 加载了授权文件,并且可以读取 rpx 文件的参数等信息看错误应该是没有加载配置文件 raqsoftConfig.xml, 可能集成中少了 http://c.raqsoft.com.cn/article/1534778906951 文章中 “二(3)”部分的 Servlet 注册(注册过程中会加载 raqsoftConfig.xml),您检查下。
如果只是调用 API,怎么与 springboot 集成?看了其他集成的教程,都是要加入 xml、jsp 的,太冗余了。
您好,关于前后端分离,复杂类型的报表可以使用吗?在经过复杂查询获取到数据后,整合的复杂报表。我之前按照文中的方法做了后端集成,去掉了 jsp 等界面,但是可以显示简单的报表信息,而诸如 demo 里面那几个复杂的报表就无法显示了,或者只能显示出部分,这个是不支持吗?还是需要做什么配置
我按照您的步骤尝试,其中 echarts 图并未访问到
echarts 图属于前端统计图,需要用到 js,注意一下“实例”中第 2 步,一定要引入。
另外,注意此处引入的 echarts 的版本,实例代码是 echart2,如果报表设计时用的其他版本,请对应引入。
注:如数据集使用集算器文件,并且是相对路径,需要通过代码设置下路径:
Env.setMainPath(“path”);
你好,请问不同的 rpx 模板,用同一个 api 接口返回的一直是第一次访问这个接口的模板是什么原因?