實(shí)例講解:ASP.NET水晶報(bào)表教程
報(bào)表是應(yīng)用程序中不可缺少的部分,一張好的報(bào)表,能直觀地讓人把握數(shù)據(jù)的情況,對(duì)決策起到重要作用。那么,如果才能更快捷、更高效地實(shí)現(xiàn)報(bào)表呢?本文以一個(gè)三層結(jié)構(gòu)的ASP.NET程序?yàn)槔?,介紹如何使用crystalreport,來制作一份報(bào)表,其中介紹了不少ASP.NET水晶報(bào)表的技巧。
在這個(gè)例子中,我們?cè)O(shè)想的應(yīng)用要為一個(gè)銷售部門制作一份報(bào)表,管理者可以查看某段時(shí)間之內(nèi)的銷售情況,以列表或者折線圖的形式反映出銷售的趨勢(shì)。我們將使用SQLServer 2000做為數(shù)據(jù)庫,使用VB.NET編寫中間層邏輯層,而前端的表示層使用C#。
介紹ASP.NET水晶報(bào)表教程之前,我們先來看下數(shù)據(jù)庫的結(jié)構(gòu)。

其中,tbitem表中存放的是每張訂單中所訂購的貨品,tbsales存放的是每張訂單,tblsalesperson是銷售員表,存放該出版社的每位銷售員。
接下來,使用SQLServer 2000來創(chuàng)建這些表。表的結(jié)構(gòu)如下所示:
- CREATETABLE[dbo].[tblItem](
- [ItemId][int]NOTNULL,
- [Description][varchar](50)NOTNULL
- )ON[PRIMARY]
- CREATETABLE[dbo].[tblSalesPerson](
- [SalesPersonId][int]NOTNULL,
- [UserName][varchar](50)NOTNULL,
- [Password][varchar](30)NOTNULL
- )ON[PRIMARY]
- CREATETABLE[dbo].[tblSales](
- [SaleId][int]IDENTITY(1,1)NOTNULL,
- [SalesPersonId][int]NOTNULL,
- [ItemId][int]NOTNULL,
- [SaleDate][datetime]NOTNULL,
- [Amount][int]NOTNULL
- )ON[PRIMARY]
并且用以下的代碼創(chuàng)建表之間的約束關(guān)系。
- ALTERTABLEtblItem
- ADDCONSTRAINTPK_ItemId
- PRIMARYKEY(ItemId)
- GO
- ALTERTABLEtblSalesPerson
- ADDCONSTRAINTPK_SalesPersonId
- PRIMARYKEY(SalesPersonId)
- GO
- ALTERTABLEtblSales
- ADDCONSTRAINTFK_ItemId
- FOREIGNKEY(ItemId)REFERENCEStblItem(ItemId)
- GO
- ALTERTABLEtblSales
- ADDCONSTRAINTFK_SalesPersonId
- FOREIGNKEY(SalesPersonId)REFERENCEStblSalesPerson(SalesPersonId)
- GO
ASP.NET水晶報(bào)表教程之創(chuàng)建中間邏輯層
在中間邏輯層組件中,我們?yōu)槊恳粡埍矶紕?chuàng)建兩個(gè)類。比如,對(duì)于tblItems表,創(chuàng)建item和items類。Item類中記錄每件銷售的貨品的詳細(xì)情況,而items表則記錄所有銷售的貨品并且有增加貨品的方法。這樣,就存在下面的六個(gè)類:
Item and Items
SalesPerson and SalesPersons
Sale and Sales
接下來,看一下每個(gè)類中的屬性:
Item類
包括如下屬性
ItemId (貨品id編號(hào))
Description (貨品的描述)
Items
有一個(gè)方法,將根據(jù)item的編號(hào)返回一個(gè)item對(duì)象
PublicFunctionGetAllItems()AsCollections.ArrayList
SalesPerson
該類有以下三個(gè)屬性:
SalesPersonId(銷售員編號(hào))
Name(姓名)
Password(密碼)
SalesPersons
有一個(gè)方法,根據(jù)銷售員登陸時(shí)輸入的用戶名和密碼,在數(shù)據(jù)庫中,驗(yàn)證銷售員的登陸是否正確,如果正確,則返回零。
PublicFunctionValidateUser(strUserNameasString,strPasswordasString)AsInteger
Sale
有如下5個(gè)屬性
SaleId
SalesPersonId
ItemId
SaleDate
Amount
Sales
有兩個(gè)方法,其中g(shù)etsales根據(jù)輸入的參數(shù)返回sales對(duì)象的集合
PublicFunctionGetSales(OptionalnSaleIdAsInteger=0,OptionalnSalesPersonIdAsInteger=0,OptionalnItemIdAsInteger=0)AsCollections.ArrayList
還有一個(gè)addsales方法,用于增加一張訂單
PublicFunctionAddSale(objSaleAsSale)
#p#
ASP.NET水晶報(bào)表教程之創(chuàng)建表現(xiàn)層頁面
接下來,開始創(chuàng)建表現(xiàn)層頁面。首先,要?jiǎng)?chuàng)建一個(gè)可以給銷售員登陸的頁面,如下圖所示。
在銷售員成功登陸后,可以給銷售員輸入某樣貨品銷售的數(shù)量,如下圖:
此外,為了給業(yè)務(wù)主管看到某個(gè)時(shí)期的銷售情況,創(chuàng)建如下頁面。
其中,業(yè)務(wù)主管可以選擇查看某樣貨品在某個(gè)時(shí)期(選擇開始日期,結(jié)束日期)的銷售情況,以圖表方式顯示。
這里特別值得一提的是,日歷控件的使用。在頁面中放置日歷控件后,設(shè)置如下代碼:
- <inputtype="image"onclick="Page_ValidationActive=false;"src="datepicker.gif"alt="ShowCalender"runat="server"onserverclick="ShowCal1"id="ImgCal1"name="ImgCal1">
這里設(shè)置page_validationactive參數(shù)為false,所以不需要重新提交頁面,并且,在onserverclick事件中,設(shè)置處理的代碼,如下所示:
- publicvoidShowCal1(Objectsender,System.Web.UI.ImageClickEventArgse)
- {//顯示日歷控件
- DtPicker1.Visible=true;
- }
當(dāng)用戶選擇了相關(guān)的日期后,在文本框中可以獲得相關(guān)的日期:
- privatevoidDtPicker1_SelectionChanged(objectsender,System.EventArgse)
- {
- txtStartDate.Text=DtPicker1.SelectedDate.ToShortDateString();
- DtPicker1.Visible=false;
- }
在提交的頁面中,處理的代碼如下:
- privatevoidbSubmit_ServerClick(objectsender,System.EventArgse)
- {
- Response.Redirect("ViewReport.aspx?ItemId="+cboItemType.SelectedItem.Value+"&StartDate="+txtStartDate.Text+"&EndDate="+txtEndDate.Text);}
在提交頁面后,將跳轉(zhuǎn)到瀏覽報(bào)表的頁面viewreport.aspx,傳入相關(guān)的參數(shù),如貨品ID,開始和結(jié)束日期。
ASP.NET水晶報(bào)表教程之創(chuàng)建報(bào)表
首先,往窗體中添加水晶報(bào)表控件,之后,就可以用水晶報(bào)表的報(bào)表設(shè)計(jì)器設(shè)計(jì)一份報(bào)表了。新建一個(gè)水晶報(bào)表文件類型,命名為itemreport.rpt,接著使用報(bào)表設(shè)計(jì)專家,并選擇設(shè)計(jì)標(biāo)準(zhǔn)型的報(bào)表,點(diǎn)下一步,出現(xiàn)如下畫面:

