轉:利用reportviewer與C#產生報表

來源:互聯網
上載者:User

關於編寫報表,職場中的人相信都會有所感慨,一份整潔、優美的報表會為你在上司面前增色不少,甚至加薪 ——大家都喜歡加薪,對吧?在本文中,將向大家介紹怎樣利用MS Reporting Services 2005來建立一份報表,並用一個C#小程式來產生它。

  本文假定讀者已對Visual Studio 2005 IDE有了初步的瞭解,並能用C#編寫代碼,懂不懂MS Reporting Services都對理解本文沒有關係,當然了,之前寫過類似的報表,將有助於你更快地上手。好了,捲起袖子,準備開始吧!

  請看圖1,這份報表有多複雜?猜猜它需要多少時間完成?就複雜而言,它只是一份簡單的、從NorthWind->Products (SQL Server 2000)中提取出來的報表;就時間而言,相信不會花你一整個小時吧。

 

圖1

  下面,我們開始建立報表,首先要編寫一個產生報表的C#小程式。

  第一步:建立一個Windows應用程式

  選擇檔案菜單,建立-工程,從工程類型中選擇C#,從右方對話方塊中選擇Windows應用程式;在名稱欄中,最好用一個表明程式用途的名字;在位置欄中,寫明你想要儲存的目錄。完成之後,工程中會有一個Form1,我們就從對它的表單設計器開始講解。

  像下面這樣修改Form1的屬性,當然也可以依個人喜好修改其他的屬性:

  Form1.Text = "MS Reporting Services 101 with Smart Client"
  Form1.Size = 750, 300

  第二步:為表單(Form)添加報表檢視器(Report Viewer)

  什麼是報表檢視器,就像看DVD碟時需要一部DVD播放機一樣,我們需要一個報表檢視器來預覽報表。
對初寫報表的人來說,報表檢視器可以說是賦予了報表生命,它不僅可預覽輸出,還可協助將報表資訊產生各種格式(PDF或Excel等等),列印出來更不在話下。

  [span] 請按如下步驟在Form1上放置好報表檢視器控制項:
  依次找到工具箱(ToolBox)-資料(Data)-報表檢視器(ReportViewer),並把它拖到Form1上。這會建立一個名為reportViewer1新的執行個體。
通過設定reportViewer1.Dock = Fill,報表檢視器將會填充表單的整個地區,以顯示報表。
在完成第一步與第二步之後,工程看起來應該2所示:

 

圖2

  第三步:為工程添加資料集(DataSet)

  資料集是伴隨報表檢視器而來的,它儲存並提供從資料來源而來的未經處理資料,我們便可對這些未經處理資料進行處理或在C#程式中輸出。

  請依照如下步驟添加資料集:
  從解決方案資源總管中選擇添加-新項目-資料集,將其名稱DataSet1修改dsProduct,並單擊添加按鈕完成。

  添加一個資料表到新建立的資料集中。資料表實質上是用來載入報表資料的,在設計報表時,將會用到DataSet/DataTable中的相關資訊。

  以下為添加資料表到資料集(dsProduct)中:
  從解決方案資源總管中雙擊dsProduct,將會開啟設計檢視,按右鍵並選擇添加-資料表。接著,單擊表頭修改名稱為dtProductList,3:

 

圖3

  接下來開始為資料表(dtProductList)添加列,此時的設計檢視應該4所示。按右鍵dtProductList並選擇添加——列(Column)。

 

圖4

  重複以上步驟添加以下列:

  ProductName (String)
  QuantityPerUnit (String)
  UnitPrice (Double)
  UnitsInStock (Double)
  UnitValue (Double):一個基於UnitsInStock * UnitPrice的計算域

  在添加列時,預設為String資料類型,添加完之後請轉到屬性視窗,修改相應的列為Double類型。
請看圖5,現在的資料表看上去應該就像這樣子了。同時,你也可查看屬性視窗來修改資料類型。

 

圖5

  第四步:為工程添加報表

  到目前為止,我們已經建立了工程,添加了報表檢視器與資料集;現在,是時候建立一份整潔、優美的報表了。

  需按照以下步驟產生報表(rptProductList.rdlc):
  從解決方案資源總管中選擇添加-新項目-報表,把名稱Report1.rdlc修改為rptProductList.rdlc,並單擊添加按鈕完成。
  工程可能會像圖6這樣;而添加完報表之後,就可以開始使用資料集(DataSet)進行設計了。

 

