王朝网络
分享
 
 
 

ASP.NET中动态控制RDLC报表

王朝asp·作者佚名  2006-11-24
宽屏版  字体: |||超大  

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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有