Asp.net中动态控制RDLC报表 自定义RDLC

转载自: http://dlwang2002.cnblogs.com/archive/2006/05/27/410499.html

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

已经有老兄做出了不少诠释:http://www.cnblogs.com/waxdoll/
更多资料可以在这里找到:http://www.gotreportviewer.com/

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下的代码

Asp.net中动态控制RDLC报表 自定义RDLC           this.reportViewer1.Reset();
Asp.net中动态控制RDLC报表 自定义RDLC            this.reportViewer1.LocalReport.LoadReportDefinition(m_rdl);
Asp.net中动态控制RDLC报表 自定义RDLC            this.reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("MyData", m_dataSet.Tables[0]));
Asp.net中动态控制RDLC报表 自定义RDLC            this.reportViewer1.RefreshReport();

这是自动生成xml的代码:

Asp.net中动态控制RDLC报表 自定义RDLC       private MemoryStream GenerateRdl(List<string> allFields, List<string> selectedFields)
Asp.net中动态控制RDLC报表 自定义RDLC        {
Asp.net中动态控制RDLC报表 自定义RDLC            MemoryStream ms = new MemoryStream();
Asp.net中动态控制RDLC报表 自定义RDLC            RdlGenerator gen = new RdlGenerator();
Asp.net中动态控制RDLC报表 自定义RDLC            gen.AllFields = allFields;
Asp.net中动态控制RDLC报表 自定义RDLC            gen.SelectedFields = selectedFields;
Asp.net中动态控制RDLC报表 自定义RDLC            gen.WriteXml(ms);
Asp.net中动态控制RDLC报表 自定义RDLC            ms.Position = 0;
Asp.net中动态控制RDLC报表 自定义RDLC            return ms;
Asp.net中动态控制RDLC报表 自定义RDLC        }

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

