前言
本教程主要介绍了如何通过Dorado5的集成润乾进行报表的开发相关技术细节,以及提供一个现有项目的集成方案作为借鉴。
本教程使用的Dorado版本为Dorado5,润乾版本为4.0。
原理概述
润乾报表4.0与基于JavaEE的Web系统集成,是通过润乾提供的自定标签(Tag)完成报表的解析以及运算,并按照用户配置的属性要求将报表通过HTML的方式输入到客户端。(具体的润乾提供的Tag详述,请见润乾提供的文档《润乾报表4.0用户开发手册》)。
以Dorado作为展现层的JavaEE Web应用系统,通过润乾提供的Tag进行集成,从而简化了表现层的开发,并与润乾良好的配合,实现相关报表业务场景的快速开发。
集成Dorado5工程
下面,将介绍如何将润乾集成到Dorado5 Web工程中。
一. 创建一个基于Dorado5的Web工程。(新建或者已有的Dorado5 Web工程均可)
具体如何创建Dorado5的Web工程,详见Dorado5的相关文档,这里不做累述。
二. 将润乾需要的相关包以及文件,拷贝到Dorado5工程中。
具体参见润乾提供的文档《润乾报表4.0在J2EE部署教程》。
具体拷贝的文件如下图:
其中,”web发布包”即为Dorado5的Web工程。
三. 修改当前工程的Web.xml文件,添加润乾的报表的相关配置。
添加的配置如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>reportServlet</servlet-name> <servlet-class>com.runqian.report4.view.ReportServlet</servlet-class> <init-param> <param-name>configFile</param-name> <param-value>/WEB-INF/reportConfig.xml</param-value> </init-param> <init-param> <param-name>headless</param-name> <param-value>false</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>reportServlet</servlet-name> <url-pattern>/reportServlet</url-pattern> </servlet-mapping> <taglib> <taglib-uri>/WEB-INF/runqianReport4.tld</taglib-uri> <taglib-location>/WEB-INF/runqianReport4.tld</taglib-location> </taglib> </web-app>
四. 配置WEB-INF/reportConfig.xml文件。
配置润乾的相关参数,根据具体的应用系统需求,按需定制。
详细配置参见润乾相关文档。
通过以上几步,将润乾报表集成到了Dorado的Web工程中。
方案介绍
主要满足业务场景:动态的查询条件,查询报表结果。
设计思路:将查询条件设计为一个视图文件,将报表的展现设计成另外一个jsp文件(可复用)。将这个view与jsp合并到一个jsp中,通过查询条件的view的相关操作(如点击“查询”按钮,将动态的参数传入到展现报表的jsp中来展现具体的报表应用)。
即主要有三个文件组成:
viewRadReport.jsp –查看报表的父jsp,负责包含下面两个页面。
xxxQueryView.xml –自定义当前报表的查询条件
viewReport.view.xml与viewReport.jsp –展现报表的模板jsp(可复用)
下面分别详细设计示例:
1. xxxQueryView.xml示例
如下图的查询条件
将查询条件,设计成一个dorado的视图文件,范例借鉴如下(部分js与具体系统应用有关,仅仅提供借鉴,具体应用系统需要自定义实现与本系统相关的部分):
<?xml version="1.0" encoding="UTF-8"?> <view> <Datasets> <Dataset type="Form" id="dsCondition"> <MasterLink/> <Fields> <Field dropDown="#ddExchange" visible="false" label="交易所代码:" defaultValue="${Session.EXCHANGEID}" dataType="string" name="i_chExchangeID"> <Properties/> <FieldType/> </Field> <Field dropDown="#ddSettlementGroup" label="结算组代码:" defaultValue="${Session.SETTLEMENTGROUPID}" dataType="string" readOnly="false" name="i_chSettlementGroupID"> <Properties/> <FieldType/> </Field> <Field dropDown="#dropdownDate" label="开始日期(YYYYMMDD):" dataType="" name="i_chStartDate"> <Properties/> <Validator type="Required"/> <FieldType validators="length,pattern,required" name="tradingDay"/> </Field> <Field dropDown="#dropdownDate" label="结束日期(YYYYMMDD):" dataType="" name="i_chEndDate"> <Properties/> <Validator type="Required"/> <FieldType validators="length,pattern,required" name="tradingDay"/> </Field> </Fields> <Parameters/> <Properties/> </Dataset> </Datasets> <Controls> <Control type="AutoForm" dataset="dsCondition" id="formCondition"> <FormGroup name="groupCondition" defaultControlWidth="260" dataset="dsCondition" labelWidth="180" title="查询条件"> <Element name="i_chExchangeID" dataset="dsCondition" type="TextEditor" field="i_chExchangeID"> <FieldLabel/> <TextEditor/> </Element> <Element name="i_chSettlementGroupID" dataset="dsCondition" colSpan="2" type="TextEditor" field="i_chSettlementGroupID"> <FieldLabel/> <TextEditor/> </Element> <Element name="i_chStartDate" type="TextEditor" field="i_chStartDate"> <FieldLabel/> <TextEditor/> </Element> <Element name="i_chEndDate" type="TextEditor" field="i_chEndDate"> <FieldLabel/> <TextEditor/> </Element> <Element name="Search" controlAlign="right" showLabel="false" type="Custom" controlId="buttonSearch"> <FieldLabel/> </Element> <Element name="Reset" controlAlign="left" showLabel="false" type="Custom" controlId="buttonReset"> <FieldLabel/> </Element> </FormGroup> </Control> <Control id="buttonSearch" width="80" type="Button" value="查询"> <Events> <Event name="onClick">if(!dsCondition.postRecord()){ return; } var i_chStartDate = dsCondition.getCurrent().getValue("i_chStartDate"); var i_chEndDate = dsCondition.getCurrent().getValue("i_chEndDate"); var i_chExchangeID = dsCondition.getCurrent().getValue("i_chExchangeID"); var i_chSettlementGroupID = dsCondition.getCurrent().getValue("i_chSettlementGroupID"); var i_chOperatorID = "${session.getAttribute('userId')}"; //var raq = Report.raqRelaPath(xmlName); var saveAsName = "XXXX"; var reportframe = document.getElementById("reportframe"); param = "&i_chExchangeID=" + i_chExchangeID + "&i_chSettlementGroupID=" + i_chSettlementGroupID + "&i_chOperatorID=" + i_chOperatorID + "&i_chStartDate=" + i_chStartDate + "&i_chEndDate=" + i_chEndDate + "&saveAsName=" + saveAsName; //alert("../../framework/report/viewReport.jsp?raq=" + raq + param); reportframe.src="../../framework/report/viewReport.jsp?xmlName=" + xmlName + param; </Event> </Events> </Control> <Control id="buttonReset" width="80" type="Button" value="重置"> <Events> <Event name="onClick">init();
 dsCondition.setValue("i_chSettlementGroupID",'${Session.SETTLEMENTGROUPID}');
 </Event> </Events> </Control> </Controls> <Properties/> <Events> <Event name="onLoad">init();
 </Event> <Event name="functions">function init(){
 top.dsSysDate.flushData();
 var sysDate = top.dsSysDate.getValue("sysDate");
 
 // dsCondition.setValue("i_chStartDate",sysDate);
 dsCondition.setValue("i_chStartDate","20120510");
 dsCondition.setValue("i_chEndDate",sysDate);
 }
 </Event> </Events> </view>
