zoukankan      html  css  js  c++  java
  • 真正的全动态报表:RDLC+ReportViewer

    源代码下载

    阅读本文需要有 XML解析 及 ADO.net 相关经验。

    本文编译器使用 Visual Studio 2005 数据库采用XML格式 ReportView 版本为2.0 .net版本为2.0

    一、水晶报表的缺陷

      Crystal Repotrs的功能固然很强大,但是对我们写程序的人来说,是否支持动态生成才是最重要的。如果报表只能静态生成再嵌入到程序中,实在有些没意思。
      不巧的是强大的水晶报表这一点做的很不好,我们可以在程序中动态修改数据源,也可以动态修改文本和字段,但是报表的一大特色,数据图表,却只能静态生成。也就是说,假如我设计报表时添加了一个图表,用户希望能在多个字段中选择自己想显示的,动态显示到图表中,水晶报表就做不到。对它来说,我们至多只能在程序中得到一张位图,这样就没有意义了。
      这个时候我发现了ReportViewer,它用来显示RDLC语言表述的报表。RDLC最初被用在SQL Server for XML上。它实际上是一个XML文本,这就意味着我们在程序中很容易更改它的构架。ReportViewer是RDLC的浏览器,本身没什么好说的,需要注意的是它的数据源必须是DataTable对象。

    二、结构模型

    猛的一看有点复杂呵呵,其实还是挺简单的。

    数据源
      可以是传统数据库,也可以是XML表格
    Data Adapter 及 Connection 等
      用来连接传统的数据库
    DataSet
      用来存储数据,同时可以直接操作XML文件
    BindingSource
      利用DateSet来填充BindingSource,这一步数据中转逻辑上有点多余,但是必不可少
    ReportDataSource
      利用BindingSource来填充ReportDataSource,......-_-!!
    ReportViewer
    利用ReportDataSource填充的 数据 及 指定给它的RDLC报表文件 来显示报表

    三、示例代码

    请大家注意:

    1. 这里我呈现给大家的只是如何实现报表,报表本身的制作 及 RDLC描述语言不在讨论范围。ADO.net同样不在讨论范围,感兴趣的读者可以参考这篇文章:《用VC轻松实现 ADO.net》
    2. 如果按照MSDN上介绍的步骤,可以在VB或C#等语言中实现报表显示,但不能用在VC中,因为向导可能产生中文变量,而VC目前还不支持中文变量。请使用VC的读者按照我介绍的步骤来实现。

    1.制作报表
      新建一个空项目,在解决方案资源管理器中右键点项目名,添加新建项,找到Report,起个名字,点确定。
      具体的制作不在这里说了,请参考相关的文章,或者下载我的示例代码,里面有两个做好的报表文件。
      
    2.制作XML数据库文件
      ADO.net连接传统数据库这里就不多说了,参见上面那篇链接文章。
      方法1:
       安装了SQL Server for XML的话,直接建立数据库模型生成XML文件即可。
      方法2:
      如果没有安装SQL Server for XML,需要绕个弯子:
       1.先使用SQL Server 或 其他数据库建立传统的数据库模型。
       2.写个临时程序,利用ADO.net将数据库模型导入DataSet中。
       3.利用DataSet::WriteXml("文件名");的方法生成XML数据库文件。
      方法3:
      同样没有安装SQL Server for XML时:
       1.先写一个程序,在DataSet中建立数据库模型,当然编程建立要比方法1中的向导建立麻烦一些。
       2.利用DataSet::WriteXml("文件名");的方法生成XML数据库文件。
     
    3.连接数据库
      ADO.net不再多说。

          //连接XML文件
          DataSet^ DateSet1 = gcnew DataSet();
          DataSet1->ReadXml("XML文件");
          

    4.一系列的数据填充

          BindingSource^ aBindingSource;
          ReportDataSource^ reportDataSource1;
          
          //根据DateSet1设置BindingSource
          aBindingSource = gcnew BindingSource();
          aBindingSource->DataMember = "Table1";   //注意,表名要同创建报表时用的相同
          aBindingSource->DataSource = DataSet1;
          
          //根据BindingSource设置ReportDataSource
          reportDataSource1 = gcnew ReportDataSource();
          reportDataSource1->Name = "DataSet1_Table1";
          reportDataSource1->Value = aBindingSource;
          
          //根据ReportDataSource设置ReportViewer控件的数据源,ReportViewer控件最终用来显示报表
          reportViewer1->LocalReport->DataSources->Add(reportDataSource1);
          reportViewer2->LocalReport->DataSources->Add(reportDataSource1);
          .....  //多个报表窗口可以使用同一个数据源
          

    5.连接要显示的报表

          reportViewer1->LocalReport->ReportPath = "rdlc文件1";
          reportViewer2->LocalReport->ReportPath = "rdlc文件2";
          .....
          

    6.显示报表

          reportViewer1->RefreshReport();
          reportViewer2->RefreshReport();
          .....
          

    7.报表的动态修改
      对于普通的数据,只需修改DataSet即可

          DataRow^ row = DataSet1->Tables["Table1"]->NewRow();
          row[0] = newd->comboBox1->Text;   //假设数据来自comboBox控件
          row[1] = newd->comboBox2->Text;
          .....
          DataSet1->Tables["Table1"]->Rows->Add(row);
          
          //刷新一下报表
          reportViewer1->RefreshReport();
          reportViewer2->RefreshReport();
          .....
          

      对于图表之类的数据,需解析RDLC文件,修改之,然后调用RefreshReport()。由于其格式是XML文本,故比较容易,这方面不再多说,感兴趣的读者可以自己解析一下。

    四、示例程序

      在示例程序中我提供了一个记账本功能的小程序,使用XML数据库文件,两张RDLC报表文件。由于时间关系,没有去做RDLC文件解析,请大家见谅。
    report.exe
      主程序
    ReportViewer.exe
      没有安装ReportViewer的客户机需要安装此文件,ReportViewerLP.exe是中文包。
    ngen.exe
      动态报表的生成速度比较慢,有个解决办法,在命令行方式下敲入ngen install report.exe回车,可以将程序及其依赖项编译成机器码并安装到本机全局映像中去,从而提高运行效率。删除前记得ngen uninstall report.exe一下。
    xml文件 及 rdlc文件
      一个是数据库文件,一个是报表文件,均是XML文本格式,可以随意打开浏览编辑。
    运行效果:




    好了,就写到这里,欢迎大家来与我交流相关经验,共同进步。

  • 相关阅读:
    【转】[行业透视] 外企九年-我最终选择放弃
    【转】Win7下有线与无线网络使用优先级
    【转】POJ 1177 Picture(1)
    【转】POJ 1151 Atlantis
    POJ1151Atlantis(扫描线求面积并+线段树+离散化)
    【转】poj_1151(Atlantis)
    【转】poj pku 线段树题目20道汇总+简要算法+分类+难度
    【转】POJ 1151 Atlantis(AC)
    【转】线段树(segment tree)
    【转】poj 1177 pictures(2)
  • 原文地址:https://www.cnblogs.com/chenbg2001/p/2017207.html
Copyright © 2011-2022 走看看