Microsoft Reporting Services(子报表、图表、参数、表达式编辑器等)
本文展示了创建报表、在运行时定义数据源、使用参数、插入图像、使用表达式编辑器以及如何向子报表和图表提供数据的基本步骤。最后,它将演示ReportViewer的一些简单自定义。

Microsoft 报表基于报表定义,报表定义是一个 XML 文件,描述了报表的数据和布局,具有不同的扩展名。您可以使用 Visual Studio 创建客户端报表定义语言 (*.rdlc) 文件,并为您的应用程序构建出色的报表。报表可以包含表格、聚合和多维数据,此外还可以包含图表,并可用于 Winform 或 ASP.NET。
这篇“操作指南”文章的目的是展示创建报表、在运行时定义数据源、使用参数、包含图像、使用表达式编辑器以及如何向子报表和图表提供数据的基本步骤。最后,它还将演示一些自定义ReportViewer
控件的简单方法。
引言
首先,我为这个例子创建了一个简单的 SQL 表,其中包含一些数据。它是一个电子设备列表,如 PDA、台式机等。从该表中,您需要创建包含两个不同DataTable
的DataSet
。将其命名为“dsReport.xsd”。

第一个DataTable
“products
”包含表中所有产品的列表。第二个“groupTotal
”是一个聚合 (Group By
) 查询,其中包含将在子报表和图表中使用的组和数量总和。
之后,您需要向应用程序添加一个报表。只需选择它并给它一个合适的名称。例如,我选择了“rptProducts
”。

报表创建并打开后,菜单栏中会有一个新菜单,名为“Report
”。选择“页面页眉”和“页面页脚”以在报表中显示这些部分。之后,只需从工具箱中将一个表格拖到报表的正文部分。
DataSource
现在是时候定义DataSource
了。从“报表”菜单中,选择“数据源”。它将打开一个窗口,您可以在其中选择应用程序中可用的数据源。选择已创建的DataSet
。

注意:“报表数据源”的名称可以重命名,并且将在后续代码中使用,您将看到!
为报表定义数据源后,您将在“数据源资源管理器”(通常在“解决方案资源管理器”窗口中可用)中看到可用的DataTable
。现在,从“Products
”表中,将列拖到已添加到正文部分的Table
对象中。

Table
对象的工作方式类似于 Excel 电子表格。您可以合并单元格、格式化单元格、更改背景颜色等。本示例使用货币字段。为了向您展示格式化单元格有多容易,右键单击字段单元格并选择“属性”。在“属性”窗口中,转到“格式”选项卡并为该单元格定义货币格式。

您还可以更改其他字段的格式,例如粗体、颜色、标题等,以获得专业外观。
图像
要在应用程序中包含图像,您可以嵌入它们,然后将其用作徽标(例如)。如果它们以二进制数据存储,您也可以从数据库中获取它们。
要将图像嵌入到报表中,您只需转到菜单“报表”并选择“嵌入图像”。在新窗口中,选择“新建图像”按钮并浏览您的图像。

关闭窗口。然后,从工具箱中,将图像控件添加到报表。在图像属性中,从“值”属性中可用的组合框中选择图像名称。
表达式编辑器
Visual Studio 2008 Microsoft Reporting Services 表达式编辑器的一大优点是,在您需要创建某些公式时,它提供了智能感知功能。
在页脚部分,您可以添加两个文本框。其中一个可以包含页码和总页数。为此,您已经在“全局”类别中有一些内置公式。

如下图所示,您可以在表达式编辑器中使用 VB 公式(大部分)。智能感知大大有助于防止错误和记住公式语法。

参数
您可以将参数用于许多不同的事情。对于本示例,我将仅用于将信息从应用程序传递到报表。
在“报表”菜单中,选择“报表参数”。定义两个类型为String
的参数:“ApplicationUser
”和“ApplicationLevel
”。

