本文原地址:怡紅公子的blogs:http://blog.joycode.com/luke/articles/29892.aspx

報表服務中的程式設計

Reporting Services 提供了良好的應用程式和管理工具,使得您無需編寫一行程式碼就可以建立、檢視和管理報表。您可以將 Reporting Services 作為一種現成的報表解決方案,方便地處理現有 SQL Server 資料庫、Analysis Server 資料庫和其他資料來源型別。但是,如果您希望把 Reporting Services 整合到自定義的門戶中,或者是想提供給使用者自定義的管理工具,那麼您就需要編寫一些程式。

Reporting Service提供了Web Service介面,並且在報表中也可以嵌入 VB .Net 程式碼,也可以引用 .Net 程式集。

對報表服務程式設計,您可以做到:1、將報表服務整合到自定義的應用程式;2、生成自定義設計和報表管理工具;3、擴充套件 Reporting Services 平臺。

使用 Visual Studio .Net訪問 Reporting Services Web Service

報表服務提供的是 Web Service介面,在Visual Studio .Net中可以很方便的建立 Web 引用來訪問 Web Service介面。 Visual Studio .Net 中的 Web Service found 是客戶端查詢 Web Service 並獲取其服務描述的過程。Visual Studio .Net 中的 Web Service found 過程涉及詢問網站是否遵循預定演算法。此過程的目的是查詢服務描述,它是使用 Web Services 描述語言 (WSDL) 的一個 XML 文件。

服務描述說明了哪些服務可用,以及如何與這些服務進行互動。沒有服務描述,就不可能通過程式設計方式與 Web Service 進行互動。

Visual Studio .Net 中新增 Web 引用

  1. 專案選單上,單擊新增 Web 引用

新增 Web 引用對話方塊的“URL”框中,鍵入可獲取 Reporting Services Web Service 的服務描述的 URL,如 http://localhost/reportserver/reportservice.asmx?wsdl。然後單擊轉到按鈕即可檢索有關 Web Service 的資訊。

如果本地計算機上存在 Reporting Services Web Service,則單擊瀏覽器窗格中的本地計算機上的 Web Service”連結。然後從提供的列表中單擊 ReportService Web Service 的連結。

  1. “Web 引用名框中,將 Web 引用重新命名為 ReportingServices,這是將用於此 Web 引用的名稱空間。
  2. 單擊新增引用可新增目標 Web Service Web 引用。

 

Visual Studio 將下載服務描述,並生成一個代理類,以在您的應用程式和 Reporting Services Web Service 之間進行連線。

有關訪問 Web Services的更多資訊,請參閱 MSDN 中的文章“演練:使用 Visual Basic Visual C# 訪問 XML Web services”。

如果希望在安裝時配置 Web Service URL,請參閱 MSDN 中的文章“演練:安裝期間重定向應用程式以面向另一個 XML Web services”。

報表服務的 Web Service 認證

Web Service 認證可以使用 Windows 認證和基本認證。任何客戶端呼叫 Web Service 的方法前,都必須經過認證。在 Visual Studio .Net中,認證是非常簡單易行的。

Windows 認證Visual Basic 程式碼示例

Dim rs As New ReportingService()

rs.Credentials = System.Net.CredentialCache.DefaultCredentials

基本認證 Visual Basic 程式碼示例

Dim rs As New ReportingService()

rs.Credentials = New System.Net.NetworkCredential("username", "password", "domain")

從報表服務中獲取報表的資料

ReportingService 類的 Render 方法可以提供報表按照指定格式渲染後的結果,以便於將報表服務整合到自定義的應用程式,用自定義的控制元件或者其它方式向終端使用者提供報表。

Render 方法的引數很多,重要的有報表的完整路徑、渲染格式、報表引數。

渲染格式可以有HTML3.2, HTML4.0, HTML5, XML, CSV, PDF IMAGE,報表引數是一個陣列。

Render 方法的返回值是一個位元組陣列。

Render 方法 Visual Basic 示例程式碼

Imports System

Imports System.IO

Imports System.Web.Services.Protocols

 

