zoukankan      html  css  js  c++  java
  • (分享)利用reportviewer与C#一步一步生成报表

      关于编写报表,职场中的人相信都会有所感慨,一份整洁、优美的报表会为你在上司面前增色不少,甚至加薪 :) ——大家都喜欢加薪,对吧?在本文中,将向大家介绍怎样利用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等等),打印出来更不在话下。
      请按如下步骤在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
      要注意了,日期TextBox的Value属性以"="符号打头,这代表它不是一个简单的静态文本,而是一个表达式,这个表达式是字符串"Run Date"与.NET脚本Today的结果。 另外多说一点,你可对报表中所有对象指定任何你想要的名称,一般对大多数控件而言,保持默认名称就好了,此处把标题TextBox的名称(即Name属性)指定为“txtTitle”。
      参照图8,完成页眉设计之后,应该看起来就像这样子:

    图8

      现在是表体了。表体是承载信息的详细区域,是整个报表最重要的部分,而且你也看到了,当添加报表到工程时,表体已经自动添加了,我们只需要在上面放些控件就行了。
      从传统意义上来说,表体区是用于显示详细数据的(在本例中,为产品信息),并且通常为多行信息,而随着报表上数据的增多,表体区也相应会扩展,但一般来说,报表只会设计为一页(信纸或A4纸大小)。 在表体区中,有三种最常用的控件:Table(表格)、Matrix(矩阵)、List(列表),在本例中会使用Table控件。在报表设计界面中,拖动并把Table控件放置于表体区中,你会看到,这会生成一张三行三列的表,而中间一列则已被标记为:Header、Detail、Footer。
      当你知道Table控件只不过是一堆TextBox的组合,是不是有点吃惊呢。对了,Table中的每个单元(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是通过SUM函数计算得到的,DateSet中的所有数据都可以由“Fields!”关键字访问。

    图11

      第五步:编写赋予报表生机的C#代码

      从解决方案资源浏览器中,选择Form1,右键单击并选择查看代码,为Form1_Load添加以下代码:  

    View Code
    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();

        //为查看器提供本地报表数据
        reportViewer1.LocalReport.ReportEmbeddedResource ="WindowsApplication1.rptProductList.rdlc";

    reportViewer1.LocalReport.DataSources.Clear();

        //准备报表数据源
        ReportDataSource rds = new ReportDataSource();
        rds.Name = "dsProduct_dtProductList";
        rds.Value = dsReport.Tables[0];
        reportViewer1.LocalReport.DataSources.Add(rds);

        //加载报表查看器
        reportViewer1.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/article/details/4157216

  • 相关阅读:
    HDU 4069 Squiggly Sudoku
    SPOJ 1771 Yet Another NQueen Problem
    POJ 3469 Dual Core CPU
    CF 118E Bertown roads
    URAL 1664 Pipeline Transportation
    POJ 3076 Sudoku
    UVA 10330 Power Transmission
    HDU 1426 Sudoku Killer
    POJ 3074 Sudoku
    HDU 3315 My Brute
  • 原文地址:https://www.cnblogs.com/JuneZhang/p/2266783.html
Copyright © 2011-2022 走看看