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文本格式,可以随意打开浏览编辑。
    运行效果:




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

  • 相关阅读:
    PAT (Basic Level) Practise 1013 数素数
    PAT (Basic Level) Practise 1014 福尔摩斯的约会
    codeforces 814B.An express train to reveries 解题报告
    KMP算法
    rsync工具
    codeforces 777C.Alyona and Spreadsheet 解题报告
    codeforces 798C.Mike and gcd problem 解题报告
    nginx + tomcat多实例
    MongoDB副本集
    指针的艺术(转载)
  • 原文地址:https://www.cnblogs.com/chenbg2001/p/2017207.html
Copyright © 2011-2022 走看看