我們選擇使用ADO類型的數(shù)據(jù),在彈出的窗口中,設(shè)置好sqlserver的登陸名,登陸密碼,選擇好數(shù)據(jù)庫后,選擇在報(bào)表中使用tblsales表,如下圖:
![]() |
接著選Next,在要在報(bào)表中顯示的字段中,選擇SaleDate和Amount。之后,一直選NEXT,忽略其他相關(guān)設(shè)置,***,在圖表類型中選擇折線圖,如下圖:
![]() |
***點(diǎn)擊finish,可以看到如下的報(bào)表:
![]() |
再次選擇報(bào)表專家,在彈出的窗口中選擇數(shù)據(jù)頁,在數(shù)據(jù)可用字段中選擇salesdate,并且可以在文本頁中,設(shè)置適當(dāng)?shù)膱?bào)表標(biāo)題。

由于要根據(jù)輸入的日期,貨品參數(shù)來動(dòng)態(tài)顯示報(bào)表,因此我們要設(shè)置參數(shù)字段。在報(bào)表設(shè)計(jì)器中,在字段資源管理器中,選擇參數(shù)字段,鼠標(biāo)右擊選擇“新建”,新建如下三個(gè)參數(shù)字段。
名稱: | 類型: |
ItemId | Number |
StartDate | Date |
EndDate | Date |
***,要設(shè)置相關(guān)的查詢公式,在除報(bào)表頁眉的區(qū)域,鼠標(biāo)右鍵點(diǎn)擊,在彈出菜單中選擇“報(bào)表|編輯選擇公式|記錄”,輸入如下的公式:

