润乾报表提供了tag标签供程序员发布报表,减轻代码编写的工作量。
本章重点讲解<report:html/>的使用。
◆ 背景说明
通过tag发布报表,最简单的情况下只需要指定报表模板名。为了满足不同层次的需要,润乾报表tag还支持definebean的方式发布报表、支持传递context对象,便于用户自定义数据源、自定义参数等。
◆ 示例代码1:file方式发布
<report:html name="report1"
srcType="file"
reportFileName="api/wangge.rpx"
/>
◆ 示例代码2:defineBean方式发布
<%
//取得报表真实路径
String reportPath = request.getRealPath("WEB-INF/reportFiles/api/wangge.rpx");
ReportDefine rd = (ReportDefine)ReportUtils.read(reportPath);
request.setAttribute("reportDefine",rd); //把ReportDefine对象在request中保存
%>
<report:html name="report1"
srcType="defineBean"
beanName="reportDefine"
exceptionPage="myError.jsp" //错误提示页面
/>
示例代码3:reportBean方式发布
<%
//取得报表真实路径
String reportPath = request.getRealPath("WEB-INF/reportFiles/api/wangge.rpx");
ReportDefine rd = (ReportDefine)ReportUtils.read(reportPath);
Context cxt = new Context();
//..............//其它辅助代码,例如往报表引擎传递参数,传递数据库连接参数等,见后面的介绍
Engine engine = new Engine(rd, cxt); //构造报表引擎
IReport iReport = engine.calc(); //运算报表
request.setAttribute("report", iReport); //把IReport对象在request中保存
%>
<report:html name="report1"
srcType="reportBean"
beanName="report"
exceptionPage="myError.jsp" //错误提示页面
/>
◆ 示例代码4:自定义context后传递给tag去发布
<%
……
Context context = new Context();
…… //利用context,可以传递参数,可以指定数据源、数据库连接工厂等
session.setAttribute( “myContext”, context );
%>
<report:html ……..
contextName=”myContext”
/>
◆ 示例代码5:错误提示页面
错误提示页面,是指当程序发布错误时,转跳到一个页面,来人性化的展现错误,具体到报表中,我们在tag标签里提供了exceptionPage属性来指定转跳页面.
<report:html ......
exceptionPage="myError.jsp" //错误提示页面
/>
在转跳页面中,通过如下代码获取掷出的异常信息:
<%
Exception e = ( Exception ) request.getAttribute( "exception" );
out.println( "<h1>错误信息:</h1><div style='color:red'>" + e.getMessage() + "</div>" );
%>
◆ 参考文件:
1.1.1.a.jsp,1.1.1.b.jsp,1.1.1.c.jsp
◆ 缺省参数输入页面—1.1.2.a.jsp
为了方便用户快速体验报表的功能,当用户的关注点不在于参数录入页面而在于报表时,润乾报表的tag标签提供了generateParamForm属性,只要置为yes就可以自动生成参数录入表单,方便用户快速体验报表。
<report:html name="report1"
......
generateParamForm="yes"
......
/>
◆ 参数模板—1.1.2.b.jsp
用润乾报表设计的参数模板,需要利用参数模板的tag进行发布,其自动与结果页面的报表关联。因此,比较简单的做法是把参数模板tag和结果报表tag写到一个页面里。如下所示:
<report:param name="form1" paramFileName="api/wangge_arg.rpx" /> //参数模板tag
<report:html name="report1" //结果报表tag
srcType="file"
reportFileName="api/wangge.rpx"
generateParamForm="no"
needImportEasyui="no"
/>
注意:
缺省情况下每个tag标签都会引入一次Easyui样式。如上述jsp 所示,包含两个tag标签,因此默认就会引入两次Easyui样式,引入多次Easyui样式则会出现编辑控件显示不正常的现象。具体关于needImportEasyui属性的使用可参考tag标签。
◆ 自定义参数输入—1.1.2.c.jsp
如果用户自己定义参数输入页面,那么集成流程包括:设计参数页面——〉在接收页面中写代码接收参数——〉在接收页面里把参数拼成串传给tag
//用户自定义的参数输入页面
<FORM name="form1" action="#">
尊称:<INPUT type="text" name="appellation">
<input type="submit" value="查询">
</FORM>
//接收页面代码
<% //获取由参数表单传递的值
request.setCharacterEncoding("UTF-8");
String param = "appellation="+request.getParameter("appellation");
%>
//注:参数串param的格式是:paramName=paramValue;paramName2=paramValue2……
<report:html name="report1"
srcType="file"
reportFileName="api/wangge.rpx"
generateParamForm="no"
params="<%=param%>" //将拼好的参数串传给tag
exceptionPage="myError.jsp"
/>
◆ 在Jsp中引用参数模板提交的参数-1.1.2.d.jsp
参数模板提交的参数,保存在报表系统的参数池中,并没有存在request里,因此如果使用参数模板,要在结果页面里引用参数值,必须在报表的参数池中读取,而不应该从request里获得。
报表提供了两种从参数池中读取参数模板提交的参数值的方法,具体如下所示:
方法一:
<%
String reportParamsId=request.getParameter("reportParamsId"); //取得参数缓存的标识号
//从参数缓存池中取得的参数保存于一个Hashtable中
Hashtable params = null;
if(!"".equals(reportParamsId) && reportParamsId != null){
params = com.raqsoft.report.view.ParamsPool.get( reportParamsId );
}
//接下来我们以参数名为key,直接从Hashtable中取参数模板中的传递的参数值
String paramValue = (String) params.get("appellation");
out.println("取得的参数值是:"+paramValue);
%>
方法二:
通过调用ReportUtils工具类中的getReportParamValue方法获取参数值
<%
//通过传递参数名和request请求获取参数值
String paramValue=(String)com.raqsoft.report.util.ReportUtils.getReportParamValue(request, "appellation");
out.println("appellation参数取得的参数值是:"+paramValue);
%>
◆参数表单提交回调js函数-1.1.2.g.jsp
参数表单提交后通过callback回调js函数,当用户提供此函数后,表单采用ajax的方式提交,不刷新页面,系统将resultPage的内容作为参数去调用callback函数。如下所示:
1.1.2.g.jsp:
<script language=javascript>
function showReports(html){
$("#reportDiv").html(html);
}
</script>
…..
<report:param name="form1" paramFileName=" api/call_arg.rpx "
needSubmit="no"
callback="showReports"
resultPage="/jsp/1.1.2.h.jsp?rpx= api/call.rpx"
params="<%=param.toString()%>"
/>
<div id="reportDiv">
<report:html name="report1" reportFileName="api/call.rpx "
funcBarLocation="top"
needPageMark="yes"
generateParamForm="no"
params="<%=param.toString()%>"
exceptionPage=" myError.jsp"
appletJarName="raqsoftReportApplet.jar"
needImportEasyui="no"
/>
</div>
1.1.2.h.jsp:
<report:html name="report1" reportFileName="api/call.rpx"
funcBarLocation="top"
needPageMark="no"
generateParamForm="no"
params="<%=param.toString()%>"
exceptionPage=" myError.jsp"
appletJarName="raqsoftReportApplet.jar"
needImportEasyui="no"
/>
◆ 利用tag属性改变按钮风格
<report:html name="report1"
srcType="file"
funcBarLocation="top" //功能条的位置
reportFileName="api/wangge.rpx"
separator="|" //功能按钮的分隔符
funcBarFontFace="黑体" //功能按钮的字体
funcBarFontColor="red" //功能按钮上的文字颜色
funcBarFontSize="12" //功能按钮的字号
functionBarColor="white" //功能按钮的背景色
/>
◆ 传入按钮的html语法
<% //自定义图片按钮
String appmap = request.getContextPath();
String printImage = "<img src='" + appmap + "/images/print.gif' border=no >"; //打印
String excelImage = "<img src='" + appmap + "/images/excel.gif' border=no >"; //导出Excel
String pdfImage = "<img src='" + appmap + "/images/pdf.gif' border=no >"; //导出PDF
String firstPageImage = "<img src='" + appmap + "/images/firstpage.gif' border=no >"; //最前页
String lastPageImage = "<img src='" + appmap + "/images/lastpage.gif' border=no >"; //最后页
String nextPageImage = "<img src='" + appmap + "/images/nextpage.gif' border=no >"; //下一页
String prevPageImage = "<img src='" + appmap + "/images/prevpage.gif' border=no >"; //上一页
%>
<report:html name="report1"
srcType="file"
reportFileName="api/wangge.rpx"
printLabel="<%= printImage %>"
excelLabel="<%= excelImage %>"
pdfLabel="<%= pdfImage %>"
firstPageLabel="<%=firstPageImag%>"
prevPageLabel="<%= prevPageImage %>"
nextPageLabel="<%= nextPageImage %>"
lastPageLabel="<%= lastPageImage %>"
/>
◆ 自己设计按钮,调用js方法
//自定义图片按钮
<%
String appmap = request.getContextPath();
String excelImage = "<img src='" + appmap + "/images/excel.gif' border=no >";//导出Excel
String csvImage = "<img src='" + appmap + "/images/csv.gif' border=no >";//导出CSV
String pdfImage = "<img src='" + appmap + "/images/pdf.gif' border=no >";//导出PDF
String ofdImage = "<img src='" + appmap + "/images/ofd.gif' border=no >";//导出OFD
String wordImage = "<img src='" + appmap + "/images/word.gif' border=no >";//导出Word
String pictureImage = "<img src='" + appmap + "/images/picture.gif' border=no >";//导出图片
String textImage = "<img src='" + appmap + "/images/text.gif' border=no >";//导出Text
String mhtImage = "<img src='" + appmap + "/images/mht.gif' border=no >";//导出mht
String printImage = "<img src='" + appmap + "/images/print.gif' border=no >";//预览打印
String directprintImage = "<img src='" + appmap + "/images/directprint.gif' border=no >";//直接打印
String flashprintImage = "<img src='" + appmap + "/images/flashprint.gif' border=no >";//flash预览打印
String directflashprintImage = "<img src='" + appmap + "/images/directflashprint.gif' border=no >";//flash直接打印
String pdfprintImage = "<img src='" + appmap + "/images/pdfprint.gif' border=no >";//PDF预览打印
String directpdfprintImage = "<img src='" + appmap + "/images/directpdfprint.gif' border=no >";//PDF直接打印
String localprintImage = "<img src='" + appmap + "/images/localprint.gif' border=no >";//本地预览打印
String localdirectprintImage = "<img src='" + appmap + "/images/localdirectprint.gif' border=no >";//本地直接打印
String firstPageImage = "<img src='" + appmap + "/images/firstpage.gif' border=no >";//最前页
String lastPageImage = "<img src='" + appmap + "/images/lastpage.gif' border=no >";//最后页
String nextPageImage = "<img src='" + appmap + "/images/nextpage.gif' border=no >";//下一页
String prevPageImage = "<img src='" + appmap + "/images/prevpage.gif' border=no >";//上一页
%>
<table width="100%">
<tr ><td style="font-size:12px" >
<a href="#" title="预览打印" onClick="printReport('report1');return false;"><%=printImage%></a>
<a href="#" title="直接打印" onClick="directPrintReport('report1');return false;"><%=directprintImage%></a>
<a href="#" title="flash预览打印" onClick="flashPrintReport('report1');return false;"><%=flashprintImage%></a>
<a href="#" title="flash直接打印" onClick="directFlashPrintReport('report1');return false;"><%=directflashprintImage%></a>
<a href="#" title="PDF预览打印" onClick="pdfPrintReport('report1');return false;"><%=pdfprintImage%></a>
<a href="#" title="PDF直接打印" onClick="directPdfPrintReport('report1');return false;"><%=directpdfprintImage%></a>
<a href="#" title="本地预览打印" onClick="localPrintReport('report1');return false;"><%=localprintImage%></a>
<a href="#" title="本地直接打印" onClick="localDirectPrintReport('report1');return false;"><%=localdirectprintImage%></a>
<a href="#" title="导出Excel" onClick="exportExcel('report1');return false;"><%=excelImage%></a>
<a href="#" title="导出Csv" onClick="exportCsv('report1');return false;"><%=csvImage%></a>
<a href="#" title="导出Pdf" onClick="exportPdf('report1');return false;"><%=pdfImage%></a>
<a href="#" title="导出Ofd" onClick="exportOfd('report1');return false;"><%=ofdImage%></a>
<a href="#" title="导出Word" onClick="exportWord('report1');return false;"><%=wordImage%></a>
<a href="#" title="导出图片" onClick="exportPicture('report1');return false;"><%=pictureImage%></a>
<a href="#" title="导出Text" onClick="exportText('report1');return false;"><%=textImage%></a>
<a href="#" title="导出Mht" onClick="exportMht('report1');return false;"><%=mhtImage%></a>
<a href="#" title="最前一页" onClick="try{toPage('report1',1);}catch(e){}return false;"> <%=firstPageImage%> </a>
<a href="#" title="上一页" onClick="try{prevPage('report1');}catch(e){}return false;"> <%=prevPageImage%> </a>
<a href="#" title="下一页" onClick="try{nextPage('report1');}catch(e){}return false;"> <%=nextPageImage%> </a>
<a href="#" title="最后一页" onClick="try{toPage('report1',getPageCount('report1'));}catch(e){}return false;"> <%=lastPageImage%> </a>
</td>
</tr>
</table>
◆ 用户自定义功能条
用户可能在报表界面中增加自己的功能按钮,而这些功能按钮如何与tag生成的按钮统一摆放呢?此时可以利用tag的userFuncBarElements属性。
<report:html name="report1"
......
userFuncBarElements="<table><tr><td><a href='#' onClick='test()'>测试</a></td></tr></table>"
/>
◆ 超链接显示风格
报表中经常用到超链接,对于有超链接的单元格,其外观是按照设计时单元格的外观还是自动变成蓝色+下划线?润乾报表的tag提供了属性配置:
<report:html name="report1"
......
needLinkStyle="yes"
/>
◆ 参考文件:
1.1.3.jsp
◆ 背景说明
报表的打印一般都是基于客户端打印,对于一些大数据量报表来说,一次性将所有数据从服务器端传输到打印机,有可能出现内存溢出,为了避免这种情况,报表采取每5页为一个打印单位发送给打印机,这5页打印完后就将从内存中清除,然后循环,直至打印完成。
◆ 示例代码
1.修改WEB-INF\web.xml。将以下代码添加到web.xml中。
<servlet>
<servlet-name>com.raqsoft.report.view.PagedPrint</servlet-name>
<servlet-class>com.raqsoft.report.view.PagedPrint</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>com.raqsoft.report.view.PagedPrint</servlet-name>
<url-pattern>/servlet/pagedPrintServer</url-pattern>
</servlet-mapping>
2.在tag标签中添加serverPagedPrint属性。
<report:html name="report1"
......
serverPagedPrint="yes"
/>
◆ 背景说明
由于润乾报表中的换行符是固定的,但是WINDOWS下的记事本不支持该换行符。所以在将报表导为Text时,部分字符就会显示成■。为了避免这种情况的发生,润乾报表在tag中定义了textDataLineBreak属性,让用户在导出Text时自定义windows记事本所支持的换行符,从而确保每个字符都能正常显示。
◆ 示例代码
<report:html name="report1"
......
textDataLineBreak="\r\n"
/>
<report:html name="report1"
srcType="file"
reportFileName="api/wangge.rpx"
scrollWidth="300" //滚动区域宽度
needScroll="yes" //是否需要滚动
scrollHeight="200" //滚动区域高度
scrollBorder="border:1px solid red" //滚动区域边框
/>
◆ 参考文件:
1.1.6.jsp
可以在标签里通过scale属性来指定报表缩放显示比例,默认情况下为1.0,我们可以直接设置scale属性来达到固定控制缩放比例,也可以用户传入参数,来达到自定义缩放比例要求:请参考例子1.1.7.jsp
◆ 直接指定缩放属性
<report:html name="report1"
srcType="file"
reportFileName="api/wangge.rpx"
......
scale="0.5"
/>
◆ 用户自定义缩放比例
<report:html name="report2"
srcType="file"
reportFileName="api/wangge.rpx"
scale="<%=request.getParameter("scale")%>" //通过传递参数控制缩放比例
/>
◆ 参考文件:
1.1.7.jsp
使用needPrint启动打印功能,printLabel为打印功能按钮设置显示值,needDirectPrint属性启用直接打印, needSelectPrinter是否选择打印机,printedRaq设置后,展现与打印可以分别是不同的报表,appletJarName属性指定打印applet所在的位置,可以带路径.这个可以参看例子1.1.8.jsp
<%
String appmap = request.getContextPath();
String PrintImg = "<img src='" + appmap + "/images/print.gif' border=no>";
%>
<report:html name="report1"
reportFileName="api/wangge.rpx"
needPrint="yes"
printLabel="点击进入打印预览"
needDirectPrint="yes" //是否需要显示直接打印按钮
needPrintPrompt="yes" //是否立即打印(即是否弹出对话框询问是否打印)
needSelectPrinter="yes" //是否需要选择打印机
savePrintSetup="yes" //是否保存打印设置
printedRaq="api/wangge_arg.rpx" //打印的报表,此属性用于显示报表和打印报表不同
appletJarName="raqsoftReportApplet.jar" //打印applet的jar文件名
/>
参看例子1.1.10.jsp
<report:html name="report1"
reportFileName="api/wangge.rpx"
needSaveAsPdf="yes"
pdfExportStyle="text,0" //表示导出文本方式的不分页的PDF文件
needSaveAsText="yes"
textDataSeparator="," //存为Text时,同行单元格数据间的分隔符
needSaveAsExcel="yes"
needSaveAsWord="yes"
excelUsePaperSize="no" //存为Excel时:yes按报表设计时的纸张尺寸,no采用本tag标签中指定的width,height值
excelPageStyle="1" //存为Excel时的分页方式,不指定此属性值,则弹出对话框让用户选,0(不分页)或1(分页)
saveAsName="网格" //报表另存为Excel、PDF、Word或Text时的文件名(不用带扩展名)
/>
分页
参见例子1.1.11.1.jsp
<report:html name="report1"
reportFileName="api/wangge.rpx"
width="1000" //报表分页宽度
height="1000" //报表分页高度
needPageMark="yes" //是否显示报表页数及翻页功能
columns="2" //分栏数
displayNoLinkPageMark="no" //是否显示无超链接的页码标识(如第一页时的“最前页”和“上一页”
/>
缓存与实时报表
当且仅当raqsoftConfig.xml里的alwayReloadDefine属性设置为no时, tag标签中的useCache与timeout属性才会起作用,useCache属性控制是否启用缓存,而timeout为取多少长时间内生成的报表。这个可以参看例子1.1.11.2.jsp.建议大报表启用缓存。
<report:html name="report1"
reportFileName="api/wangge.rpx"
useCache="yes" //是否使用缓存
timeout="30" //从缓存系统中取多少分钟内产生的报表,如果没有此时间内的,则产生一个新报表
/>
◆背景说明
当某些分组报表的格式符合折叠报表的格式要求时,在web端是可以按照折叠报表的方式展现的。通常折叠报表用于大数据量的分组报表展现,以便能逐级展开/收拢查看。
折叠报表说明:
(1) OLAP折叠报表(isOlap)和树形报表(isTreeTable)两种展现方式互斥,因此isOlap与isTreeTable不可以同时为yes
(2) 折叠报表同时支持固定表头
(3) 折叠报表不支持分页
(4) 折叠报表是js的功能,因此仅限于网页支持。打印和导出时与普通报表一致
(5) 树形报表对浏览器没有要求,OLAP折叠报表要求IE浏览器为IE9以上版本,其它类浏览器不限
(6) 树形报表格式要求:分组格与它的子格不在同一行上,不能有行上的全包含或半包含关系。
(7) OLAP折叠报表格式要求:必须全包含,并且必须给每个分组都加上一个统计行,如果分组格是纵向扩展,统计行必须与分组格同行,如果是横向扩展,统计行必须与分组格同列。
◆树形折叠报表
首先,制作一个满足树形折叠报表格式要求的报表,比如该示例中的tree.rpx
然后,通过tag标签发布该报表:
<report:html name="report1"
reportFileName="api/tree.rpx"
isTreeTable="yes" //以树形折叠报表展现
needScroll="yes" //固定表头
foldIcon="arrow" //折叠图标为箭头(plus或arrow)
foldOnBegin="2" //初始可以看见2层(yes、no或整数)
/>
◆olap折叠报表
首先,制作一个满足olap折叠报表格式要求的报表,比如该示例中的olap.rpx
然后,通过tag标签发布该报表:
<report:html name="report1"
reportFileName="api/olap.rpx"
isOlap="yes" //以OLAP式折叠报表展现
needScroll="yes" //固定表头
scrollWidth="1000"//滚动区域宽度
foldIcon="plus" //折叠图标为加减号(plus或arrow)
foldOnBegin="yes" //初始全折叠(yes、no或整数)
/>
对于添加isOlap标签的折叠报表,如需自定义折叠和收起的图标,可替换[应用根目录]/raqsoft/images下的folded.gif、extended.gif 、foldedCol.gif 、extendedCol.gif即可
◆参考文件
1.1.12.a.jsp, 1.1.12.b.jsp
用户可以使用tag标签来冻结报表的表头。
html报表在JSP文件中用<prefix:html>标签来发布,prefix是用户在JSP文件头指定tag定义文件时指定的前缀名。该定义语句如下所示:
<%@taglib uri="/WEB-INF/raqsoftReport.tld" prefix="report"%>
此定义语句必须写在JSP的开头,其中prefix的值可以自己指定,但tag标签中的前缀必须与其保持一致。
在要发布报表的地方用上面介绍的tag标签来发布,在tag标签中用needScroll属性来指定是否冻结报表的表头,用scrollWidth和scrollHeight指定表头的宽度和高度。
needScroll:是否固定上表头和左表头。取值为yes或no,其中yes表示发布报表时冻结报表的表头,no表示发布报表时不冻结报表的表头,默认属性取值为:no。
scrollWidth:固定表头报表的显示宽度。取值为整数、象素值、百分数(如80%),默认属性取值为:600。
scrollHeight:固定表头报表的显示高度。取值为整数、象素值、百分数(如80%),默认属性取值为:400。
举例:
<report:html name=”report1”
reportFileName=”冻结表头.rpx”
needScroll=”yes”
scrollWidth=”650”
scrollHeight=”450”
/>
<report:group groupFileName="api/group.rpg"
border="4px double peachpuff " //报表显示区边框,html边框表示法
margin="10" //报表与报表显示区边框的距离,整数
tabFontColor="red" // tab页字体颜色
tabHLFontColor="blue" //当前tab页字体颜色
tabFontName="宋体" // tab页字体名
tabFontSize="10px" // tab页字体大小
useTabControl="yes" //是否以TAB标签页的方式发布,如为no,则首先显示第一个,然后用户可下拉选择显示哪一个
needImportExcel="yes" //报表组中的填报表是否需要从Excel导入数据
tabLocation="top" // tab选项卡位置
/>
◆手机端参数模板-1.1.2.e.jsp
制作手机报表时参数模板表单只有前两列有效,列宽设计无效。第一列是参数提示,第二列是输入区,第二列会与屏幕宽度自适应。除列数要求外,其他关于手机参数模板的制作与普通参数模板一致,这里只讲解tag标签的使用。
手机端参数模板可利用参数模板的tag进行发布,通过mobileMode属性设置是否使用手机模式发布。如使用手机模式发布需将mobileMode属性值设置为yes,并且通过resultPage属性跳转到结果页面。如下所示:
1.1.2.e.jsp:
<report:param name="param1" paramFileName="api/wangge_arg.rpx"
needSubmit="yes"
resultPage="/jsp/1.1.2.f.jsp?rpx= api/wangge.rpx"
mobileMode="yes"
/>
1.1.2.f.jsp:
<report:html name="report1"
srcType="file"
reportFileName="api/wangge.rpx"
funcBarLocation="top"
generateParamForm="no"
exceptionPage=" myError.jsp"
/>
<%
//通过传递参数名和request请求获取参数值
String paramValue=(String)com.raqsoft.report.util.ReportUtils.getReportParamValue(request, "appellation");
out.println("appellation参数取得的参数值是:"+paramValue);
%>