Class Sample

   Public Shared Sub Main()

      Dim rs As New ReportingService()

      rs.Credentials = System.Net.CredentialCache.DefaultCredentials    基本認證

     

      Dim result As Byte() = Nothing

      Dim reportPath As String = "/SampleReports/Employee Sales Summary"

      Dim format As String = "MHTML"

      Dim historyID As String = Nothing

      Dim devInfo As String = "<DeviceInfo><Toolbar>False</Toolbar></DeviceInfo>"

     

      ' 報表引數

      Dim parameters(2) As ParameterValue

      parameters(0) = New ParameterValue()

      parameters(0).Name = "EmpID"

      parameters(0).Value = "38"

      parameters(1) = New ParameterValue()

      parameters(1).Name = "ReportMonth"

      parameters(1).Value = "6" ' June

      parameters(2) = New ParameterValue()

      parameters(2).Name = "ReportYear"

      parameters(2).Value = "2004"

     

      Dim credentials As DataSourceCredentials() = Nothing

      Dim showHideToggle As String = Nothing

      Dim encoding As String

      Dim mimeType As String

      Dim warnings As Warning() = Nothing

      Dim reportHistoryParameters As ParameterValue() = Nothing

      Dim streamIDs As String() = Nothing

      Dim sh As New SessionHeader()

      rs.SessionHeaderValue = sh

     

      Try

         result = rs.Render(reportPath, format, historyID, devInfo, parameters, credentials, showHideToggle, encoding, mimeType, reportHistoryParameters, warnings, streamIDs)

         sh.SessionId = rs.SessionHeaderValue.SessionId

      Catch e As SoapException

         Console.WriteLine(e.Detail.OuterXml)

      End Try

      ' 儲存為 MHTML 檔案,也可以直接 Response 給客戶端

      Try

         Dim stream As FileStream = File.Create("report.mhtml", result.Length)

         stream.Write(result, 0, result.Length)

         stream.Close()

      Catch e As Exception

         Console.WriteLine(e.Message)

      End Try

   End Sub 'Main

End Class 'Sample

有關 Render 方法的更多資訊,請參閱 Reporting Services 聯機叢書中的文章“ReportingService.Render Method

檢視、管理報表伺服器的內容

將報表服務整合到自定義的應用程式,檢視和管理報表伺服器的目錄、報表、資料來源是必不可少的。

常用的方法有:

l         CreateFolder   建立目錄

l         ListChildren    列出目錄的內容

l         DeleteItem      刪除元素

l         MoveItem       移動元素

l         CreateReport   建立報表

l         GetReportDefinition       獲取報表定義內容

l         CreateResource      建立資源

l         GetResourceContents    獲取資源內容

l         CreateDataSource   建立資料來源

l         GetDataSourceContents獲取資料來源內容

l         GetProperties  獲取元素屬性

l         SetProperties  設定元素屬性

l         CreateBatch    建立批處理以便在一個事務中執行多條命令

l         ExecuteBatch  執行批處理

關於這些方法的示例,請參閱 RSExplorer 示例 Windows 應用程式。關於這些方法的詳細資訊,請參閱 Reporting Services 聯機叢書。

用於安裝和作業的指令碼程式

在一個專案中,安裝部署是很重要的一環。 CreateFolderCreateReportCreateResourceCreateDataSource方法固然可以在報表伺服器上建立報表所需的全部元素,但是 Reporting Services 提供的 rs.exe 實用工具,可以更方便的做到這一點。

rs.exe 實用工具是一個指令碼宿主,可用來處理您在輸入檔案中提供的指令碼。您可以通過定義指令碼來管理報表伺服器,將報表伺服器資料庫內容複製到其他資料庫,以及釋出報表等。必須採用 Visual Basic 程式碼來編寫指令碼,並使用 .rss 副檔名將其儲存為 Unicode 文字檔案或 UTF-8 文字檔案。

Reporting Services 安裝程式或單獨的示例安裝程式可以將示例指令碼檔案安裝到硬碟上。如果示例指令碼安裝在預設目錄中,請檢視C:\Program Files\Microsoft SQL Server\MSSQL\Reporting Services\Samples\Scripts\ 目錄中的 PublishSampleReports.rss 示例指令碼。該指令碼可以在指定的報表伺服器上執行 Web Service 操作。建立一個資料夾(您可以使用 v 開關將其指定為命令提示變數),然後將 Reporting Services 所帶的示例報表釋出到報表伺服器。

只需要修改該指令碼中的filePath變數、資料來源資訊和報表檔名,即可用於釋出自己的報表檔案。

在命令列下,呼叫rs -i PublishSampleReports.rss -s http://myserver/reportserver -v parentFolder="Sample Reports",即可釋出報表。

在報表中嵌入表示式

Reporting Services 支援以 Visual Basic 編寫的表示式。您可以使用這些表示式來計算報表項的值,或者計算樣式和格式設定屬性的值以及其他報表項屬性的值。

例如,以下表示式在文字框中顯示產品名稱:

=Fields!Product.Value

以下表示式(用於文字框的 Color 屬性中)在“Cost”欄位的值大於“Revenue”欄位的值時,以紅色顯示“Cost”欄位的值;在“Cost”欄位的值小於等於“Revenue”欄位的值時,以黑色顯示“Cost”欄位的值。