Asp.net中动态控制RDLC报表 自定义RDLCnamespace Rdl {
Asp.net中动态控制RDLC报表 自定义RDLC    using System.Xml.Serialization;
Asp.net中动态控制RDLC报表 自定义RDLC    
Asp.net中动态控制RDLC报表 自定义RDLC    
Asp.net中动态控制RDLC报表 自定义RDLC    /// <remarks/>
Asp.net中动态控制RDLC报表 自定义RDLC    [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
Asp.net中动态控制RDLC报表 自定义RDLC    [System.SerializableAttribute()]
Asp.net中动态控制RDLC报表 自定义RDLC    [System.Diagnostics.DebuggerStepThroughAttribute()]
Asp.net中动态控制RDLC报表 自定义RDLC    [System.ComponentModel.DesignerCategoryAttribute("code")]
Asp.net中动态控制RDLC报表 自定义RDLC    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
Asp.net中动态控制RDLC报表 自定义RDLC    [System.Xml.Serialization.XmlRootAttribute(Namespace="http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefinition", IsNullable=false)]
Asp.net中动态控制RDLC报表 自定义RDLC    public partial class Report {
Asp.net中动态控制RDLC报表 自定义RDLC        
Asp.net中动态控制RDLC报表 自定义RDLC        private object[] itemsField;
Asp.net中动态控制RDLC报表 自定义RDLC        

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

于是乎尝试第三种方法:ReportVivwer加载报表前在内存中修改报表源文件。这个方法比较狠,其实可以解决很多问题,包括设计自定义的打印纸张等(这里有另外一种设置打印纸张的方法http://waxdoll.cnblogs.com/archive/2006/03/03/342435.html)。
设计思路是:首先加载rdlc文件到一个XmlDocument对象;然后修改xml内容;把xml序列化成字节流,交给ReportViewer显示。
这是这一段代码:

Asp.net中动态控制RDLC报表 自定义RDLC   public MemoryStream GenerateRdlc()
Asp.net中动态控制RDLC报表 自定义RDLC    {
Asp.net中动态控制RDLC报表 自定义RDLC           XmlDocument sourceDoc = new XmlDocument();
Asp.net中动态控制RDLC报表 自定义RDLC        string path = AppDomain.CurrentDomain.BaseDirectory + "Test/OrderList.rdlc";
Asp.net中动态控制RDLC报表 自定义RDLC        sourceDoc.Load(path);
Asp.net中动态控制RDLC报表 自定义RDLC        Hashtable reportColumns = GetReportColumns(sourceDoc.LastChild);
Asp.net中动态控制RDLC报表 自定义RDLC        //just remove
Asp.net中动态控制RDLC报表 自定义RDLC
        for (int i = 0; i < reportColumns.Count; i++)
Asp.net中动态控制RDLC报表 自定义RDLC        {
Asp.net中动态控制RDLC报表 自定义RDLC            if (!FindReportCoulmns(reportColumns[i].ToString()))
Asp.net中动态控制RDLC报表 自定义RDLC            {
Asp.net中动态控制RDLC报表 自定义RDLC                RemoveColumnFromRdlc(sourceDoc.LastChild, i);
Asp.net中动态控制RDLC报表 自定义RDLC            }

Asp.net中动态控制RDLC报表 自定义RDLC        }

Asp.net中动态控制RDLC报表 自定义RDLC
Asp.net中动态控制RDLC报表 自定义RDLC        MemoryStream ms = new MemoryStream();
Asp.net中动态控制RDLC报表 自定义RDLC        XmlSerializer serializer = new XmlSerializer(typeof(XmlDocument));
Asp.net中动态控制RDLC报表 自定义RDLC        serializer.Serialize(ms, sourceDoc);
Asp.net中动态控制RDLC报表 自定义RDLC        ms.Position = 0;
Asp.net中动态控制RDLC报表 自定义RDLC        return ms;
Asp.net中动态控制RDLC报表 自定义RDLC    }

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

Asp.net中动态控制RDLC报表 自定义RDLC  private Hashtable GetReportColumns(XmlNode root)
Asp.net中动态控制RDLC报表 自定义RDLC    {
Asp.net中动态控制RDLC报表 自定义RDLC        Hashtable cols = new Hashtable();
Asp.net中动态控制RDLC报表 自定义RDLC        //XmlNamespaceManager s=new XmlNamespaceManager(
Asp.net中动态控制RDLC报表 自定义RDLC
        XmlNode cells = FindChildNode(root,"Body/ReportItems/Table/Header/TableRows/TableRow/TableCells");
Asp.net中动态控制RDLC报表 自定义RDLC        for (int i = 0; i < cells.ChildNodes.Count; i++)
Asp.net中动态控制RDLC报表 自定义RDLC        {
Asp.net中动态控制RDLC报表 自定义RDLC            XmlNode cell =FindChildNode( cells.ChildNodes[i],"ReportItems/Textbox/DataElementName");
Asp.net中动态控制RDLC报表 自定义RDLC            cols[i] = cell.InnerText;
Asp.net中动态控制RDLC报表 自定义RDLC        }

Asp.net中动态控制RDLC报表 自定义RDLC        return cols;
Asp.net中动态控制RDLC报表 自定义RDLC    }


这是使用这一段的代码

Asp.net中动态控制RDLC报表 自定义RDLC           this.ReportViewer1.LocalReport.LoadReportDefinition(this.Report.GenerateRdlc());
Asp.net中动态控制RDLC报表 自定义RDLC            this.ReportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", result.Tables[0]));
Asp.net中动态控制RDLC报表 自定义RDLC            this.ReportViewer1.LocalReport.Refresh();


这个方法终于成功了。
附:rdlc文件的xml一段结构

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



 

Asp.net中动态控制RDLC报表 自定义RDLC,布布扣,bubuko.com

Asp.net中动态控制RDLC报表 自定义RDLC

上一篇:查看webdriver针对浏览器的一些函数


下一篇:ajax & jsonp & img