圖6

  無論你是第設計一次報表的新手,或是曆經沙場老手,都必須與以下三種最基本的報表地區打交道:頁首(或叫表頭)、頁尾、表體。一般來說,報表在設計時,就應該有一個腹稿,如多大的紙張、應該怎樣排版等等,通常都為信紙大小、縱向排版。當然了,如果能在動手之前,先在紙上畫個草圖,這樣更好。可以回過頭來看一1,在頁首,已經有了報表名及報表日期,表體中有產品的相關資訊列表,而頁尾中有頁碼。

  那我們就從頁首開始吧。當添加新報表到工程時,預設情況下,在報表設計師中只能看到表體。按右鍵報表設計師的表體之外處,選擇頁首,這會在報表中添加一個頁首,可以隨意調整頁首與表體區的高度,請看圖7,圖7中減少了表體的高度,增加了頁首的高度。

 

圖7

  在報表設計師的工具箱中,你可以看到用於設計報表的各種各樣的控制項。在我們這個例子中,會用到TextBox、Line和Table控制項。現在我們開始設計頁首了。拖動兩個TextBox並把它們置於頁首區,TextBox既能顯示靜態也能顯示動態資料,而Line控制項用於把頁首從表體區中分隔出來。控制項放置好之後,可以修改它們的屬性以顯示我們所需的值,例如可以指定一個TextBox為報表標題,而另一個TextBox顯示當前日期。選擇TextBox之後,可直接在其內輸入靜態文本。

  請照以下修改標題TextBox:

  Value = "Product List"
  Color = Purple

  而日期TextBox則修改為:

  Value = "Run Data: " & Today
  Color = Purple

  [span] 要注意了,日期TextBox的Value屬性以"="符號打頭,這代表它不是一個簡單的靜態文本,而是一個運算式,這個運算式是字串"Run Date"與VB.NET指令碼Today的結果。
另外多說一點,你可對報表中所有對象指定任何你想要的名稱,一般對大多數控制項而言,保持預設名稱就好了,此處把標題TextBox的名稱(即Name屬性)指定為“txtTitle”。

  參照圖8,完成頁首設計之後,應該看起來就像這樣子:

 

圖8

  現在是表體了。表體是承載資訊的詳細地區,是整個報表最重要的部分,而且你也看到了,當添加報表到工程時,表體已經自動添加了,我們只需要在上面放些控制項就行了。

  從傳統意義上來說,表體區是用於顯示詳細資料的(在本例中,為產品資訊),並且通常為多行資訊,而隨著報表上資料的增多,表體區也相應會擴充,但一般來說,報表只會設計為一頁(信紙或A4紙大小)。
在表體區中,有三種最常用的控制項:Table、Matrix、List,在本例中會使用Table控制項。在報表設計介面中,拖動並把Table控制項放置於表體區中,你會看到,這會產生一張三行三列的表,而中間一列則已被標記為:Header、Detail、Footer。

  當你知道Table控制項只不過是一堆TextBox的組合,是不是有點吃驚呢。對了,Talbe中的每個單元(Cell)都與TextBox一樣,也就是說,可以在其中輸入靜態文本,或指定一個動態運算式。
在開始設計表體區之前,記得要多添加兩列(我們的報表中有5列喔),添加列非常簡單,依照以下步驟就行了:

  1、 在表體區中選擇Table控制項。
  2、 左鍵單擊最右邊一列的表頭(此處假設你是從右邊添加新列的)。
  3、 按右鍵表頭,並選擇“Insert Column to the Right”(在右邊插入列)。

  現在報表看起來應該像圖9了,可以依據列中的資料隨意調整列的寬度。

 

圖9

  大家多半也用過Excel或類似的東西吧,可以把Table控制項看成是一張迷你工作表,在其中可以選擇邊框類型、改變任一儲存格的字型等等。因此,所需做的就是依之前設想好的格式來設計表格。
我們從第一列開始,隨後的每一列也一樣,單擊最上方的儲存格並依次輸入:

  表頭1:“Product Name”
  表頭2:“Packaging”
  表頭3:“Unit Price”
  表頭4:“Units in Stock”
  表頭5:“Stock Value”

  而在接下來的詳細資料區(即前面的Detail)中,需要輸入運算式,其為dsProduct.dtProductInfo中的列,在此既可以手工輸入運算式,也可以從資料來源(Data Sources)工具箱(見圖7左邊)中拖放實現。
