ASP.NET中動(dòng)態(tài)控制RDLC報(bào)表
更新時(shí)間:2006年09月28日 00:00:00 作者:
在asp.net程序中,可以選擇使用水晶報(bào)表,功能確實(shí)強(qiáng)大。但是web版的水晶報(bào)表好像存在版權(quán)的問題。如果所作報(bào)表不是復(fù)雜的一塌糊涂的話,可以使用微軟自帶的Rdlc報(bào)表。
Rdlc優(yōu)點(diǎn):
1:Rdlc報(bào)表設(shè)計(jì)簡單
2:結(jié)果存成xml,易于控制
3:導(dǎo)出格式作的很不錯(cuò)
這里所說的動(dòng)態(tài)控制報(bào)表所指的是:在一些時(shí)候,制作了報(bào)表之后希望在運(yùn)行中可以動(dòng)態(tài)的做一些小修改,比如說列的位置,用戶控制顯示那些列等等。
控制方法,嘗試了這么幾種:
1:控制微軟提供的報(bào)表對(duì)象的屬性;
2:報(bào)表全部自動(dòng)生成
3:修改報(bào)表源文件,然后加載。
控制微軟提供的報(bào)表對(duì)象的屬性:基于這個(gè)功能需求,一開始我想到的方法是通過控制微軟提供的這些報(bào)表對(duì)象的屬性來實(shí)現(xiàn)。因?yàn)檫@種方法最人道了。但是事與愿違,微軟的ReportViewer對(duì)象是用來顯示Report的,自然不行;我使用的report是自己設(shè)計(jì)的,localReport,找到Report對(duì)象,里面方法有這個(gè)幾個(gè):report.GetDefaultPageSettings();report.GetDocumentMap()等,第一個(gè)是獲取打印紙張德設(shè)置,第二個(gè)是獲取doc文檔(但是始終出錯(cuò)),都是只讀屬性;所以,第一種嘗試失敗。
第二種方法就是報(bào)表全部自動(dòng)生成??梢哉业揭粋€(gè)完整的例子,在這里:http://www.gotreportviewer.com/DynamicTable.zip
這個(gè)例子里面,他把xml結(jié)構(gòu)的rdlc報(bào)表寫成一個(gè)類ReportDefinition,然后通過自定義這個(gè)類的內(nèi)容來得到一個(gè)報(bào)表。其實(shí)際還是為了自己構(gòu)造一個(gè)報(bào)表對(duì)象的xml。這是加載自定義報(bào)表的過程:win下的代碼 this.reportViewer1.Reset();
但是幾經(jīng)考慮之后,這個(gè)方案也不讓人滿意,原因是:所有的報(bào)表對(duì)象都得自己生成,一下子回到了解放前,沒有可視化工具的設(shè)計(jì)既繁瑣又復(fù)雜。特別是如果設(shè)計(jì)幾個(gè)line,然后再來上幾個(gè)分組的話,工作量巨大。
于是乎嘗試第三種方法:ReportVivwer加載報(bào)表前在內(nèi)存中修改報(bào)表源文件。這個(gè)方法比較狠,其實(shí)可以解決很多問題,包括設(shè)計(jì)自定義的打印紙張等(這里有另外一種設(shè)置打印紙張的方法http://waxdoll.cnblogs.com/archive/2006/03/03/342435.html)。
設(shè)計(jì)思路是:首先加載rdlc文件到一個(gè)XmlDocument對(duì)象;然后修改xml內(nèi)容;把xml序列化成字節(jié)流,交給ReportViewer顯示。
這是這一段代碼:
至于如何GetReportColumns和RemoveColumnFromRdlc,那就很簡單了,就是一個(gè)操作xml對(duì)象的過程。比方說:
這是使用這一段的代碼:
這個(gè)方法終于成功了。
附:rdlc文件的xml一段結(jié)構(gòu)
xml結(jié)構(gòu)
Rdlc優(yōu)點(diǎn):
1:Rdlc報(bào)表設(shè)計(jì)簡單
2:結(jié)果存成xml,易于控制
3:導(dǎo)出格式作的很不錯(cuò)
這里所說的動(dòng)態(tài)控制報(bào)表所指的是:在一些時(shí)候,制作了報(bào)表之后希望在運(yùn)行中可以動(dòng)態(tài)的做一些小修改,比如說列的位置,用戶控制顯示那些列等等。
控制方法,嘗試了這么幾種:
1:控制微軟提供的報(bào)表對(duì)象的屬性;
2:報(bào)表全部自動(dòng)生成
3:修改報(bào)表源文件,然后加載。
控制微軟提供的報(bào)表對(duì)象的屬性:基于這個(gè)功能需求,一開始我想到的方法是通過控制微軟提供的這些報(bào)表對(duì)象的屬性來實(shí)現(xiàn)。因?yàn)檫@種方法最人道了。但是事與愿違,微軟的ReportViewer對(duì)象是用來顯示Report的,自然不行;我使用的report是自己設(shè)計(jì)的,localReport,找到Report對(duì)象,里面方法有這個(gè)幾個(gè):report.GetDefaultPageSettings();report.GetDocumentMap()等,第一個(gè)是獲取打印紙張德設(shè)置,第二個(gè)是獲取doc文檔(但是始終出錯(cuò)),都是只讀屬性;所以,第一種嘗試失敗。
第二種方法就是報(bào)表全部自動(dòng)生成??梢哉业揭粋€(gè)完整的例子,在這里:http://www.gotreportviewer.com/DynamicTable.zip
這個(gè)例子里面,他把xml結(jié)構(gòu)的rdlc報(bào)表寫成一個(gè)類ReportDefinition,然后通過自定義這個(gè)類的內(nèi)容來得到一個(gè)報(bào)表。其實(shí)際還是為了自己構(gòu)造一個(gè)報(bào)表對(duì)象的xml。這是加載自定義報(bào)表的過程: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();這是自動(dòng)生成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;
this.reportViewer1.LocalReport.DataSources.Add(new ReportDataSource("MyData", m_dataSet.Tables[0]));
this.reportViewer1.RefreshReport();這是自動(dòng)生成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;
但是幾經(jīng)考慮之后,這個(gè)方案也不讓人滿意,原因是:所有的報(bào)表對(duì)象都得自己生成,一下子回到了解放前,沒有可視化工具的設(shè)計(jì)既繁瑣又復(fù)雜。特別是如果設(shè)計(jì)幾個(gè)line,然后再來上幾個(gè)分組的話,工作量巨大。
于是乎嘗試第三種方法:ReportVivwer加載報(bào)表前在內(nèi)存中修改報(bào)表源文件。這個(gè)方法比較狠,其實(shí)可以解決很多問題,包括設(shè)計(jì)自定義的打印紙張等(這里有另外一種設(shè)置打印紙張的方法http://waxdoll.cnblogs.com/archive/2006/03/03/342435.html)。
設(shè)計(jì)思路是:首先加載rdlc文件到一個(gè)XmlDocument對(duì)象;然后修改xml內(nèi)容;把xml序列化成字節(jié)流,交給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;
}
{
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,那就很簡單了,就是一個(gè)操作xml對(duì)象的過程。比方說:
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;
}
{
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();
this.ReportViewer1.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", result.Tables[0]));
this.ReportViewer1.LocalReport.Refresh();
這個(gè)方法終于成功了。
附:rdlc文件的xml一段結(jié)構(gòu)
xml結(jié)構(gòu)
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">
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">
您可能感興趣的文章:
- VS2015 update2安裝歷程
- VS2015開發(fā)環(huán)境的安裝和配置
- 解決安裝VS2008無法更改默認(rèn)路徑的問題
- CentOs6.5中安裝和配置vsftp簡明教程
- 同時(shí)安裝vs2005團(tuán)隊(duì)開發(fā)版和sql 2005企業(yè)版的方法(downmoon原作)
- vs10安裝之后一些列問題
- vs2008 安裝失敗的總結(jié)與分享
- 安裝 VS2005 SP1 有關(guān)問題的解決辦法
- ASP.NET 水晶報(bào)表打印功能實(shí)現(xiàn)代碼
- 解決VS2015中沒有報(bào)表項(xiàng)(ReportViewer)的方法
相關(guān)文章
ASP.NET Core 2.0中Razor頁面禁用防偽令牌驗(yàn)證
在這篇短文中,我將向您介紹如何ASP.NET Core2.0 Razor頁面中禁用防偽令牌驗(yàn)證,對(duì)此有興趣的朋友參考學(xué)習(xí)下吧。2018-01-01ASP.NET MVC3網(wǎng)站創(chuàng)建與發(fā)布(1)
這篇文章主要介紹了ASP.NET MVC3網(wǎng)站創(chuàng)建與發(fā)布,根據(jù)文章內(nèi)容大家可以實(shí)現(xiàn)發(fā)布網(wǎng)站,感興趣的小伙伴們可以參考一下2015-08-08詳細(xì)說明asp.net中datareader 和 dataset 的區(qū)別
asp.net中datareader 和 dataset的區(qū)別主要是在獲取數(shù)據(jù)的機(jī)制和獲取數(shù)據(jù)的方式方面,下面我們來看教程2013-08-08用javascript為DropDownList控件下拉式選擇添加一個(gè)Item至定義索引位置
用Javascript為DropDownList控件下拉式選擇添加一個(gè)Item至定義索引位置;準(zhǔn)備數(shù)據(jù),創(chuàng)建一個(gè)對(duì)象,將是存儲(chǔ)DropDownList控件每個(gè)Item數(shù)據(jù)2013-01-01asp.net LINQ中數(shù)據(jù)庫連接字符串的問題
這兩天一直在用LINQ做開發(fā),也是第一次嘗試用LINQ做開發(fā),效率沒的說,開發(fā)過程中遇到一個(gè)問題困擾了我好久,今天問題終于解決了,發(fā)上來和大家分享一下,也給自己做個(gè)備忘。2010-03-03關(guān)于兩個(gè)自定義控件的取值問題及接口的應(yīng)用
一個(gè).aspx的頁面中,用到了兩個(gè)用戶控件,其中想做的到A控件有一個(gè)按鈕,點(diǎn)擊的時(shí)候獲取到B控件中的一個(gè)textbox的值想必大家會(huì)使用findcontrol獲取控件吧,而在生成的時(shí)候名字是不確定的,那么如何書寫呢?接下來為您提供詳細(xì)的解決方法,感興趣的朋友可以了解下啊2013-01-01