在上面的公式編輯器中,分為左中右三部分,左邊的是報(bào)表的字段,中間的是相關(guān)的功能函數(shù),最右邊的是運(yùn)算符,雙擊其中選中的部分,則可以添加到下部的公式顯示區(qū)域中。***,保存建立的公式。
#p#
ASP.NET水晶報(bào)表教程之在程序中使用報(bào)表
接下來,我們可以在程序中用代碼處理和報(bào)表的連接過程。首先,在工程項(xiàng)目中,增加如下的兩個(gè)命名空間的引用(注意,在代碼中也必須用using引入它們):
- CrystalDecisions.CrystalReports.Engine
- CrystalDecisions.Shared
在viewreport.aspx的Page_load事件中,加入以下代碼
- //接收傳遞的參數(shù)
- nItemId=int.Parse(Request.QueryString.Get("ItemId"));
- strStartDate=Request.QueryString.Get("StartDate");
- strEndDate=Request.QueryString.Get("EndDate");
- //聲明報(bào)表的數(shù)據(jù)對(duì)象
- CrystalDecisions.CrystalReports.Engine.DatabasecrDatabase;CrystalDecisions.CrystalReports.Engine.TablecrTable;
- TableLogOnInfodbConn=newTableLogOnInfo();
- //創(chuàng)建報(bào)表對(duì)象opt
- ReportDocumentoRpt=newReportDocument();
- //加載已經(jīng)做好的報(bào)表
- oRpt.Load("F:\\aspnet\\WroxWeb\\ItemReport.rpt");
- //連接數(shù)據(jù)庫,獲得相關(guān)的登陸信息
- crDatabase=oRpt.Database;
- //定義一個(gè)arrtables對(duì)象數(shù)組
- object[]arrTables=newobject[1];
- crDatabase.Tables.CopyTo(arrTables,0);
- crTable=(CrystalDecisions.CrystalReports.Engine.Table)arrTables[0];dbConn=crTable.LogOnInfo;
- //設(shè)置相關(guān)的登陸數(shù)據(jù)庫的信息
- dbConn.ConnectionInfo.DatabaseName="WroxSellers";dbConn.ConnectionInfo.ServerName="localhost";
- dbConn.ConnectionInfo.UserID="sa";
- dbConn.ConnectionInfo.Password="test";
- //將登陸的信息應(yīng)用于crtable表對(duì)象
- crTable.ApplyLogOnInfo(dbConn);
- //將報(bào)表和報(bào)表瀏覽控件綁定
- crViewer.ReportSource=oRpt;
- //傳遞參數(shù)
- setReportParameters();
在上面的代碼中,首先接收了日期,貨品編號(hào)等參數(shù),并實(shí)例化了Database,Table和TableLogOnInfo三個(gè)類,它們是用來在運(yùn)行時(shí),建立報(bào)表和數(shù)據(jù)庫的連接必需的。再使用
oRpt.Load("F:\\aspnet\\WroxWeb\\ItemReport.rpt");
來裝載已經(jīng)做好了的報(bào)表。
在裝載完報(bào)表后,將數(shù)據(jù)庫中要使用的表復(fù)制到一個(gè)對(duì)象數(shù)組中去,并選擇對(duì)象數(shù)組中的***個(gè)表元素,將其轉(zhuǎn)換為水晶報(bào)表的報(bào)表對(duì)象。接著,再設(shè)置LOGONINFO中的登陸數(shù)據(jù)庫的信息。***,將報(bào)表源與報(bào)表瀏覽控件綁定。
#p#
ASP.NET水晶報(bào)表教程之傳遞參數(shù)到ASP.NET水晶報(bào)表
定義一個(gè)新的過程,setReportParameters(),代碼如下:
- privatevoidsetReportParameters()
- {
- //alltheparameterfieldswillbeaddedtothiscollection
- ParameterFieldsparamFields=newParameterFields();
- //theparameterfieldstobesenttothereport
- ParameterFieldpfItemId=newParameterField();
- ParameterFieldpfStartDate=newParameterField();
- ParameterFieldpfEndDate=newParameterField();
- //設(shè)置在報(bào)表中,將要接受的參數(shù)字段的名稱
- pfItemId.ParameterFieldName="ItemId";
- pfStartDate.ParameterFieldName="StartDate";
- pfEndDate.ParameterFieldName="EndDate";
- ParameterDiscreteValuedcItemId=newParameterDiscreteValue();
- ParameterDiscreteValuedcStartDate=newParameterDiscreteValue();ParameterDiscreteValuedcEndDate=newParameterDiscreteValue();
- dcItemId.Value=nItemId;
- dcStartDate.Value=DateTime.Parse(strStartDate);
- dcEndDate.Value=DateTime.Parse(strEndDate);
- pfItemId.CurrentValues.Add(dcItemId);
- pfStartDate.CurrentValues.Add(dcStartDate);pfEndDate.CurrentValues.Add(dcEndDate);
- paramFields.Add(pfItemId);
- paramFields.Add(pfStartDate);
- paramFields.Add(pfEndDate);
- //將參數(shù)集合綁定到報(bào)表瀏覽控件
- crViewer.ParameterFieldInfo=paramFields;
- }
現(xiàn)在來解釋一下上面的代碼。在水晶報(bào)表中,瀏覽器控件有一個(gè)屬性parameterfieldsinfo,該屬性可以通過綁定parameterfields類型的集合,將相關(guān)的參數(shù)的實(shí)際數(shù)值傳遞到報(bào)表。Parameterfields類型集合通過add的方法,接收Parameterfield類型的對(duì)象。因此,我們先為itemid,startdate,enddate三個(gè)參數(shù)創(chuàng)建parameterfield類型的對(duì)象,并且設(shè)置它們對(duì)應(yīng)報(bào)表中接受參數(shù)的名稱:
- ParameterFieldsparamFields=newParameterFields();
- ParameterFieldpfItemId=newParameterField();
- ParameterFieldpfStartDate=newParameterField();
- ParameterFieldpfEndDate=newParameterField();
- //設(shè)置在報(bào)表中,將要接受的參數(shù)字段的名稱
- pfItemId.ParameterFieldName="ItemId";
- pfStartDate.ParameterFieldName="StartDate";
- pfEndDate.ParameterFieldName="EndDate";
接著,可以為這些參數(shù)字段設(shè)置具體的值了,但由于parameterfield必須接受ParameterDiscreteValue類型的對(duì)象,所以,再創(chuàng)建相關(guān)的實(shí)例:
- ParameterDiscreteValuedcItemId=newParameterDiscreteValue();
- ParameterDiscreteValuedcStartDate=newParameterDiscreteValue();
- ParameterDiscreteValuedcEndDate=newParameterDiscreteValue();
- dcItemId.Value=nItemId;
- dcStartDate.Value=DateTime.Parse(strStartDate);
- dcEndDate.Value=DateTime.Parse(strEndDate);
***,就可以在三個(gè)parameterfield的對(duì)象中的currentvalues中設(shè)置它們的值,并往paramFields集合中加進(jìn)這三個(gè)parameterfield對(duì)象。
運(yùn)行的結(jié)果如下。
![]() |
以上ASP.NET水晶報(bào)表教程相關(guān)程序在VS.NET2003,crystalreport9以上版本可以正確運(yùn)行。
【編輯推薦】
- 淺談ASP.NET報(bào)表控件
- 概述ASP.NET水晶報(bào)表
- VS.Net中的水晶報(bào)表的應(yīng)用
- VS.NET 2002下水晶報(bào)表的安裝與部署
- ASP.NET 2.0部署WEB應(yīng)用程序淺析
- ASP.NET中的數(shù)據(jù)源控件