ASP.NET中动态控制RDLC报表

  在asp.net程序中,可以选择使用水晶报表,功能确实强大。但是web版的水晶报表好像存在版权的问题。如果所作报表不是复杂的一塌糊涂的话,可以使用微软自带的Rdlc报表。

  Rdlc优点:

  1:Rdlc报表设计简单

  2:结果存成xml,易于控制

  3:导出格式作的很不错

  这里所说的动态控制报表所指的是:在一些时候,制作了报表之后希望在运行中可以动态的做一些小修改,比如说列的位置,用户控制显示那些列等等。

  控制方法,尝试了这么几种:

  1:控制微软提供的报表对象的属性;

  2:报表全部自动生成

  3:修改报表源文件,然后加载。

  控制微软提供的报表对象的属性:基于这个功能需求,一开始我想到的方法是通过控制微软提供的这些报表对象的属性来实现。因为这种方法最人道了。但是事与愿违,微软的ReportViewer对象是用来显示Report的,自然不行;我使用的report是自己设计的,localReport,找到Report对象,里面方法有这个几个:report.GetDefaultPageSettings();report.GetDocumentMap()等,第一个是获取打印纸张德设置,第二个是获取doc文档(但是始终出错),都是只读属性;所以,第一种尝试失败。

  第二种方法就是报表全部自动生成。可以找到一个完整的例子,在这里:http://www.gotreportviewer.com/DynamicTable.zip
这个例子里面,他把xml结构的rdlc报表写成一个类ReportDefinition,然后通过自定义这个类的内容来得到一个报表。其实际还是为了自己构造一个报表对象的xml。这是加载自定义报表的过程:win下的代码 this.reportViewer1.Reset();

this.reportViewer1.LocalReport.LoadReportDefinition(m_rdl);
this.reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("MyData", m_dataSet.Tables[0]));
this.reportViewer1.RefreshReport();这是自动生成xml的代码:
private MemoryStream GenerateRdl(List<string> allFields, List<string> selectedFields)
{
 MemoryStream ms = new MemoryStream();
 RdlGenerator gen = new RdlGenerator();
 gen.AllFields = allFields;
 gen.SelectedFields = selectedFields;
 gen.WriteXml(ms);
 ms.Position = 0;
 return ms;
}

  这是完全ReportDefinition的一部分定义:

namespace Rdl {
 using System.Xml.Serialization;