具体的步骤,如红色代码注释。
2. ViewReport.jsp示例
主要的负责展现润乾的代码如下,步骤详见代码中的注释:
<%@page import="com.bstek.dorado.common.cache.CacheManager"%> <%@ page contentType="text/html; charset=GBK" %> <%@ taglib uri="http://www.bstek.com/dorado" prefix="d" %> <%@taglib uri="/WEB-INF/runqianReport4.tld" prefix="report" %> <html> <head> <title></title> </head> <body> <d:View config="com.report.viewmodel.viewReport"> <d:SubWindow id="subwindowConfirm"> <table width="100%" height="100%"> <tr heigth = "80%"> <td align="center">没有查询到符合条件的记录!</td> </tr> <tr> <td align="center"><d:Button id="btnEnsure" /></td> </tr> </table> </d:SubWindow> <center> <% // 1、处理由xxxQueryView.xml的buttonSearch按钮传过来的参数 request.setCharacterEncoding("GBK"); String paramStr = ReportUtil.getInstance().generateRequestParameters(request); String reportFileName = ReportUtil.getInstance().getReportFileName(request); request.setAttribute("i_chReportName",ReportUtil.getInstance().getRaqName(request)); String saveAsName =null; if(ParamsPool.get(reportFileName)==null){ saveAsName =new String(request.getParameter("saveAsName").getBytes("Iso-8859-1"), "GBK"); Hashtable<String,String> params = new Hashtable<String,String>(1); params.put("saveAsName", saveAsName); ParamsPool.put(reportFileName, params); }else{ saveAsName=(String)ParamsPool.get(reportFileName).get("saveAsName"); } %> // 2、负责调用润乾的Tag,展现HTML报表 <report:html name="report1" scale="1.4" reportFileName="<%=reportFileName%>" funcBarLocation="top" needPageMark="yes" functionBarColor="#fff5ee" funcBarFontSize="9pt" funcBarFontColor="blue" separator=" " needSaveAsExcel="yes" needSaveAsPdf="yes" needPrint="yes" pageMarkLabel="页号{currpage}/{totalPage}" printLabel="打印" displayNoLinkPageMark="yes" calculateListener="com.sfit.report.common.util.CalculateListener" params="<%=paramStr%>" saveAsName="<%=saveAsName%>" useCache="no" width="-1" exceptionPage="/framework/report/errorPage.jsp"/> </center> <div id=pop style="position:absolute;width:100;height:50;z-index:99;display:none"> <table border=0 bgcolor=#E5E5E5><tr><td><span id="buttonTitle"></span></td></tr></table> </div> </d:View> <% if("true".endsWith(String.valueOf(request.getAttribute("showNoDataWindow")))) { %> <script language="JavaScript"> var sw =getViewModel().getControl("subwindowConfirm"); sw.show(true, true); sw.style.top = "20px"; </script> <% } %> <script language="javascript"> //隐藏"正在加载"的提示 try { parent.hideLoadingTip(); } catch(e){} </script> </body> </html>
3. viewRadReport.jsp负责引用xxxQueryView.xml,并设置显示最后html润乾报表结果的iframe。
<%@ page contentType="text/html; charset=GBK"%> <%@ taglib uri="http://www.bstek.com/dorado" prefix="d"%> <html> <head> <title></title> <meta http-equiv="content-type" content="text/html; charset=GBK" /> </head> <body> <d:View config="XXXX" /> <% String xmlName=new String(request.getParameter("xmlfile").getBytes("Iso-8859-1"), "GB2312"); String reportFileName=xmlName.split("\\.")[1]; String reportStatus=ReportInfo.getReportStatus(xmlName); String xmlConfigName=ReportInfo.getXmlConfigName(xmlName); //设置默认显示报表收藏按钮,当参数showFavorite="1"时不显示 String showFavorite=request.getParameter("showFavorite"); if(showFavorite==null||showFavorite==""){ showFavorite="0"; }else{ if(!showFavorite.equals("1")){ showFavorite="0"; } } if(reportStatus!=null && reportStatus.trim().equals("0")){ %> <script language="javascript"> xmlName='<%=xmlName%>'; reportFileName='<%=reportFileName%>'; </script> <%if(showFavorite.equals("0")){ %> // <iframe scrolling="no" src="../../report/workspace/operateReport.jsp?reportFileName=<%=reportFileName %>" id="opeReportFrame" name="opeReportFrame" frameborder="0" style="width: 100%; height: 18px; overflow: hidden;"></iframe> <%} %> // 动态显示查询条件view 如"xxxQueryView.xml" 的部分 <d:View config='<%=xmlConfigName %>'> <script language="javascript"> hideLoadingTip(); </script> <d:Layout type="border"> <d:AutoForm id="formCondition" /> <table width="100%"> <tr> <td width="20%"> </td> <td width="20%"> </td> </tr> </table> <d:Pane position="center" width="100%"> <script language="javascript"> function OnSrcChanged () { if ("propertyName" in event && event["propertyName"] == "src") { // Internet Explorer if(event.srcElement.src != "" && event.srcElement.src.indexOf("viewExtReport") == -1){ try { showLoadingTip(); } catch(e){} } } } </script> // 动态展现润乾报表的HMTL的iframe(src为显示viewReport.jsp) <iframe src="" id="reportframe" name="reportframe" frameborder="0" style="width: 100%; height: 600px; overflow: hidden;" onpropertychange=OnSrcChanged() ></iframe> </d:Pane> </d:Layout> </d:View> <%}else if(reportStatus!=null && reportStatus.trim().equals("1")){ out.println("<table border=0 cellpadding=0 cellspacing=0 width=100% height=400 ><tr><td align=center valign=center><img src=../../images/lock.gif width=50 height=50 border=0/><font size=5 > <strong>该报表已被冻结</strong></font></td></tr></table>"); }else if(reportStatus!=null && reportStatus.trim().equals("2")){ out.println("<table border=0 cellpadding=0 cellspacing=0 width=100% height=400 ><tr><td align=center valign=center><img src=../../images/delete.gif width=50 height=50 border=0/><font size=5 > <strong>该报表已被删除</strong></font></td></tr></table>"); } else if(reportStatus!=null && reportStatus.trim().equals("3")){ out.println("<table border=0 cellpadding=0 cellspacing=0 width=100% height=400 ><tr><td align=center valign=center><img src=../../images/maintenance.gif width=50 height=50 border=0/><font size=5 > <strong>该报表正在维护中。。。</strong></font></td></tr></table>"); } else{ out.println("<table border=0 cellpadding=0 cellspacing=0 width=100% height=400 ><tr><td align=center valign=center><img src=../../images/exception.gif width=50 height=48 border=0/><font size=5 > <strong>该报表状态异常</strong></font></td></tr></table>"); } %> </body> </html>
页面演示图:
注:此方案部分示例代码,包含具体项目的其他业务要求,请参考具体关于润乾与Dorado结合部分。
Attachments:
Dorado5-Integrate-RunqianReport-002.jpg (image/jpeg)
Dorado5-Integrate-RunqianReport-003.png (image/png)
Dorado5-Integrate-RunqianReport-004.png (image/png)
Dorado5与润乾报表集成教程 By Jacob 2012-07-06-1456.docx (application/vnd.openxmlformats-officedocument.wordprocessingml.document)