然后,在报表中,您可以使用表达式编辑器为文本框定义参数(它们将在代码中定义)。它们将在参数类别中可用。

图表
您可以在报表中使用许多图表,它们非常容易自定义和提供数据。从工具箱中将一个图表控件添加到报表的正文部分。双击它,它将显示“数据字段”和“类别字段”区域。从“数据源资源管理器”中拖动“组”和“总计”字段。

您也可以在“图表属性”窗口的“数据”选项卡中执行此操作。在此窗口中,您可以自定义系列颜色、图例、3D 效果、过滤器、轴等。
Using the Code
在前面的步骤中,您在报表中使用了一些数据源。现在您将添加新的数据源,无论是否过滤,那将是您将看到的数据。
Imports System.Data.SqlClient
Imports Microsoft.Reporting.WinForms
Public Class Form1
' Connection string definition
Private connString As String = _
"Data Source=.\SQLEXPRESS;AttachDbFilename='|DataDirectory|\myDatabase.mdf';_
Integrated Security=True;User Instance=True"
''' <summary>
''' Form load event
''' </summary>
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Load
Try
' Call the customization method
Call customizeReportViewer(Me.ReportViewer1)
' Add a button to the ReportViewer
Call AddReportViewerButton()
With Me.ReportViewer1.LocalReport
' Report path
.ReportPath = Application.StartupPath & "\..\..\rptProducts.rdlc"
.DataSources.Clear()
' Set the parameters
Dim parameters(1) As ReportParameter
parameters(0) = New ReportParameter("ApplicationUser", "jpaulino")
parameters(1) = New ReportParameter("ApplicationLevel", "Administrator")
.SetParameters(parameters)
End With
' ----------------------------------------------------
' Datasource for the main report (where price > 200)
' ----------------------------------------------------
Dim SQL As String = "SELECT * FROM products WHERE price > @price"
Using da As New SqlDataAdapter(SQL, connString)
da.SelectCommand.Parameters.Add("@price", SqlDbType.Int).Value = 200
Using ds As New DataSet
da.Fill(ds, "products")
' You must use the same name as defined in the report
' Data Source Definition
Dim rptDataSource As New ReportDataSource_
("dsReport_products", ds.Tables("products"))
Me.ReportViewer1.LocalReport.DataSources.Add(rptDataSource)
End Using
End Using
' ----------------------------------------------------
' Datasource for the Chart
' ----------------------------------------------------
Dim SQL_Chart As String = "SELECT [group], SUM(quantity) AS _
Total FROM products GROUP BY [group]"
Using da As New SqlDataAdapter(SQL_Chart, connString)
Using ds As New DataSet
da.Fill(ds, "groupTotal")
Dim rptDataSource As New ReportDataSource("dsReport_groupTotal", _
ds.Tables("groupTotal"))
Me.ReportViewer1.LocalReport.DataSources.Add(rptDataSource)
End Using
End Using
' Refresh the report
ReportViewer1.RefreshReport()
Catch ex As Exception
MessageBox.Show(ex.Message, My.Application.Info.Title, _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
子报表
您可以在报表中使用一个或多个子报表。为此,您需要为每个子报表填充数据源。由于您无法直接访问子报表的数据源,因此您必须为SubreportProcessing
定义一个处理程序,然后当子报表加载时,您可以从数据库中检索数据,并设置其数据源。
它可能看起来很难,但很容易完成!
定义子报表的数据源并使用Table
对象,就像在主报表中一样。将字段添加到Table
对象。在主报表中,从工具箱添加一个子报表对象,并选择“报表名称”属性,以命名子报表。
然后在主报表的表单加载事件中,为SubreportProcessing
添加一个处理程序。
AddHandler ReportViewer1.LocalReport.SubreportProcessing, _
AddressOf SubreportProcessingEvent
最后,在SubreportProcessingEvent
中,您只需以相同的方式定义新的datasource
。
''' <summary>
''' When the subreport is being processed/loaded, fills the datasource
''' </summary>
Sub SubreportProcessingEvent(ByVal sender As Object, _
ByVal e As SubreportProcessingEventArgs)
Try
Dim SQL As String = "SELECT [group], SUM(quantity) AS _
Total FROM products GROUP BY [group]"
Using da As New SqlDataAdapter(SQL, connString)
Using ds As New DataSet
da.Fill(ds, "groupTotal")
Dim rptDataSource As New ReportDataSource_
("dsReport_groupTotal", ds.Tables("groupTotal"))
e.DataSources.Add(rptDataSource)
End Using
End Using
Catch ex As Exception
MessageBox.Show(ex.Message, My.Application.Info.Title, _
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
ReportViewer 自定义
ReportViewer
是一个控件,用于在您的表单或网页中显示 Microsoft 报表。您可以自定义大多数控件以根据需要改进和自定义它。
在本文中,我将展示两种简单的自定义方法。
首先,您可以更改控件中的标题。您还可以做其他事情,例如禁用项目、重命名工具提示等。如果您需要更改控件的语言,这尤其有用,因为您只有英语可用。
为此,我创建了这个递归子例程,它将遍历ReportViewer
中的所有控件并进行一些更改。
''' <summary>
''' Loops through all of ReportViewer controls and customize them
''' </summary>
''' <remarks></remarks>
Sub customizeReportViewer(ByVal ctrl As Control)
For Each c As Control In ctrl.Controls
' ----------------------------------------------------
' Check the text of the available labels
' ----------------------------------------------------
If TypeOf c Is Label Then
Dim lbl As Label = DirectCast(c, Label)
Select Case lbl.Name
Case "LblGeneratingReport"
lbl.Text = "My report is loading now ... "
Case Else
' You can add more customizations
End Select
End If
' ----------------------------------------------------
' Change the text in the ToolStrip to Portuguese
' ----------------------------------------------------
If TypeOf c Is ToolStrip Then
Dim ts As ToolStrip = DirectCast(c, ToolStrip)
For Each item As ToolStripItem In ts.Items
Select Case item.Text
Case "Find"
item.Text = "Pesquisar"
Case "Next"
item.Text = "Próximo"
Case "of"
item.Text = "de"
Case Else
' You can add more customizations
End Select
Next
End If
' If the control has child controls
If c.HasChildren Then
customizeReportViewer(c)
End If
Next
End Sub
最后,您只需从表单加载事件中调用它,您在其中拥有ReportViewer
。
' Call the customization method
Call customizeReportViewer(Me.ReportViewer1)
第二个自定义显示了如何在ToolStrip
中包含一个新按钮。它将找到主toolstrip
并在右侧添加一个新按钮。
''' <summary>
''' Find the main ToolStrip and add a new button on the right side
''' </summary>
Sub AddReportViewerButton()
Dim ts() As Control = Me.ReportViewer1.Controls.Find("toolStrip1", True)
If ts IsNot Nothing Then
Dim tsItem As ToolStrip = DirectCast(ts(0), ToolStrip)
Dim item As New ToolStripButton
item.Name = "newButton"
item.Text = "New Button"
item.BackColor = Color.Green
item.ForeColor = Color.White
item.Alignment = ToolStripItemAlignment.Right
tsItem.Items.Add(item)
AddHandler item.Click, AddressOf newButtonClick
End If
End Sub
当按钮按下时
''' <summary>
''' Shows a messagebox when the new button of
''' the Reportviewer is pressed
''' </summary>
Sub newButtonClick()
MessageBox.Show("This is my new button!")
End Sub
关注点
本文展示了使用 Microsoft Reports 的第一步,也是最重要的一步,以及如何处理一些代码。我希望这能帮助您开始使用它,并帮助您理解使用它们是多么容易。
希望对您有所帮助!
历史
- 2009 年 6 月 1 日:初始帖子