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

           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一段结构


 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">

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

时间: 2024-10-21 13:52:02

Asp.net中动态控制RDLC报表 自定义RDLC的相关文章

Asp.Net中使用水晶报表

Asp.Net中使用水晶报表(上) 在我们对VS.Net中的水晶报表(Crystal Reports)进行研究之前,我和我朋友对如何将这个复杂的东东加入我们的Web应用有着非常的好奇心.一周以后,在阅读了大量的“HOWTO”文档之后,我们成功地将一些简单的报告加入到了我们的Asp.net程序中,并得到了一些小决窍. 这篇文章教你如何在.Net Web应用中使用水晶报表,也可以让你在学习过程中少走一些弯路.为了得到最好的效果,读者最好需要有一些基础的Asp.Net访问数据库的知识以及使用VS.Ne

ASP.NET中利用DataGrid的自定义分页功能

ASP.NET中利用DataGrid的自定义分页功能和存储过程结合实现高效分页 ASP.Net中的DataGrid有内置分页功能, 但是它的默认的分页方式效率是很低的,特别是在数据量很大的时候,用它内置的分页功能几乎是不可能的事,因为它会把所有的数据从数据库读出来再进行分页, 这种只选取了一小部分而丢掉大部分的方法是不可去取的. 在最进的一个项目中因为一个管理页面要管理的数据量非常大,所以必须分页显示,并且不能用DataGrid的内置分页功能,于是自己实现分页. 下面介绍一下我在项目中用到的分页

在ASP程序中打印Excel报表的新方法

目前,B/S模式(浏览器/服务器模式)成为企业网上首选的计算模式.由于B/S模式的特殊性,在C/S下相对较易实现的Excel报表打印功能在B/S下却成为一个难点.本人通过研究写了一个基于ASP程序的打印Excel报表的程序.本程序的特点是无须任何组件. Print.asp ------------------------------------------------ <html><title>打印Excel报表</title> <% '控制脚本语言 respon

RDLC系列(一)ASP.NET RDLC 报表自定义数据源

最近一段时间开发ERP系统中要用到不少报表打印,在网上找了一圈发现想些好用的报表控件大部分要收费,一些面免费要么不好用要么IE8不兼容,最后还是用了微软自带的RDLC报表,把自己遇到的坑和技巧整理分享出来. 一般Visaul Studio上新建的的EDLC报表文件之后数据源都是按照向导直接连接数据库,自动生成数据源和数据集的,但是遇到一些复杂的就不够灵活. 一.新建报表 1.新建一个空白的报表如下 2.打开新建好的空报表文件,选择报表文件右键选择[打开方式]→[XML(文本)编辑]打开 在Pag

WinForm rdlc 报表自定义datatable数据源

public partial class _Default : System.Web.UI.Page { //页面加载的时候绑定数据源 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { FillDataToReport(); } } public void FillDataToReport() { DataTable dt = new DataTable();         //创建一个datat

asp.net中使用水晶报表 ---push

首先要说明的是push比pull多了一层DataSet所以我们来创建一个 还需要创建一个报表 导入命名空间 private void Show() { DataSet ds=new DataSet(); string connStr = "server=.;database=demo;uid=sa;pwd=12345"; using (SqlConnection conn=new SqlConnection(connStr)) { conn.Open(); string sql1 =

asp.net中使用水晶报表 ---使用向导

编写环境 vs2013,sqlserver2012 由于我们安装的2013没有水晶报表,所以需要我们手动的去下载并安装 下载地址为http://www.aspsnippets.com/Articles/Download-Crystal-Reports-for-Visual-Studio-2013.aspx 然后我们就来编写我们的水晶报表,在编写前我们需要了解的是水晶报表有两种方式 1.pull 拉 拉的意思就是说,当你用的时候就连接数据库然后返回数据 2.push 推 推的意思就是保存在本地,要

在mvc视图中实现rdlc报表展示

需求:在view视图页面中嵌入rdlc报表,rdlc的xml为动态传入的xml字符串.本项目是基于abp框架 可能出现问题: 1.rdlc报表是由asp.net的服务器控件ReportViewer来支持的,view视图不能直接使用服务器控件 2.ReportViewer需要通过aspx页面来承载,并在服务端事件中完成对控件的xml绑定.datatable绑定 3.由于是基于abp框架的项目,不能在aspx.cs后台页面中直接实例化IxxAppService接口的实现类 想达到的效果如下图: 上部

mvc 在view视图中直接输出rdlc报表文件(Excel、PDF、Word)

给一段代码做参考 public ActionResult RdlcReport(string code) { LocalReport localReport = new LocalReport(); EasyMan.Dtos.ErrorInfo err = new EasyMan.Dtos.ErrorInfo(); err.IsError = false; try { var report = _reportAppService.GetReport(code, 0, false); DataTa