`
cxh870510
  • 浏览: 967 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

水晶报表的jsp实现(开发工具:bea weblogic workshop)

阅读更多
最近为客户开发一个mis系统,Java技术,b/s结构.客户要求系统的报表采用水晶报表.
怎样在JSP中实现水晶报表呢?找遍了所有的资料,水晶报表的Web实现倒是很多,但都讲的是微软的.net方案.jsp中如何实现水晶报表的动态显示呢?
经过一段时间的痛苦摸索,现在把我的方案介绍给大家,希望各位大哥批评指正

软件开发网

我的问题:
需要动态的显示水晶报表,并且要根据我传递的一个参数(BH)的值动态的显示数据.并且要可以把水晶报表导出为word,Excel,pdf等格式

我的解决方案:
一:下载crystalreports10for BEAweblogicworkshop
二:安装crystalreports10for BEAweblogicworkshop;
三:如果安装成功,则在C:\ProgramFiles\CommonFiles\CrystalDecisions\2.5\bin目录下,可以找到CRDB_JavaServer.ini文件.该文件很重要,里面的内容
关系到水晶报表如何访问数据库.我的水晶报表采用JDBC的方式访问Oracle数据库,配置如下:

[Common]
PATH=C:\bea\JDK141_05\bin
CLASSPATH=C:\Projects\Drivers\jdbc\classes12.jar;
C:\Projects\Drivers\jdbc\msbase.jar;
C:\Projects\Drivers\jdbc\MSSQLserver.jar;
C:\Projects\Drivers\jdbc\msutil.jar;
C:\Projects\Drivers\jdbc\common.jar;
C:\Projects\Drivers\jdbc\DB2fs.jar;
C:\Projects\Drivers\jdbc\db2java.zip;
C:\Projects\Drivers\jdbc\db2jcc.jar;
C:\Projects\Drivers\jdbc\weblogic.jar;
D:/Progra~1/IBM/WebSph~1/Applic~1\v5.1.1\runtimes\base_v51\lib\naming.jar;
D:/Progra~1/IBM/WebSph~1/Applic~1\v5.1.1\runtimes\base_v51\lib\namingclient.jar;
D:/Progra~1/IBM/WebSph~1/Applic~1\v5.1.1\runtimes\base_v51\lib\namingserver.jar;
D:/Progra~1/IBM/WebSph~1/Applic~1\v5.1.1\runtimes\base_v51\lib\cmImpl.jar;
D:/Progra~1/IBM/WebSph~1/Applic~1\v5.1.1\runtimes\base_v51\lib\j2cImpl.jar;
C:/projects/drivers/jdbc/weblogic.jar;
C:\ProgramFiles\CommonFiles\CrystalDecisions\2.5\bin\CRDBJavaServer.jar;
C:\bea\weblogic81\server\lib\ojdbc14.jar

http://www.mscto.com

IORFileLocation=${TEMP}
JavaServerTimeout=1800
JVMMaxHeap=64000000
JVMMinHeap=32000000



[CRDB_JDBC]
CacheRowSetSize=100
JDBCURL=jdbc:oracle:thin:@192.168.1.99:1521:pwsc
JNDIURL=
JDBCUserName=testuser
JDBCDriverName=oracle.jdbc.driver.OracleDriver
JNDIUserName=weblogic
JNDIConnectionFactory=
JNDIInitContext=/
GenericJDBCDriverBehavior=DB2

[CRDB_XML]
PREREADNBYTE=5000
CacheRowSetSize=100
XMLLOCALURL=
SCHEMALOCALURL=
XMLHTTPURL=
SCHEMAHTTPURL=
USETEMPFile=TRUE

软件开发网


以上是配置文件,需要说明的是:
1:由于我采用的是jdbc的方式访问数据库,所以CLASSPATH中一定要把C:\bea\weblogic81\server\lib\ojdbc14.jar加进去,它是jdbc的驱动
2:[CRDB_JDBC]中的:JDBCURL=jdbc:oracle:thin:@192.168.1.99:1521:pwsc是我要访问的数据库名称.JDBCUserName=testuser是设置用户名,
JDBCDriverName=oracle.jdbc.driver.OracleDriver是jdbc驱动名称



四:在水晶报表编辑器中编辑我要用的报表.由于我需要动态的给报表传递参数,所以我在报表中设置了一个参数字段,水晶报表根据这个参数字段,就可以显示相应的
数据,参数字段命名为BH,在公式编辑器中编写如下代码:
IF{?BH}<>"" THEN
{GG_BPBJ.JLBH}={?BH}
ELSE
{GG_BPBJ.JLBH}="1"OR{GG_BPBJ.JLBH}<>"1"
以上代码的意思是:如果bh参数不为空,则显示{GG_BPBJ.JLBH}等于参数BH的记录,否则显示出所有的记录
(大家可能觉得{GG_BPBJ.JLBH}="1"OR{GG_BPBJ.JLBH}<>"1"很可笑,是啊,我开始是写成"true"了,在水晶报表编辑器中可以很好的运行,但方到web上显示就有问题,万般无奈,只有如此了,:()


五:在weblogicworkshop中新建一个web项目,用右键选择该项目文件夹,选择"新建",选择"crystalreport",则在该web项目根目录下自动新建了一个
crystalreportviewers10目录,里面有显示水晶报表需要的页面元素系统自动添加了开发水晶报表需要的jar包,共有13个jar文件(位于WEB_INF\LIB目录下),
并增加了一些水晶报表专用的标签(在WEB_INF\SRC下)

http://www.mscto.com

六:需要特别注意的是:在WEB_INF下的web.xml文件也随之改动,改动后的web.xml文件如下:
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEweb-appPUBLIC"-//SunMicrosystems,Inc.//DTDWebApplication2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd">
<!--Theweb.xmlfileisaconfigurationfileusedtocontrolthebehaviorofWebLogicserver.
Inmostcases,youwillnotneedtomodifythisfile.Formoreinformationonweb.xml,please
consulttheWeb.xmlDeploymentDescriptorElementschapterofthe"DevelopingWebLogicServer
Applications"documentationonedocs.bea.com.-->
<web-app>
<display-name>WorkshopApplication</display-name>
<context-param>
<param-name>weblogic.httpd.inputCharset./*</param-name>
<param-value>GBK</param-value>
</context-param>
<context-param>
<param-name>crystal_image_uri</param-name>
<param-value>/webmis/crystalreportviewers10</param-value>
</context-param>
<filter> 软件开发网
<filter-name>PageFlowJspFilter</filter-name>
<filter-class>com.bea.wlw.netui.pageflow.PageFlowJspFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PageFlowJspFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.bea.wlw.runtime.core.Servlet.WebappContextListener</listener-class>
</listener>
<!--StandardActionServletConfiguration(withdebugging)-->
<servlet>
<servlet-name>messageServlet</servlet-name>
<servlet-class>com.infoearth.servlets.getTaskServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>com.bea.wlw.netui.pageflow.DynamicSubappActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/jpf-Struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>config/-global</param-name>
<param-value>/WEB-INF/jpf-struts-config--global.xml</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>


<servlet>
<servlet-name>drawImage</servlet-name>
<servlet-class>com.infoearth.drawimage.DrawImageServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>drawImage</servlet-name>
<url-pattern>drawImage</url-pattern>
</servlet-mapping>

http://www.mscto.com

<!--StrutsActionServletMappings-->
<!--NotethatbecauseStrutstakesthe*last*mappinghereastheextensiontoaddto
actionspostedfromforms,wemusthave*.docomeafter*.jpf.-->
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.jpf</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>messageServlet</servlet-name>
<url-pattern>/messageServlet</url-pattern>
</servlet-mapping>
<mime-mapping>
<extension>doc</extension>
<mime-type>application/msword</mime-type>
</mime-mapping>
<mime-mapping>
<extension>xls</extension>
<mime-type>application/msexcel</mime-type>
</mime-mapping>
<welcome-file-list>



<welcome-file>Login/loginController.jpf</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<error-page>
<error-code>500</error-code>
<location>/error.jsp</location>
</error-page>
<!--DefinetheNetUItaglibraryTLDs-->
<taglib>
<taglib-uri>netui-tags-html.tld</taglib-uri>
<taglib-location>/WEB-INF/netui-tags-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>netui-tags-databinding.tld</taglib-uri>
<taglib-location>/WEB-INF/netui-tags-databinding.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>netui-tags-template.tld</taglib-uri>
<taglib-location>/WEB-INF/netui-tags-template.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/crystal-tags-reportviewer.tld</taglib-uri>
<taglib-location>/WEB-INF/crystal-tags-reportviewer.tld</taglib-location>
</taglib>
</web-app>




其中:

<context-param>
<param-name>crystal_image_uri</param-name>
<param-value>/webmis/crystalreportviewers10</param-value>
</context-param>
很关键,它设置了水晶报表专用的crystalreportviewers10路径(第五步中自动建的crystalreportviewers10目录),如果设置错误,将来点击水晶报表自带的
导出和打印按钮是就会报页面错误,并且水晶报表自己的各种翻页,导出等图标也无法正常显示.

软件开发网


七:把编辑好的水晶报表(后缀命为rpt)放在一个目录下(我自己建了一个report目录,专门存放报表文件)
八:可以写程序了:
1.编写ReportInit类.作用:用于传递参数BH.这个类很关键,负责把java的参数值传递到水晶报表文件.
2.在页面流中增加showRpt操作:其实就是实例化一个ReportInit类.
3.编写viewer.jsp文件用来动态显示水晶报表.


后面有我的源代码,请大家批评指正. http://www.mscto.com

存在的问题:
1:水晶报表导出成pdf文件时有问题:汉字显示为乱码,不知何故?此问题困扰我几个月了,没法解决
2:无法把打印/导出页面汉化:在crystalreportviewers10\js目录下有一系列strings命名的js文件,我猜测是用来国际化页面的,可是我修改
strings_zh,js,strings_en.js,没有什么效果.
3:在浏览器中显示水晶报表后,关闭显示页面,该水晶报表依然和数据库连接,(可由select*fromv$session查看oracle的连接数).如果在
viewer.jsp中加入断开连接的语句:
viewer.dispose();
rptSource.dispose();
则只能显示一页报表.并且打印和导出不能工作. 软件开发网

以上问题困扰我很久,虽然并不影响使用,但心中还是不是很爽.希望高手指点.

http://www.mscto.com



源程序:

http://www.mscto.com


/*
*CreateDate:2004-8-14 11:06
*CreateBy:李春雷
*purpose:设置水晶报表的查询参数(目前支持7个参数的查询,有用的参数为编号)
*/




packagecom.infoearth.report;
importcom.crystaldecisions.report.web.viewer.*;
importcom.crystaldecisions.sdk.occa.report.data.*;
importcom.crystaldecisions.reports.reportengineinterface.JPEReportSourceFactory;
importcom.crystaldecisions.sdk.occa.report.reportsource.IReportSourceFactory2;
importcom.crystaldecisions.sdk.occa.report.reportsource.IReportSource;

http://www.mscto.com


publicclassReportInit
{
privateIReportSourcerptSource;

privateFieldsfields;

publicReportInit(){
rptSource=null;
fields=null;
}

publicIReportSourcegetRptsource(){
returnrptSource;
}

publicFieldsgetFields(){
returnfields;
}

public booleansetReport(Stringfname,StringrptID){
//获得查询条件
StringFileName=fname ".rpt";
StringBH=rptID;
Stringpath="report/" FileName;//报表文件路径
try{
IReportSourceFactory2rsf=newJPEReportSourceFactory();
java.util.Localelocaletest=java.util.Locale.CHINA;
rptSource=(IReportSource)rsf.createReportSource(path,localetest);
fields=newFields();
ParameterFieldpfield1=newParameterField();//编号
ParameterFieldpfield2=newParameterField();//单位
ParameterFieldpfield3=newParameterField();//人
ParameterFieldpfield5=newParameterField();//FIELD5
ParameterFieldpfield6=newParameterField();//FIELD6
ParameterFieldpfield4_KSSJ=newParameterField();//开始时间
ParameterFieldpfield4_JSSJ=newParameterField();//结束时间

Valuesvals1=newValues();
Valuesvals2=newValues();
Valuesvals3=newValues();
Valuesvals5=newValues();
Valuesvals6=newValues();
Valuesvals4_KSSJ=newValues();
Valuesvals4_JSSJ=newValues();

软件开发网

ParameterFieldDiscreteValuepfieldDV1=newParameterFieldDiscreteValue();

ParameterFieldDiscreteValuepfieldDV2=newParameterFieldDiscreteValue();
ParameterFieldDiscreteValuepfieldDV3=newParameterFieldDiscreteValue();
ParameterFieldDiscreteValuepfieldDV5=newParameterFieldDiscreteValue();
ParameterFieldDiscreteValuepfieldDV6=newParameterFieldDiscreteValue();
ParameterFieldDiscreteValuepfieldDV4_KSSJ=newParameterFieldDiscreteValue();
ParameterFieldDiscreteValuepfieldDV4_JSSJ=newParameterFieldDiscreteValue();
//设置第一个参数:编号
pfield1.setReportName("");
pfield1.setName("BH");
pfieldDV1.setValue(BH);
pfieldDV1.setDescription("编号");
vals1.add(pfieldDV1);
pfield1.setCurrentValues(vals1);
//设置第二个参数:单位部门
pfield2.setReportName("");
pfield2.setName("DW");
pfieldDV2.setValue("");
pfieldDV2.setDescription("发单部门");
vals2.add(pfieldDV2);



pfield2.setCurrentValues(vals2);
//设置第三个参数:人
pfield3.setReportName("");
pfield3.setName("REN");
pfieldDV3.setValue("");
pfieldDV3.setDescription("申请人、下达人、操作人、负责人等");
vals3.add(pfieldDV3);
pfield3.setCurrentValues(vals3);
//设置第五个查询字段
pfield5.setReportName("");
pfield5.setName("FIELD5");
pfieldDV5.setValue("");
pfieldDV5.setDescription("查询字段5:任务来源线路名称等");
vals5.add(pfieldDV5);
pfield5.setCurrentValues(vals5);
//设置第六个查询字段
pfield6.setReportName("");
pfield6.setName("FIELD6");
pfieldDV6.setValue("");
pfieldDV6.setDescription("查询字段6:更改原因、工作内容等");
vals6.add(pfieldDV6);
pfield6.setCurrentValues(vals6);
//设置开始时间
pfield4_KSSJ.setReportName("");
pfield4_KSSJ.setName("KSSJ");
pfieldDV4_KSSJ.setValue("");
pfieldDV4_KSSJ.setDescription("开始时间");
vals4_KSSJ.add(pfieldDV4_KSSJ);
pfield4_KSSJ.setCurrentValues(vals4_KSSJ);
//设置结束时间
pfield4_JSSJ.setReportName("");
pfield4_JSSJ.setName("JSSJ");
pfieldDV4_JSSJ.setValue("");
pfieldDV4_JSSJ.setDescription("结束时间");
vals4_JSSJ.add(pfieldDV4_JSSJ);
pfield4_JSSJ.setCurrentValues(vals4_JSSJ);
//参数字段和报表关联
fields.add(pfield1);
fields.add(pfield2);
fields.add(pfield3);
fields.add(pfield5);
fields.add(pfield6);
fields.add(pfield4_KSSJ);
fields.add(pfield4_JSSJ);
returntrue;
}
catch(Exceptione){
System.out.println("Class:ReportInit错误:" e);
returnfalse;
}
}
}



//在页面流中增加如下操作:
/**
*@jpf:action
*@jpf:forwardname="false"path="error.jsp"
*@jpf:forwardname="success"path="viewer.jsp"
*/
protectedForwardshowRpt()
{
Stringrptid=this.getRequest().getParameter("rptID");
StringrptBH=this.getRequest().getParameter("rptBH");
StringrptName=dbCtrl.getRptCNName(rptid);
if((rptName!=null)&&(rptBH!=null)){
ReportInitrpt=newReportInit();
booleanresult=rpt.setReport(rptName,rptBH);
if(result==true){
Fieldsfields=rpt.getFields();
IReportSourcerptSource=rpt.getRptsource();
this.getSession().setAttribute("fields",fields);
this.getSession().setAttribute("rptSource",rptSource);
returnnewForward("success");
}else{
returnnewForward("false");
}
}
returnnewForward("false");
}

http://www.mscto.com

//viewer.jsp用来动态显示水晶报表.viewer.jsp的内容如下:

<%@pagelanguage="java"contentType="text/html;charset=utf-8"%>
<%@pageimport="com.crystaldecisions.report.web.viewer.*,
com.crystaldecisions.sdk.occa.report.data.*,
com.crystaldecisions.reports.reportengineinterface.JPEReportSourceFactory,
com.crystaldecisions.sdk.occa.report.reportsource.IReportSourceFactory2,
com.crystaldecisions.sdk.occa.report.reportsource.IReportSource"%>
<%@tagliburi="netui-tags-html.tld"prefix="netui"%>
<%
//fields rptSource
//Stringname=(String)request.getAttribute("nametest");
//System.out.println("name=" name);
%>
<!--../crystalreportviewers10/css/default.css-->
<LINKrel="stylesheet"type="text/css"href="../crystalreportviewers10/css/default.css">
<%
IReportSourcerptSource=(IReportSource)session.getAttribute("rptSource");
Fieldsfields=(Fields)session.getAttribute("fields");
ConnectionInfosconnInfos=newConnectionInfos();
IConnectionInfoconnInfo1=newConnectionInfo();
connInfo1.setUserName("testuser");
connInfo1.setPassword("test");
connInfos.add(connInfo1);
CrystalReportViewerviewer=newCrystalReportViewer();
viewer.setReportSource(rptSource);
viewer.setDatabaseLogonInfos(connInfos);
viewer.setParameterFields(fields);
viewer.setEnableParametERPrompt(true);
viewer.setOwnPage(true);
viewer.setOwnForm(true);
viewer.setPrintMode(CrPrintMode.ACTIVEX);
viewer.setHasExportButton(true);
viewer.setHASPrintButton(true);
viewer.setHasLogo(false);
viewer.processHttpRequest(request,response,getServletConfig().getServletContext(),out);
viewer.refresh();
//viewer.dispose();
//rptSource.dispose();
%>
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics