需求如下:
1.可以在一个界面中列出多张报表,根据用户的选择,浏览指定的报表,用户可以随意选择,切换新报表,也即是报表可以被替换的。
2.可以实现对所选择的报表,替换它的数据源,或者往数据源增加或删除行(如果数据源绑定的是自定义对象集合,则可以往集合插入或移除对象),也即是报表的数据是可以被替换的。
3如何让最终用户控制报表,我的意思是:可以让用户在默认报表的情况下,更改下列宽行高,隐藏排序列,设置页眉页脚或者表标题,等等。应用了这些功能后,在报表浏览器看到新的结果。
4套打报表,连续打印,存折打印模式.
5.有界面和无界面的打印.
实现思路如下:
1,如何让一个报表浏览器适应多张报表?
在网上找了很多资料,在这方面的介绍很少,看了一个博客朋友的文章http://blog.csdn.net/qiujiahao/archive/2007/08/09/1733415.aspx,是通过动态加载报表浏览器(ReportViewer)的方式来实现动态切换报表,不过,感觉很奇怪,换个URL,难道IE浏览器就把原先的IE关了再开新的IE来浏览网页吗?但是,它的变通思路还是值得借鉴的。这里是该博友文章的要点
ControlCollection coll = ReportViewer1.Parent.Controls;
intoldIndex = coll.IndexOf(ReportViewer1);
        ReportViewer newViewer =
newReportViewer();
        coll.AddAt(oldIndex, newViewer);
注意,如果是VB代码,此处没有AddAt方法,需要你为添加进去的对象指定好索引后再Add进去        coll.Remove(ReportViewer1);
上面的意思是把新的报表浏览器reportviewer替换旧的报表浏览器
这不是本文的要点,好了.先撇开这个不谈,我们知道,报表浏览器的工作原理是这样的
· 数据源  可以是传统数据库,也可以是XML表格,当然,也可以是自定义的对象
Data Adapter 及 Connection 等
  用来连接传统的数据库
DataSet
  用来存储数据,同时可以直接操作XML文件
BindingSource
  利用DateSet来填充BindingSource,这一步数据中转逻辑上有点多余,但是必不可少
ReportDataSource
  利用BindingSource来填充ReportDataSource,......-_-!!
