水晶報表的jsp實現(開發工具:bea weblogic workshop)

來源:互聯網
上載者:User

最近為客戶開發一個mis系統,java技術,b/s結構.客戶要求系統的報表採用水晶報表.
怎樣在jsp中實現水晶報表呢?找遍了所有的資料,水晶報表的web實現倒是很多,但都講的是微軟的.net方案.jsp中如何?水晶報表的動態顯示呢?
經過一段時間的痛苦摸索,現在把我的方案介紹給大家,希望各位大哥批評指正

我的問題:
需要動態顯示水晶報表,並且要根據我傳遞的一個參數(BH)的值動態顯示資料.並且要可以把水晶報表匯出為word,excel,pdf等格式

我的解決方案:
一:下載 crystal reports 10 for  BEA weblogic workshop
二:安裝crystal reports 10 for  BEA weblogic workshop;
三:如果安裝成功,則在C:/Program Files/Common Files/Crystal Decisions/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:/Program Files/Common Files/Crystal Decisions/2.5/bin/CRDBJavaServer.jar;
C:/bea/weblogic81/server/lib/ojdbc14.jar

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上顯示就有
問題,萬般無奈,只有如此了,:( )

五:在weblogic workshop中建立一個web項目,用右鍵選擇該專案檔夾,選擇"建立",選擇"crystal report",則在該web項目根目錄下自動建立了一個
crystalreportviewers10目錄,裡面有顯示水晶報表需要的頁面元素系統自動添加了開發水晶報表需要的jar包,共有13個jar檔案(位於WEB_INF/LIB目錄下),
並增加了一些水晶報表專用的標籤(在WEB_INF/SRC下)

六:需要特別注意的是:在WEB_INF下的web.xml檔案也隨之改動,改動後的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">
<!-- The web.xml file is a configuration file used to control the behavior of WebLogic server.
In most cases, you will not need to modify this file. For more information on web.xml, please
consult the Web.xml Deployment Descriptor Elements chapter of the "Developing WebLogic Server
Applications" documentation on edocs.bea.com. -->
<web-app>
  <display-name>Workshop Application</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>
  <!-- Standard Action Servlet Configuration (with debugging) -->
  <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>

  <!-- Struts Action Servlet Mappings -->
  <!-- Note that because Struts takes the *last* mapping here as the extension to add to
         actions posted from forms, we must have *.do come after *.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>
  <!-- Define the NetUI tag library TLDs -->
  <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檔案用來動態顯示水晶報表.

後面有我的原始碼,請大家批評指正.

存在的問題:
1:水晶報表匯出成pdf檔案時有問題:漢字顯示為亂碼,不知何故?此問題困擾我幾個月了,沒法解決
2:無法把列印/匯出頁面漢化:在crystalreportviewers10/js目錄下有一系列strings命名的js檔案,我猜測是用來國際化頁面的,可是我修改
 strings_zh,js,strings_en.js,沒有什麼效果.
3:在瀏覽器中顯示水晶報表後,關閉顯示頁面,該水晶報表依然和資料庫連接,(可由select * from v$session 查看oracle的串連數).如果在
viewer.jsp中加入中斷連線的語句:
viewer.dispose();
rptSource.dispose();
則只能顯示一頁報表.並且列印和匯出不能工作.

以上問題困擾我很久,雖然並不影響使用,但心中還是不是很爽.希望高手指點.

來源程式:

/*
 * Create Date: 2004-8-14  11:06
 * Create By: 李春雷
 * purpose:設定水晶報表的查詢參數(目前支援7個參數的查詢,有用的參數為編號)
 */

package com.infoearth.report;
import com.crystaldecisions.report.web.viewer.*;
import com.crystaldecisions.sdk.occa.report.data.*;
import com.crystaldecisions.reports.reportengineinterface.JPEReportSourceFactory;
import com.crystaldecisions.sdk.occa.report.reportsource.IReportSourceFactory2;
import com.crystaldecisions.sdk.occa.report.reportsource.IReportSource;

public class ReportInit
{
    private IReportSource rptSource;
   
    private Fields fields;
   
    public ReportInit(){
        rptSource = null;
        fields = null;
        }
   