如果想要手工輸入,請從資料區的第一列至最後一列,單擊儲存格並輸入:

  Detail 1: "=Fields!ProductName.Value"
  Detail 2: "=Fields!QuantityPerUnit.Value"
  Detail 3: "=Fields!UnitsInStock.Value"
  Detail 4: "=Fields!UnitPrice.Value"
  Detail 5: "=Fields!UnitsInStock.Value * Fields!UnitPrice.Value"

  請留意Detail 5,它是一個對Units in Stock與Unit Value相乘計算之後的輸出。另外提醒一點,如果是拖動列到Table控制項中的資料區來實現的,此時如果表頭為空白,它會自動添加表頭。
最後,在Table控制項的頁尾添加一累計欄,選擇表體區第4與第5列的頁尾儲存格,輸入:

  儲存格4:“Total Value:”
  儲存格5:"=SUM(Fields!UnitsInStock.Value * Fields!UnitPrice.Value)"

  單擊儲存格5,這是使用了一個內建的SUM()函數來得到累計的結果。

  最後只剩下頁尾區了,在開始編寫一些C#代碼之前,還需完成報表的頁尾,正如前面添加報表首一樣,在開啟的報表設計師中,按右鍵並選擇頁尾(Page Footer),見圖7。
拖動一個Line和TextBox控制項置於頁尾區,並在TextBox中輸入以下運算式:

  Value: ="Page: " & Globals!PageNumber & "/" & Globals!TotalPages

  大家可以看到,此處使用了PageNumber和TotalPages,兩 者皆為全域變數。

  現在,報表應該像圖10這樣了,此處,還改變了一點顏色,把數值類資料靠右對齊,把Table當作一張Excel工作表好了,可以隨意調整為你想要的外觀。

 

圖10

  快大功告成了!剩下的就是運算式產生器了。運算式產生器是Reporting Services中一個非常強大的工具,正11中所見,Stock Value是通過SUMFunction Compute得到的,DateSet中的所有資料都可以由“Fields!”關鍵字訪問。

 

圖11

  第五步:編寫賦予報表生機的C#代碼

  從解決方案資源總管中,選擇Form1,按右鍵並選擇查看代碼,為Form1_Load添加以下代碼:

using System.Data.SqlClient;
using Microsoft.Reporting.WinForms;

private void Form1_Load(object sender, EventArgs e)
{
  //聲明連接字串
  string cnString = @"(local); Initial Catalog=northwind;"+"User Id=northwind;Password=northwind";

  //如果使用標準安全屬性,請改為以下代碼
  //string cnString = @"Data Source=(local);Initial Catalog=northwind; Integrated Security=SSPI";

  //聲明串連、命令對象及其他相關對象
  SqlConnection conReport = new SqlConnection(cnString);
  SqlCommand cmdReport = new SqlCommand();
  SqlDataReader drReport;
  DataSet dsReport = new dsProduct();

  try
  {
    //開啟串連
    conReport.Open();

    //準備連線物件以把擷取的資料放入資料集

    cmdReport.CommandType = CommandType.Text;
    cmdReport.Connection = conReport;
    cmdReport.CommandText = "Select TOP 5 * FROM Products Order By ProductName";

    //從命令對象中讀取資料
    drReport = cmdReport.ExecuteReader();

    //有了ADO.NET,可把讀取來的資料直接載入到資料集中

    dsReport.Tables[0].Load(drReport);

    //關閉讀取及串連
    drReport.Close();
    conReport.Close();

    //為查看器提供本地報表資料
    rpvAbraKaDabra.LocalReport.ReportEmbeddedResource =
    "rsWin101.rptProductList.rdlc";

    //準備報表資料來源
    ReportDataSource rds = new ReportDataSource();
    rds.Name = "dsProduct_dtProductList";
    rds.Value = dsReport.Tables[0];
    rpvAbraKaDabra.LocalReport.DataSources.Add(rds);

    //載入報表檢視器
    rpvAbraKaDabra.RefreshReport();
  }
  catch (Exception ex)
  {
    //顯示錯誤資訊
    MessageBox.Show(ex.Message);
  }
  finally
  {
    //檢查串連是否仍然開啟,如果是,關閉它。
    if (conReport.State == ConnectionState.Open)
    {
      conReport.Close();
    }
  }
}

  看到這,大家可能會想,為什麼在select查詢語句中使用了“TOP 5”,此處只是作示範的目的,對輸出作一限制,以得到1中的累計結果。另外,ReportDataSource的Name屬性應總為“DataSet_DataTable”。

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/mountplorer/archive/2009/05/07/4157216.aspx

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.