如何动态切换报表中的图表类型

今天被人问到这样一个问题:如何动态地切换报表中的图表类型,例如能不能同时支持柱状图和饼图,而且用户可以切换?

开发的环境是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

 

image

【备注】为了简便演示的步骤,这里使用的模板是报表应用程序。这是VS2008的一个新的项目类型,基于Reporting Service

image 

image

image

image 

image

image 

image

image

image

 

image 

 

image

image

到这里为止,我们就创建好了一个报表应用程序。我们现在所使用的报表是所谓的本地报表(rdlc)。

运行该程序,查看效果

image

我们看到的报表,但没有数据,这是为什么呢?这是我们没有给报表绑定数据源。

image

将工具箱中的“SaleReportByCountryTableAdapter”拖动到窗体设计界面上,然后再到窗体的代码视图中添加一句代码

image

image

下面,我们为报表添加图表的功能。

image

从工具箱中拖拽“图表”到报表主体区域。

image

从数据源中拖放字段到图表上。默认的图表类型为“柱状图”。重新运行程序之后看到的效果如下

image

 

下面我们来思考的问题是如何切换图表类型。目前Reporting Service的API没有提供这方面的支持。我们现在要做就是直接修改rdlc文件的方式

rdlc其实是一个xml文件。如下

image

我们观察到,要修改报表类型的话,思路应该是要修改Report/Body/ReportItems/Chart[@Name=’chart1’]/Type属性

 

为了对比,我们专门添加了一个新的窗体,上面手工添加了几个控件,看起来就像下面这样

image

与此同时,我们将原先那个SalesReport.rdlc复制一份,粘贴之后重命名为“DynamicSalesReport.rdlc”,并且将该新文件的属性进行如下修改

image

这些都准备好了之后,我们可以编写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/reportdefinition");
    xnm.AddNamespace("rd", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner");
    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();

}

 

完成如上操作之后,就可以进行调试了

image

image

于是,整个世界清静了……

posted @ 2009-05-16 21:08  陈希章  阅读(1783)  评论(2编辑  收藏  举报