Dorado 5 : Dorado5与润乾报表集成教程(EX)

前言

本教程主要介绍了如何通过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(&quot;i_chStartDate&quot;);
var i_chEndDate = dsCondition.getCurrent().getValue(&quot;i_chEndDate&quot;);
var i_chExchangeID = dsCondition.getCurrent().getValue(&quot;i_chExchangeID&quot;);
var i_chSettlementGroupID = dsCondition.getCurrent().getValue(&quot;i_chSettlementGroupID&quot;);
var i_chOperatorID = &quot;${session.getAttribute('userId')}&quot;;
//var raq = Report.raqRelaPath(xmlName);
var saveAsName = &quot;XXXX&quot;;
var reportframe = document.getElementById(&quot;reportframe&quot;);
param = &quot;&amp;i_chExchangeID=&quot; + i_chExchangeID 
    + &quot;&amp;i_chSettlementGroupID=&quot; + i_chSettlementGroupID
    + &quot;&amp;i_chOperatorID=&quot; + i_chOperatorID
    + &quot;&amp;i_chStartDate=&quot; + i_chStartDate
    + &quot;&amp;i_chEndDate=&quot; + i_chEndDate
    + &quot;&amp;saveAsName=&quot; + saveAsName;
//alert(&quot;../../framework/report/viewReport.jsp?raq=&quot; + raq + param);
reportframe.src=&quot;../../framework/report/viewReport.jsp?xmlName=&quot; + xmlName + param;
</Event>
      </Events>
    </Control>
    <Control id="buttonReset" width="80" type="Button" value="重置">
      <Events>
        <Event name="onClick">init();&#xD;
dsCondition.setValue(&quot;i_chSettlementGroupID&quot;,'${Session.SETTLEMENTGROUPID}');&#xD;
</Event>
      </Events>
    </Control>
  </Controls>
  <Properties/>
  <Events>
    <Event name="onLoad">init();&#xD;
</Event>
    <Event name="functions">function init(){&#xD;
	top.dsSysDate.flushData();&#xD;
	var sysDate = top.dsSysDate.getValue(&quot;sysDate&quot;);&#xD;
&#xD;
	// dsCondition.setValue(&quot;i_chStartDate&quot;,sysDate);&#xD;
	dsCondition.setValue(&quot;i_chStartDate&quot;,&quot;20120510&quot;);&#xD;
	dsCondition.setValue(&quot;i_chEndDate&quot;,sysDate);&#xD;
}&#xD;
</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="&nbsp;&nbsp;" 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%">
							&nbsp;
						</td>
						<td width="20%">
							&nbsp;
						</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结合部分。