Asp.net中动态控制RDLC报表
在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();
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; }
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;
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; }
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();