ReportViewer
利用ReportDataSource填充的 数据 及 指定给它的RDLC报表文件来显示报表
好了,了解了上面的原理后,我们就可以开始让我们的报表浏览器工作起来了。
报表浏览器---指定报表定义文件和报表定义文件所绑定的数据源,(数据源可以是数据集或者自定义对象,
1其中报表定义文件的指定方法:Me.ReportViewer1.LocalReport.ReportEmbeddedResource = "rpDemo.OldReport.rdlc",在这里,我是将报表定义文件OldReport.rdlc嵌入到项目中的,如果你的报表定义文件存在于项目之外,则可以使用Me.ReportViewer1.LocalReport.ReportPath来指定报表定义文件(.其中"rpDemo. OldReport.rdlc 前面的rpDemo是项目名.
2其中报表定义文件所需要的数据源指定方式如下:
代码是在winform中写的。
Private bdds As BindingSource ‘全局变量,绑定源,在窗体初始化的时候被创建,绑定源就像个中间对象,连接着报表浏览器和报表的数据源,使得报表浏览器能显示报表的数据。
Privat e ds As demolist ‘这个ds是提供给绑定源的,而绑定源提供给报表源,报表源提供给报表浏览器的localreport属性下的datasources属性。将ds设置为全局变量,以便可以在子程序中更改DS的数据。来测试报表适应数据源的改变。
Sub New()
' 此调用是 Windows 窗体设计器所必需的。InitializeComponent()
' InitializeComponent() 调用之后添加任何初始化。If Me.components Is Nothing  Then Me.components = New System.ComponentModel.Container
bdds = New BindingSource(Me.components)   ‘创建绑定源对象的时候需要指定容器,以便于绑定源跟该容器下的报表浏览器绑定起来。End Sub
然后创建ReportDataSource对象,并将它的名字指定为报表定义文件中绑定的数据源,将它的值指定为bdds绑定源
Dim reportds As New Microsoft.Reporting.WinForms.ReportDataSource("rpDemo_demo", bdds)  '第一个参数指定的是我们在制作报表的时候为报表提供的数据源,第二个参数是绑定源对象,这样绑定源跟报表数据源就产生关联了。
ds = New demolist
bdds.DataSource = ds‘将数据实例提供给绑定源,我这里的数据实例是个对象集而不是数据集Me.ReportViewer1.LocalReport.DataSources.Add(reportds) ’最后一步,将报表数据源将到报表中
3好了。一个报表浏览器就配置好了定义文件和数据源了
Me.ReportViewer1.RefreshReport() ‘这样就可以呈现报表了。
(4)Me.ReportViewer1.Reset() ‘假如你从一个下拉框中选择新的报表定义文件后就执行这句代码,可以将报表浏览器的配置清空,然后重新配置报表浏览器呈现新的报表,代码如下。
Me.ReportViewer1.LocalReport.ReportEmbeddedResource = "rpDemo. NewReport.rdlc"注意,这里指定新的报表定义文件了
Dim reportds As New Microsoft.Reporting.WinForms.ReportDataSource("rpDemo_demo2", bdds)‘这里的两个参数也变了。因为要显示新的报表,就重新指定了新的报表定义文件,报表定义文件变了,所以第一个参数指定的报表数据源当然也跟着变了。而第二个参数指定的是绑定源,我们不需要更改,只是提供给绑定源的数据实例要变而已。demo2list而不再是demolist
bdds.DataSource = New demo2list
Me.ReportViewer1.LocalReport.DataSources.Add(reportds)
Me.ReportViewer1.RefreshReport()
2如何更改报表的数据源
更改数据的方法也很简单,由于我们使用了绑定源对象,所以对于数据源的更改,报表浏览器是不需要理会的,这就是绑定源的好处了。绑定源对报表数据源负责。
ds.Add(New demo("xyz", "asd", "ddd"))‘往我们的demolist集合中插入一个对象
Me.ReportViewer1.RefreshReport() ‘新插入的对象被显示了
3需求3 动态控制报表(可以让用户稍微调整报表的样式)
思路有三个
A. 报表对象是否公开了这些方法呢?这是最先想到的 ReportViewer.localReport.在这里,localreport下的有关控制报表项的方法都是只读的。行不通
B. 写一个动态生成报表定义文件的程序,由于报表定义文件是基于XML格式的,所以只要了解他的结构,就可以做到,不过,当你想生成的报表格式比较复杂的时候,对于你这个自定义报表生成器的要求就高很多了,并不建议这么做,有个老兄对这个报表定义文件的解析有很多的了解,可以参考他的博客http://blog.csdn.net/flygoldfish/archive/2005/12/16/554035.aspx
C. 将报表定义文件使用XMLDOCUMNET这样的类,在内存中对该文件的XML元素做更改,然后将更改后的定义文件重新加载到报表浏览器,这样的方法比较好,参考此博友的文章
D. http://www.cnblogs.com/dlwang2002/archive/2007/02/14/410499.html
E.  
由于我未在这方面做测试,希望有需求的朋友如果做出来的话,在我的博客留个言,大家交流一下。其原理就是更改报表定义文件的XML元素来达到更改报表项的目的。
4需求4套打的实现.和单据连续打印的问题
套打就是像打印发票一样,纸张是印刷好了特定的格式了,而报表只负责打印数据,实现的思路主要是在使用Reporting services的报表设计器制作报表的时候,对控件的位置指定表达式,这样,在程序中编码,计算出该控件应该所在的位置,计算元素可以从报表对象中取得.
对于连续打印的问题,请记得先在最外部使用一个列表控件,把表格控件放在列表控件里面,这样即可实现一份格式,不同的数据行,打印的时候就可以打出多份报表(如员工资料报表)由于我还没做完,等我做出后再发布.
5需求,界面打印不需要提了,reportviewer控件有打印的功能,非界面打印,可以用到localreport和printdocument的printpage事件,在这个事件中进行处理,主要用到localreport.Render方法,MSDN帮助有这个例子,可以在帮助中搜索localreport找到,这里不多说了。
总结:
需求1的实现对于报表浏览器来说,第一是报表定义文件变了,第二是报表定义文件所要求的数据源也变了。对于第一个变化,需要重新指定报表定义文件即可,对于第二个变化,我们需要指定新的报表数据源,然后将绑定源所依赖的数据实例也替换成报表数据源所需要的。别忘了替换报表之前先调用报表浏览器的Reset方法,将旧报表的设置清掉。
至于需求2,其实正是因为绑定源的存在,所以只需要操作数据实例即可。
至于需求3,我觉得其实可以将报表文件导出EXCEL文件给最终用户,毕竟在EXCEL中去调整会方便很多。另外,使用报表模型项目,将现成的报表生成器配合报表模型,最终用户也是可以自己设计报表的。使用程序更改报表定义文件的方法,工作量会大很多,只能实现有限的动态控制而已了。
需求四的套打,也存在这样的需求,像打印存折那样打印,也即是旧记录不打而只打新记录,我的思路是对要打印的行的颜色设置表达式,在提供的数据中包含一个字段控制是否已经打印,已经打印过的则让该行颜色为白色,这样旧记录既会占位,也不打印,即可只打印新的记录了。当然,使用控件的位置表达式,会更灵活,但编程就需要计算位置了。
相关参考:以下的URL包含一些打印报表中遇到的问题,可以在这些博客做些参考。http://www.cnblogs.com/dlwang2002/archive/2007/02/14/410499.html
http://blog.csdn.net/flygoldfish/archive/2005/12/16/554035.aspx
http://www.cnblogs.com/waxdoll/archive/2006/03/04/342910.html
http://blog.sina.com.cn/s/blog_4b0754cf010008e1.html
想做一个报表设计器的朋友,可以参考下速达的http://www.superdata.com.cn/down/Down_Tryout.aspx
其中的5000工业版和7000工业版都有打印样式设计的界面可以参考。
有这方面需求的朋友,不妨将你开发的经验分享下,或者在我的博客留下你的博客地址,大家互相进步。
想对Reporting Services有进一步了解的朋友也可以在这里提些问题,我能帮忙的都尽量帮,有好的资料可以在这里发布下,谢谢!

reportviewer动态加载报表的实现以及动态控制报表,套打,存折打印模式等的一些探讨,欢迎批评指正!相关推荐

  1. ReportViewer动态加载报表文件

    webform中一个ReportViewer控件如何动态显示多个rdlc文件,在网上搜索了一些资料都没有找到实现方法.于是自己就在页面中添加多个ReportViewer控件来对应多个rdlc文件,然后 ...

  2. 解决水晶报表中动态加载的图片或利用水晶报表创建的图表不显示图片的方法

    开发水晶报表时在利用其创建图表时在IIS服务器图片不显示,解决方法如下: 在解决方案资源管理器->web项目-->右键 属性页,把多余的 引用 移除就可以了(注意版本),例如VS2005版 ...

  3. Android学习——Fragment动态加载

    动态加载原理 利用FragmentManager来添加一套Fragment事务,最后通过commit提交该事务来执行对Fragment的相关操作. FragmentManager fragmentma ...

  4. Delphi FastReport动态加载图片

    Delphi  FastReport动态加载图片 2011-01-06         作者:李海彬 阅读:684 以前用FastReport制作报表,从来没有打印过图片,这段时间做了个打印个人简历的 ...

  5. 基于vue-router的从后端动态加载菜单的实现

    基于vue-router的从后端动态加载菜单的实现 源码下载 前言 后端模拟加载菜单的例子实现 VueRouterController.java CorsConfig.java application ...

  6. vue系统权限(动态加载路由方式)

    目录 1.注册vue-router 2.声明 默认路由 和权限路由 3.用vuex实现全局登录.退出登录等方法 4.用vuex模块单独写权限路由的判断 5.监听路由跳转实现动态加载权限菜单 需要用到动 ...

  7. js 动态加载select触发事件

    动态加载select后,手动调用一下 subjectChange函数,模拟触发change事件 function hallidChange(value) {$.ajax({type: "po ...

  8. cascader 动态加载 回显_ElementUI cascader级联动态加载回显和搜索看这个就够了

    这一篇是上一次讨论cascader级联动态加载回显问题的延续,文末有链接. 以下是思考和开发的过程,不感兴趣可以直接看使用文档. https://github.com/zhuss/lazy-casca ...

  9. C#动态加载DLL(转)

    利用反射进行动态加载和调用. Assembly ass=Assembly.LoadFrom(DllPath); //利用dll的路径加载 加载dll后,需要使用dll中某类. Type type=as ...

  10. 利用反射实现类的动态加载

    为什么80%的码农都做不了架构师?>>>    //首先定义一个接口来隔离类: public interface Operator { // public java.util.Lis ...

最新文章

  1. Fitnesse测试系列--如何设置SetUp文件
  2. 浅析Node模块中module.exports与exports的关系
  3. Kali Linux软件更新日报20190623
  4. Fabric环境搭建
  5. python 多图一窗口 打乱列表排序
  6. Python Django session存取值代码演示及jsonpickle序列化
  7. SpringBoot 中添加jsp支持遇到的问题
  8. Android 柱状图
  9. android svn丢失文件恢复,SVN搭建(以此为准,成功)文后含备份与恢复
  10. 第 7 章 本地方法栈
  11. getch和getchar的区别
  12. 背景图片,颜色变化脚本
  13. 搜狗拼音输入法4.2_巧用搜狗快速输入特殊字符与表情字符画
  14. yota3无第三方recovery root方法
  15. 是时候复习下 Webpack 了
  16. HTML5 SVG蝴蝶飞舞动画3D效果
  17. 台式计算机 如何组装,台式电脑买回家怎么装_组装方法图文分析
  18. sever企业版密钥 sql_SQL Server2016企业版 附全版本key(转载)
  19. 我对于创业公司的看法
  20. Unity知识点总结(1)

热门文章

  1. python文档字符串和注释的区别,加载模块时,Python文档字符串和注释是否存储在内存中?...
  2. 迅雷手机版苹果版_手机迅雷安卓版下载2019_迅雷手机版下载最新版
  3. 大数据Spark入门教程
  4. 清除ie各种缓存.cmd
  5. 2020年北京给进口摩托车(川崎)交税、验车、上牌照流程
  6. matlab 仿真 毕业设计,毕业设计matlab仿真
  7. Origin introduction and install
  8. php新年倒计时源码,2020新年倒计时网页HTML源代码 | 一叶轻舟
  9. 115网盘离线下载问题
  10. 二自由度云台扫描算法_基于二维压电透射式微扫描器的红外超分辨率成像|压电扫描台...