今天被人問到這樣一個問題:如何動態地切換報表中的圖表類型,例如能不 能同時支持柱狀圖和餅圖,而且用戶可以切換?
開發的環境是Reporting Service。
我為此做了一些研究,下面這個范例可以解釋這個問題
為了做這個演示,我們需要在Northwind數據庫中,准備一個特殊的存儲過程,它可以根據國家統計出來銷售額。
CREATE procedure [dbo].[SaleReportByCountry]
@Beginning_Date DateTime, @Ending_Date DateTime AS
SELECT Employees.Country,SUM([Order Subtotals].Subtotal) AS SaleAmount
FROM Employees INNER JOIN
(Orders INNER JOIN "Order Subtotals" ON Orders.OrderID = "Order Subtotals".OrderID)
ON Employees.EmployeeID = Orders.EmployeeID
WHERE Orders.ShippedDate Between @Beginning_Date And @Ending_Date
GROUP BY Employees.Country
【備注】為了簡便演示的步驟,這裡使用的模板是報表應用程序。這是VS2008的一個新的項目類型,基於Reporting Service
到這裡為止,我們就創建好了一個報表應用程序。我們現在所使用的報表是 所謂的本地報表(rdlc)。
運行該程序,查看效果
我們看到的報表,但沒有數據,這是為什麼呢?這是我們沒有給報表綁定數 據源。
將工具箱中的“SaleReportByCountryTableAdapter”拖動到窗體 設計界面上,然後再到窗體的代碼視圖中添加一句代碼
下面,我們為報表添加圖表的功能。
從工具箱中拖拽“圖表”到報表主體區域。
從數據源中拖放字段到圖表上。默認的圖表類型為“柱狀圖”。 重新運行程序之後看到的效果如下
下面我們來思考的問題是如何切換圖表類型。目前Reporting Service的API 沒有提供這方面的支持。我們現在要做就是直接修改rdlc文件的方式
rdlc其實是一個xml文件。如下
我們觀察到,要修改報表類型的話,思路應該是要修改 Report/Body/ReportItems/Chart[@Name=’chart1’]/Type屬性
為了對比,我們專門添加了一個新的窗體,上面手工添加了幾個控件, 看起來就像下面這樣
與此同時,我們將原先那個SalesReport.rdlc復制一份,粘貼之後重命名為 “DynamicSalesReport.rdlc”,並且將該新文件的屬性進行如下修 改
這些都准備好了之後,我們可以編寫Form2裡面的代碼
/// <summary>
/// 切換為柱狀圖
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btChangeColumnChart_Click(object sender, EventArgs e)
{
ChangeChartType("Column");
}
/// <summary>
/// 切換為餅圖
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btChangePieChart_Click (object sender, EventArgs e)
{
ChangeChartType ("Pie");
}
/// <summary>
/// 修改報表類型
/// 作者:陳希章
/// </summary>
/// <param name="type"></param>
private void ChangeChartType (string type)
{
XmlDocument doc = new XmlDocument();
doc.Load("DynamicSalesReport.rdlc");
XmlNamespaceManager xnm = new XmlNamespaceManager (doc.NameTable);
xnm.AddNamespace("x", "http://schemas.microsoft.com/sqlserver/reporting/2005/01/reportdefi nition");
xnm.AddNamespace("rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner");< br /> doc.SelectSingleNode ("/x:Report/x:Body/x:ReportItems/x:Chart[@Name='chart1']/x:Type", xnm).InnerText = type;
System.IO.MemoryStream ms = new System.IO.MemoryStream();
doc.Save(ms);
ms.Position = 0;
reportViewer1.Reset();//一定要Reset 才有效
reportViewer1.LocalReport.LoadReportDefinition (ms);
//增加一句代碼,填充數據
saleReportByCountryTableAdapter1.Fill (northwindDataSet1.SaleReportByCountry, new DateTime(1996, 1, 1), new DateTime(1998, 1, 1));
Microsoft.Reporting.WinForms.ReportDataSource datasource = new Microsoft.Reporting.WinForms.ReportDataSource ("NorthwindDataSet_SaleReportByCountry", northwindDataSet1.SaleReportByCountry);
reportViewer1.LocalReport.DataSources.Clear();
reportViewer1.LocalReport.DataSources.Add(datasource);
this.reportViewer1.RefreshReport();
ms.Close();
}
完成如上操作之後,就可以進行調試了
於是,整個世界清靜了……