=IIf(Fields!Cost.Value > Fields!Revenue.Value, "Red", "Black")

以下表示式根據使用者的輸入來決定資料集內包含的查詢語句。

="SELECT * FROM vProductProfitability WHERE (Year = 2003) AND (MonthNumberOfYear IN (" + Parameters!Month.Value + "))"

最基本的表示式是在文字框中顯示欄位值的表示式。這種型別的表示式稱作欄位表示式。要將資料庫欄位連結到報表項,表示式必須包括 Fields 集合、欄位名稱和 Value 屬性。

表示式也可以是基於欄位或其他報表項的判定函式或格式設定的長表示式。示例如下:

l         以下表示式連線 FirstName 欄位和 LastName 欄位。

=Fields!FirstName.Value & " " & Fields!LastName.Value

l         以下表示式是計算產品的銷售額在整個子類的百分比

=RunningValue(Fields!SalesAmount.Value,Sum,table1_SubCategory”)/ReportItems!SalesAmount_SubCategory.Value

關於基本表示式的更多資訊,請參閱 Reporting Services 聯機叢書中的“使用全域性集合”。

報表服務可以對從資料庫中獲取的資料作分組、篩選和聚合。可以在表示式中使用標準的聚合函式,如Avg, Sum, Count等。也可以使用執行聚合函式:

RowNumber 返回對指定範圍中所有行的執行計數值。

RunningValue 使用指定的函式來返回指定表示式的執行聚合值。

在報表中嵌入 Visual Basic 程式碼

內建函式的功能畢竟有限,但是報表中可以包含對 Microsoft.VisualBasic 名稱空間、System.Convert 名稱空間和 System.Math 名稱空間中的類的引用。如果您使用其他系統名稱空間的類或函式,則必須使用完整名稱空間(如 System.Collections.ArrayList)。這樣就很大限度的提高了報表表示式的功能。

如果報表函式和系統類尚不能滿足需求,那麼您可以編寫自定義程式碼,用在報表的表示式中。為此可採用兩種方法:在報表中嵌入程式碼和引用自定義程式集中的方法。對於複雜的函式,或在一個報表中多次使用的函式,可使用嵌入程式碼。

在“報表”選單上,單擊“報表屬性”。 然後就可以在“程式碼”選項卡的“自定義程式碼”中,鍵入程式碼。程式碼塊可以包含多個方法。嵌入程式碼中的方法必須採用 Visual Basic .NET 編寫,並且必須是基於例項的方法。

嵌入程式碼中的方法可通過全域性定義的 Code 成員使用。您可以通過引用 Code 成員和方法名稱來訪問這些方法。以下示例呼叫了 ToUSD 方法,該方法將 StandardCost 欄位值轉換為美元值:

=Code.ToUSD(Fields!StandardCost.Value)

在報表中使用自定義程式集

為了在一個位置維護程式碼或在多個報表間共享程式碼,可以使用程式碼程式集。在“報表”選單上,單擊“報表屬性”。在“引用”選項卡上,執行以下操作:

在“引用”中,單擊新增 (...) 按鈕,然後在“新增引用”對話方塊中選擇或瀏覽查詢程式集。

在“類”中,鍵入類的名稱並提供在報表中使用的例項名。

要引用表示式中的自定義程式碼,您必須呼叫自定義程式集中某個類的成員。呼叫方式取決於該方法是靜態方法還是基於例項的方法。自定義程式集中的靜態方法可在報表內全域性使用。您可以通過名稱空間、類和方法名稱來訪問表示式中的靜態方法。以下示例呼叫了 ToGBP 方法,該方法將 StandardCost 欄位的值從美元轉換為英鎊:

=CurrencyConversion.DollarCurrencyConversion.ToGBP(Fields!StandardCost.Value)

基於例項的方法可通過全域性定義的 Code 成員使用。您可以通過先引用 Code 成員,再引用例項和方法名稱來訪問這些方法。以下示例呼叫了例項方法 ToEUR,該方法將 StandardCost 欄位的值從美元轉換為歐元:

=Code.m_myDollarCoversion.ToEUR(Fields!StandardCost.Value)

小結

Reporting Service 提供了豐富的程式設計介面,使得Reporting Service很容易和與SharePoint, Office應用,瀏覽器與其它您所熟悉的工具整合,而且很容易做到可擴充套件的,可管理的與可以嵌入的伺服器體系結構。它從第一天起就被設計為一個 .NET Web Service,所有的伺服器元件都是可擴充套件的、完全可嵌入的,而且報表定義語言也是公開的, 可擴充套件的,可以用自定義的工具來設計。

這些設計,提高了開發人員的效率,節省了大量的IT資源,而且便於終端使用者作更多的控制,實現終端使用者的個性化。