    public IReportSource getRptsource(){
        return rptSource;
        }
       
    public Fields getFields(){
        return fields;
        }
       
    public  boolean setReport(String fname,String rptID){
         //獲得查詢條件
        String FileName = fname + ".rpt";
        String BH = rptID;
        String path = "report/"+FileName; //報表檔案路徑        
        try{                       
            IReportSourceFactory2 rsf = new JPEReportSourceFactory();
            java.util.Locale localetest = java.util.Locale.CHINA;
            rptSource = (IReportSource)rsf.createReportSource(path,localetest);
            fields = new Fields();
            ParameterField pfield1 = new ParameterField(); //編號
            ParameterField pfield2 = new ParameterField(); //單位
            ParameterField pfield3 = new ParameterField(); //人
            ParameterField pfield5 = new ParameterField(); //FIELD5
            ParameterField pfield6 = new ParameterField(); //FIELD6
            ParameterField pfield4_KSSJ = new ParameterField(); //開始時間
            ParameterField pfield4_JSSJ = new ParameterField(); //結束時間

            Values vals1 = new Values();
            Values vals2 = new Values();
            Values vals3 = new Values();
            Values vals5 = new Values();
            Values vals6 = new Values();
            Values vals4_KSSJ = new Values();
            Values vals4_JSSJ = new Values();

            ParameterFieldDiscreteValue pfieldDV1 = new ParameterFieldDiscreteValue();
            ParameterFieldDiscreteValue pfieldDV2 = new ParameterFieldDiscreteValue();
            ParameterFieldDiscreteValue pfieldDV3 = new ParameterFieldDiscreteValue();
            ParameterFieldDiscreteValue pfieldDV5 = new ParameterFieldDiscreteValue();
            ParameterFieldDiscreteValue pfieldDV6 = new ParameterFieldDiscreteValue();
            ParameterFieldDiscreteValue pfieldDV4_KSSJ = new ParameterFieldDiscreteValue();
            ParameterFieldDiscreteValue pfieldDV4_JSSJ = new ParameterFieldDiscreteValue();
            //設定第一個參數:編號
            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);
            return true;
            }
        catch(Exception e){               
            System.out.println("Class:ReportInit錯誤:"+e);
            return false;
            }      
    }       
}

 

//在頁面流中增加如下操作:
    /**
     * @jpf:action
     * @jpf:forward name="false" path="error.jsp"
     * @jpf:forward name="success" path="viewer.jsp"
     */
    protected Forward showRpt()
    {
        String rptid = this.getRequest().getParameter("rptID");       
        String rptBH = this.getRequest().getParameter("rptBH");
        String rptName = dbCtrl.getRptCNName(rptid);
        if ((rptName!=null) && (rptBH!=null)) {
            ReportInit rpt = new ReportInit();
            boolean result = rpt.setReport(rptName, rptBH);
            if(result==true) {
                Fields fields = rpt.getFields();
                IReportSource rptSource = rpt.getRptsource(); 
                this.getSession().setAttribute("fields", fields);
                this.getSession().setAttribute("rptSource", rptSource); 
                return new Forward("success");
            } else {
                return new Forward("false");
            }
        }
        return new Forward("false");
    }

 

    //viewer.jsp用來動態顯示水晶報表.viewer.jsp的內容如下:
   
<%@ page language="java" contentType="text/html;charset=utf-8"%>
<%@ page import= "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"%>
<%@ taglib uri="netui-tags-html.tld" prefix="netui"%>
<%
//fields  rptSource
//String name = (String)request.getAttribute("nametest");
//System.out.println("name="+name);
%>
<!-- ../crystalreportviewers10/css/default.css -->
<LINK rel="stylesheet" type="text/css" href="../crystalreportviewers10/css/default.css">
<%
IReportSource rptSource = (IReportSource)session.getAttribute("rptSource");
Fields fields = (Fields) session.getAttribute("fields");
ConnectionInfos connInfos = new ConnectionInfos();
IConnectionInfo connInfo1 = new ConnectionInfo();
connInfo1.setUserName("testuser");
connInfo1.setPassword("test");
connInfos.add(connInfo1);
CrystalReportViewer viewer = new CrystalReportViewer();
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();
%>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.