 /**//// <remarks/>
 [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
 [System.SerializableAttribute()]
 [System.Diagnostics.DebuggerStepThroughAttribute()]
 [System.ComponentModel.DesignerCategoryAttribute("code")]
 [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
 [System.Xml.Serialization.XmlRootAttribute(Namespace=_
  "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition", IsNullable=false)]
 public partial class Report {
  private object[] itemsField;

  但是几经考虑之后,这个方案也不让人满意,原因是:所有的报表对象都得自己生成,一下子回到了解放前,没有可视化工具的设计既繁琐又复杂。特别是如果设计几个line,然后再来上几个分组的话,工作量巨大。

  于是乎尝试第三种方法:ReportVivwer加载报表前在内存中修改报表源文件。这个方法比较狠,其实可以解决很多问题,包括设计自定义的打印纸张等(这里有另外一种设置打印纸张的方法http://waxdoll.cnblogs.com/archive/2006/03/03/342435.html)。

  设计思路是:首先加载rdlc文件到一个XmlDocument对象;然后修改xml内容;把xml序列化成字节流,交给ReportViewer显示。

  这是这一段代码:

public MemoryStream GenerateRdlc()
{
 XmlDocument sourceDoc = new XmlDocument();
 string path = AppDomain.CurrentDomain.BaseDirectory + "Test/OrderList.rdlc";
 sourceDoc.Load(path);
 Hashtable reportColumns = GetReportColumns(sourceDoc.LastChild);
 //just remove
 for (int i = 0; i < reportColumns.Count; i++)
 {
  if (!FindReportCoulmns(reportColumns[i].ToString()))
  {
   RemoveColumnFromRdlc(sourceDoc.LastChild, i);
  }
 }

 MemoryStream ms = new MemoryStream();
 XmlSerializer serializer = new XmlSerializer(typeof(XmlDocument));
 serializer.Serialize(ms, sourceDoc);
 ms.Position = 0;
 return ms;
}

  至于如何GetReportColumns和RemoveColumnFromRdlc,那就很简单了,就是一个操作xml对象的过程。比方说:

private Hashtable GetReportColumns(XmlNode root)
{
 Hashtable cols = new Hashtable();
 //XmlNamespaceManager s=new XmlNamespaceManager(
  XmlNode cells = FindChildNode(root,"Body/ReportItems/Table/Header/TableRows/TableRow/TableCells");
 for (int i = 0; i < cells.ChildNodes.Count; i++)
 {
  XmlNode cell =FindChildNode( cells.ChildNodes[i],"ReportItems/Textbox/DataElementName");
  cols[i] = cell.InnerText;
 }
 return cols;
}

  这是使用这一段的代码:

this.ReportViewer1.LocalReport.LoadReportDefinition(this.Report.GenerateRdlc());
this.ReportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", result.Tables[0]));
this.ReportViewer1.LocalReport.Refresh();

  这个方法终于成功了。

  附:rdlc文件的xml一段结构

  xml结构

1<?xml version="1.0" encoding="utf-8"?>
2<Report xmlns="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition" xmlns:rd="http://schemas.microsoft.com/SQLServer/reporting/reportdesigner">
3 <DataSources>
4 <DataSource Name="ConnectionString">
5 <ConnectionProperties>
6 <ConnectString />
7 <DataProvider>SQL</DataProvider>
8 </ConnectionProperties>
9 <rd:DataSourceID>073016a7-6cb0-4e06-a6fd-f5882a039188</rd:DataSourceID>
10 </DataSource>
11 </DataSources>
12 <BottomMargin>2.5cm</BottomMargin>
13 <RightMargin>2.5cm</RightMargin>
14 <PageWidth>21cm</PageWidth>
15 <rd:DrawGrid>true</rd:DrawGrid>
16 <InteractiveWidth>21cm</InteractiveWidth>
17 <rd:GridSpacing>0.25cm</rd:GridSpacing>
18 <rd:SnapToGrid>true</rd:SnapToGrid>
19 <Body>
20 <ColumnSpacing>1cm</ColumnSpacing>
21 <ReportItems>
22 <Chart Name="chart1">

(0)

相关推荐

  • 同时安装vs2005团队开发版和sql 2005企业版的方法(downmoon原作)

    同时安装vs2005团队开发版和sql 2005企业版(downmoon原作) 由于微软在vs2005vsts团队开发版中集成了sql 2005 express,而在SQL 2005中又集成了vs2005Express,,所以当很多用户同时安装vs2005团队开发?:?sql2005企业版(downmoon)时,就会出现数据库连接失败的case 请按照如下步骤修改: OK!作者: 邀月

  • CentOs6.5中安装和配置vsftp简明教程

    一.vsftp安装篇 复制代码 代码如下: # 安装vsftpdyum -y install vsftpd# 启动service vsftpd start# 开启启动chkconfig vsftpd on 二.vsftp相关命令之服务篇 复制代码 代码如下: # 启动ftp服务service vsftpd start# 查看ftp服务状态service vsftpd status # 重启ftp服务service vsftpd restart# 关闭ftp服务service vsftpd sto

  • VS2015 update2安装历程

    如何坑爹大家都有体会,就不多说了. 总结一下,如果系统是自带的win10家庭版通过换序列号升级到专业版,那趁早重装吧,不然安装VS2015后是无法启动牛逼闪闪的Android模拟器的,会报错:cant' add user to hyper-v administrator group. 但如果你看用户和组里根本就找不到这个hyper-v administrator group. 只有全新安装的win10专业版才有. 如果已经安装了VS2015只升级update2,或者全新安装带update2的is

  • vs2008 安装失败的总结与分享

    先装系统,接着装0ffice2007,接着装ms sqlserver 2005,再装adobe cs4 master套装,一路setup,很是顺利,好就差vs2008了,它一装好,我就可以赚钱了.可结果安装出错的报错,报错的文档如下: 复制代码 代码如下: [01/13/10,18:55:42] setup.exe: [2] ISetupComponent::Pre/Post/Install() failed in ISetupManager::InternalInstallManager()

  • VS2015开发环境的安装和配置

    一.简介 为了避免网上乱七八糟的过时介绍,避免误导初学者,这次把至2016年6月底C#开发环境各种版本的更新和安装过程重新整理一下贡献出来.目的是为了让对C#感兴趣的初学者知道到底哪些是过时的,哪些是最新的,哪些是别有用心的人故意给你挖的坑. 先说一下VS2015的官方网址(这是你了解VS2015以及它到底能做哪些事的第1步): https://www.visualstudio.com/en-us/visual-studio-homepage-vs.aspx 其中: VS2015 Enterpr

  • 安装 VS2005 SP1 有关问题的解决办法

    VS2005 SP1 出来了,号称是M$有史以来最bt的补丁,看见有人装了3个多小时还在收集信息-- 其实原因总结起来就两个: 1. 数字签名认证的问题 2. C盘空间的问题 原因1:Windows Installer设计的一个特性是可以验证文件的数字签名.但是这次的补丁太 大了,要验证签名的话基本上把内存都吃光了(要1GB左右的内存) 原因2:Windows Installer设计的一个特性是会在C盘生成一个$PatchCache$文 件,把补的文件再存一遍,对于这次的补丁嘛,这个大约会消耗掉

  • 解决安装VS2008无法更改默认路径的问题

    一直用VS2012 以及 VS2012开发,但是他们都不支持Wince程序的开发,所有要安装VS2008.但是发现VS2008只能安装在C盘,要知道C空间很宝贵的. 经过查找资料发现系统中已经安装了VS2008相关的组件,正是因为这些组件导致一些目录不能修改,解决方法如下: Microsoft Visual Studio Tools for Applications 2.0 - ENU Microsoft Visual Studio Tools for Applications 2.0 Lang

  • ASP.NET 水晶报表打印功能实现代码

    1.用IE的打印,调用window.print(),但这种办法对于页面上即有报表,又有其它控件情况就无法区分,不能达到只打印报表内容的目的: 2.自已写打印代码 代码如下: 复制代码 代码如下: CrystalDecisions.CrystalReports.Engine.ReportDocument rd=new CrystalDecisions.CrystalReports.Engine.ReportDocument(); rd.Load(Server.MapPath("Crystalrep

  • 解决VS2015中没有报表项(ReportViewer)的方法

    没有报表,一般默认安装之后会出现这种情况,在安装的时候选择自定义安装,把Microsoft Office 开发人员工具.Microsoft SQL Server Data Tools勾选上,安装之后就可以找到了. 1.点击vs_entprise安装 2.安装过后的点击修改 3.额外勾选Microsoft Office 开发人员工具.Microsoft SQL Server Data Tools 两项.如下图 4.点击安装,等待安装之后就可以看到报表啦(因为我的有内容没有更新,所以显示的是更新,一

  • vs10安装之后一些列问题

    记住:这时候08安装的时候要自定义一个实例 比如:mysql2008(不能在使用默认实例了) sql server 2008 express 安装的时提示"重启计算机失败 删除注册表键HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations,然后再试一下. 在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 打开进程关掉所有的sql进程

随机推荐