介紹:
這篇文章是前天看園子裡給的一個鏈接,具體是誰的我忘記了,只記得http://www.codeproject.com/aspnet/ReportViewer.asp這個地址被貼了出來,然後說因為什麼原因就沒翻譯完。我後來看了下正好對自己有用,因為公司裡RS的東西有人在做,而樓下光電部門的BS需求也經常有,並且早就知道有這個東西只是一直沒時間研究,正好找到這個文章,於是就好好的研究了一整個下午,先翻譯一下,然後再補充點心得。
翻譯的過程中盡量在地化了一下,不過保留了原文作者的意思。如果有翻譯不貼切的地方請各位朋友批評指正。
網路上有很多關於SqlServer RS 的服務模式(Server Mode),而我在研究本地模式(Local Mode)確實用了很長的時間,尤其還是有參數呼叫的時候。
之所以要用本地模式而不是伺服器模式,是因為服務模式的客戶端每次請求一個報表的時候,伺服器都要把資料組織成報表然後發送到客戶端,雖然這樣子安全些,但是巨型報表從伺服器到瀏覽器的傳輸會降低其效能。
所以這篇文章是描述如何組織報表並且用ASP.NET2.0的ReportViewer控制項讀取出來的,這裡我們選用的就是本機模式,並且是使用帶參數的預存程序。我使用的是ASP.NET2.0,VisualStudio2005,還有SQLServer2005加Application Block。如果你沒有Microsoft Application Block這個工具,那麼就請把範例中透過SQL Helper呼叫預存程序的程式碼換成SQL Command的就可以了。
這裡我們選用Northwind資料庫,我們的範例展現給使用者的就是讓使用者從下拉清單裡選擇貨品名稱然後在報表裡篩選出資訊來。
第一步,建立帶有參數的預存程序
ALTER PROCEDURE ShowProductByCategory(@CategoryName nvarchar(15) )
AS
SELECT Categories.CategoryName, Products.ProductName,
Products.UnitPrice, Products.UnitsInStock
FROM Categories INNER JOIN Products
ONatego. CategoryID
WHERE CategoryName=@CategoryName
RETURN
第二步,使用DataSet設計器建立一個DataSet下的DataTable
在解決方案管理器介面裡,右鍵App_Code這個檔案佳,選擇」Add New Item」。在彈出的對話框裡選擇”DataSet”,給它取個名,例如DataSetProducts.xsd,然後點選”Add”按鈕。這時候TableAdapter設定工具會自動出現,如果沒有出現或誤將其關閉了的話,在DataSet設計器的任何一個地方點擊滑鼠右鍵,選擇Add,然後再選擇TableAdapter這個工具就會再次出現。根據精靈來建立DataTable,在出現的介面中分別選擇”User existing stored procedures”作為命令類型然後指定”ShowProductByCategory”作為Select命令。
在第一步建立的預存程序在第二步驟就變成了一個DataTable,而報表資料就是透過這個DataTable提供的。
圖一:包含一個DataTable的DataSetProducts.xsd就是報表的資料來源
第三步:建立一個報表檔案
在解決發方案管理器下右鍵選擇Add New Item,然後選擇Report範本。在這個範例裡是直接用預設的名稱Report.rdlc的。 rdl的意思是報表定義語言,c的意思是客戶端(client)。也就是說,rdl是伺服器報表,而rdlc是本地報表。
在工具箱裡把Table拖曳到報表設計窗體中,這個」表」有三個部分,頭,內容和尾巴。一個Table就是一個顯示資料的區域,一個區域顯示的是那些被綁定到的DataSet下的那些資料元素。儘管一個報表是可以擁有很多的區域的,但是,每個區域只能顯示一個DataSet裡的內容。基於這點,我們可以用預存程序來聯合多張表的資料到一個DataSet裡來填入報表。
圖二:工具列裡的專門做報表範本的控件
打開”網站資料來源」窗口,找到”DataSetProducts”資料集,就是在第二步驟創建的那個。展開直到看到叫」ShowProductByCategory」的這個DataTable。這個Table叫這個名字是因為我們之前在TableAdapter設定精靈裡選擇了「Use existing stored procedure」這項,而我們的預存程序的名字就叫ShowProductByCategory。
在網站資料來源視窗中依序把ProductName,UnitPrice和UnitsInStock這三項分別拉到報表設計器裡顯示細節的那一行,也就是中間那行的第一列,第二列和第三列。而且你可以右鍵點擊任何一個顯示細節行中的字段,然後在屬性欄裡找到Format標籤來為Unit Price和Unit In Stock來定義它們的顯示格式。
圖三,網站資料來源窗體顯示了在你程式裡定義的DataSet以及它們所擁有的列
第四步:在ASP.NET2.0頁加入ReportViewer控制項
先把DropDownList控制項拉到表單裡,然後用選擇資料來源選項的方法把Categories裡的CategoryName欄位進行綁定。在其它場景中使用者可以透過其它方法例如文字方塊的方式來輸入參數然後傳遞到儲存過程當中。
然後,把Report View控制項拖曳到表單中,並且設定其Visible屬性為False。還有要注意的地方就是,ASP.NET2.0的Report Viewer提供Excel和PDF的匯出方式,然而實際的過程中我發現,列印出來的報表和你設計時的樣子總是會有點誤差。
圖四,把這頁設定成為StartUp頁
下一步,調出Report Viewer的智慧標籤,選擇剛才建立好的Report.rdlc檔。
圖五,把報表定義檔聯合到Report Viewer控制項裡。
步驟五:寫程式碼實作使用者在下拉方塊選擇不同的名稱然後報表裡顯示不同的資料
這裡不要忘記把Microsoft.Reporting.WebForms命名空間加入到你的code-behind(或code file)檔案裡。
1<PRE lang=cs id=pre1 style="MARGIN-TOP: 0px">using System;
2using System.Data;
3using System.Data.SqlClient;
4using System.Configuration;
5using System.Collections;
6using System.Web;
7using System.Web.Security;
8using System.Web.UI;
9using System.Web.UI.WebControls;
10using System.Web.UI.WebControls.WebParts;
11using System.Web.UI.HtmlControls;
12using Microsoft.ApplicationBlocks.Data;
13using Microsoft.Reporting.WebForms;
14
15public partial class ReportViewerLocalMode : System.Web.UI.Page
16{
17 public string thisConnectionString =
18 ConfigurationManager.ConnectionStrings[
19 "NorthwindConnectionString"].ConnectionString;
20
21 /**//*I used the following statement to show if you have multiple
22 input parameters, declare the parameter with the number
23 of parameters in your application, ex. New SqlParameter[4]; */
24
25 public SqlParameter[] SearchValue = new SqlParameter[1];
26
27 protected void RunReportButton_Click(object sender, EventArgs e)
28 {
29 //ReportViewer1.Visible is set to false in design mode
30 ReportViewer1.Visible = true;
31 SqlConnection thisConnection = new SqlConnection(thisConnectionString);
32 System.Data.DataSet thisDataSet = new System.Data.DataSet();
33 SearchValue[0] = new SqlParameter("@CategoryName",
34 DropDownList1.SelectedValue);
35
36 /**//* Put the stored procedure result into a dataset */
37 thisDataSet = SqlHelper.ExecuteDataset(thisConnection,
38 "ShowProductByCategory", SearchValue);
39
40 /**//*or thisDataSet = SqlHelper.ExecuteDataset(thisConnection,
41 "ShowProductByCategory", dropdownlist1.selectedvalue);
42 if you only have 1 input parameter */
43
44 /**//* Associate thisDataSet (now loaded with the stored
45 procedure result) with the ReportViewer datasource */
46 ReportDataSource datasource = new
47 ReportDataSource("DataSetProducts_ShowProductByCategory",
48 thisDataSet.Tables[0]);
49
50 ReportViewer1.LocalReport.DataSources.Clear();
51 ReportViewer1.LocalReport.DataSources.Add(datasource);
52 if (thisDataSet.Tables[0].Rows.Count == 0)
53 {
54 lblMessage.Text = "Sorry, no products under this category!";
55 }
56
57 ReportViewer1.LocalReport.Refresh();
58 }
59}</PRE>
第六步:執行報表
按F5鍵,點選”Run Report」按鈕執行報表。
圖六,運行報表
最後要確定ReportViewer被引入到網站中,並且要配置下web.config文件,它有可能是以下的格式:
<httpHandlers>
<add path="Reserved.ReportViewerWebControl.axd" verb="*"
type="Microsoft.Reporting.WebForms.HttpHandler,
Microsoft.ReportViewer.WebForms,
Version=8.0.0.0, Culture=neutral,
PublicKeyToken=?? ???????????"
validate="false" />
</httpHandlers>
當把有ReportViewer控制項的網站專案部署到別的伺服器的時候,你需要把C:Program FilesMicrosoft Visual Studio 8SDKv2.0BootStrapperPackagesReportViewerReportViewer.exe這個檔案拷貝出來,然後在目標伺服器運行一下。
翻譯心得:似乎做過的翻譯中這個是最簡單的了,不過可能也是作者說的比較簡介明了。
學習心得:作者闡述了兩種ReportViewer能接受的報表方式並且做了簡單的分析。不過在實際專案中用Server Mode的可能會更多吧,Local Mode做一些不是規模太大或太複雜的報表還是可以的。
公司裡有專門做RS的我知道,據說做就要做一周,運行的時候看編寫的質量,十分鐘是正常的,而超過三十分鐘的話就可能需要考慮改算法了。聽起來好恐怖,呵呵,不過,如果能用到樓下光電部門的報表需求的話,我想要比以前GridView to Excel的方式更舒服一些。
如果這個能研究明白的話打算做一個專門的入門視頻講解來幫助更多的人了解這個控制。