用reporting service創建動態報表(代碼)

using System;
using System.Collections;
using System.Data.SqlClient;

namespace ThreeLayer.Web
{
 /// <summary>
 /// ReportBuilder 的摘要說明。
 /// </summary>
 public class ReportBuilder
 { 
  SqlConnection m_connection;
  public string m_connectString;
  public string m_commandText;
  ArrayList m_fields;
       
  public ReportBuilder(string strCon,string strSQl)
  {
   m_connectString=strCon;
            m_commandText=strSQl;

  }

  //FolderName如"/Samples"
  public void Upload(string FileName,string ReportName,string FolderName)
  {
   ReportingService rs = new ReportingService();
   rs.Credentials = System.Net.CredentialCache.DefaultCredentials;

   Byte[] definition = null;
   Warning[] warnings = null;
   string name = ReportName;

   try
   {
    FileStream stream = File.OpenRead(FileName);
    definition = new Byte[stream.Length];
    stream.Read(definition, 0, (int) stream.Length);
    stream.Close();
   }

   catch(IOException e)
   {
    
   }

   try
   {
    warnings = rs.CreateReport(name,FolderName , false, definition, null);

    if (warnings != null)
    {
     foreach (Warning warning in warnings)
     {
      
     }
    }

    else
    {
    }
   }

   catch (SoapException e)
   {
    
   }


  }


 
  public void Generate(string FileName)
  {
   try
   {
    // Call methods to create the RDL
    
    this.OpenConnection();
    this.GenerateFieldsList();
    this.GenerateRdl(FileName);

    
   }

   catch (Exception exception)
   {
    
   }

   finally
   {
    // Close the connection string
    m_connection.Close();
   }
  }

  private void OpenConnection()
  {
   // TODO: Open a connection to the sample database
   m_connection = new SqlConnection();
        
   // Create the connection string
  
   m_connection.ConnectionString = m_connectString;
        
   // Open the connection
   m_connection.Open();

  }

  private void GenerateFieldsList()
  {
   // TODO: Generate a list of fields for a report query
   SqlCommand command;
   SqlDataReader reader;

   // Executing a query to retrieve a fields list for the report
   command = m_connection.CreateCommand();
   command.CommandText = m_commandText;
  
   // Execute and create a reader for the current command
   reader = command.ExecuteReader(CommandBehavior.SchemaOnly);
  
   // For each field in the resultset, add the name to an array list
   m_fields = new ArrayList();
   for (int i = 0; i <= reader.FieldCount - 1; i++)
   {
    m_fields.Add(reader.GetName(i));
   }

  }

  private  void GenerateRdl(string FileName)
  {
   // TODO: Generate RDL using XmlTextWriter
   // Open a new RDL file stream for writing
   FileStream stream;
   stream = File.OpenWrite(FileName);
   XmlTextWriter writer = new XmlTextWriter(stream, Encoding.UTF8);

   // Causes child elements to be indented
   writer.Formatting = Formatting.Indented;

   // Report element
   writer.WriteProcessingInstruction("xml", "version=/"1.0/" encoding=/"utf-8/"");
   writer.WriteStartElement("Report");
   writer.WriteAttributeString("xmlns", null, "http://schemas.microsoft.com/sqlserver/reporting/2003/10/reportdefinition");
   writer.WriteElementString("Width", "6in");

   // DataSource element
   writer.WriteStartElement("DataSources");
   writer.WriteStartElement("DataSource");
   writer.WriteAttributeString("Name", null, "DataSource1");
   writer.WriteStartElement("ConnectionProperties");
   writer.WriteElementString("DataProvider", "SQL");
   writer.WriteElementString("ConnectString", m_connectString);
   writer.WriteElementString("IntegratedSecurity", "true");
   writer.WriteEndElement(); // ConnectionProperties
   writer.WriteEndElement(); // DataSource
   writer.WriteEndElement(); // DataSources

   // DataSet element
   writer.WriteStartElement("DataSets");
   writer.WriteStartElement("DataSet");
   writer.WriteAttributeString("Name", null, "DataSet1");

   // Query element
   writer.WriteStartElement("Query");
   writer.WriteElementString("DataSourceName", "DataSource1");
   writer.WriteElementString("CommandType", "Text");
   writer.WriteElementString("CommandText", m_commandText);
   writer.WriteElementString("Timeout", "30");
   writer.WriteEndElement(); // Query

   // Fields elements
   writer.WriteStartElement("Fields");
   foreach (string fieldName in m_fields)
   {
    writer.WriteStartElement("Field");
    writer.WriteAttributeString("Name", null, fieldName);
    writer.WriteElementString("DataField", null, fieldName);
    writer.WriteEndElement(); // Field
   }

   // End previous elements
   writer.WriteEndElement(); // Fields
   writer.WriteEndElement(); // DataSet
   writer.WriteEndElement(); // DataSets

   // Body element
   writer.WriteStartElement("Body");
   writer.WriteElementString("Height", "5in");

   // ReportItems element
   writer.WriteStartElement("ReportItems");

   // Table element
   writer.WriteStartElement("Table");
   writer.WriteAttributeString("Name", null, "Table1");
   writer.WriteElementString("DataSetName", "DataSet1");
   writer.WriteElementString("Top", ".5in");
   writer.WriteElementString("Left", ".5in");
   writer.WriteElementString("Height", ".5in");
   writer.WriteElementString("Width", (m_fields.Count * 1.5) + "in");

   // Table Columns
   writer.WriteStartElement("TableColumns");
   for (int i = 0; i < m_fields.Count; i++)
   {
    writer.WriteStartElement("TableColumn");
    writer.WriteElementString("Width", "1.5in");
    writer.WriteEndElement(); // TableColumn
   }
   writer.WriteEndElement(); // TableColumns

   // Header Row
   writer.WriteStartElement("Header");
   writer.WriteStartElement("TableRows");
   writer.WriteStartElement("TableRow");
   writer.WriteElementString("Height", ".25in");
   writer.WriteStartElement("TableCells");

   foreach (string fieldName in m_fields)
   {
    writer.WriteStartElement("TableCell");
    writer.WriteStartElement("ReportItems");

    // Textbox
    writer.WriteStartElement("Textbox");
    writer.WriteAttributeString("Name", null, "Header" + fieldName);

    writer.WriteStartElement("Style");
    writer.WriteElementString("TextDecoration", "Underline");
    writer.WriteEndElement(); // Style

    writer.WriteElementString("Top", "0in");
    writer.WriteElementString("Left", "0in");
    writer.WriteElementString("Height", ".5in");
    writer.WriteElementString("Width", "1.5in");
    writer.WriteElementString("Value", fieldName);
    writer.WriteEndElement(); // Textbox

    writer.WriteEndElement(); // ReportItems
    writer.WriteEndElement(); // TableCell
   }

   writer.WriteEndElement(); // TableCells
   writer.WriteEndElement(); // TableRow
   writer.WriteEndElement(); // TableRows
   writer.WriteEndElement(); // Header

   // Details Row
   writer.WriteStartElement("Details");
   writer.WriteStartElement("TableRows");
   writer.WriteStartElement("TableRow");
   writer.WriteElementString("Height", ".25in");
   writer.WriteStartElement("TableCells");

   foreach (string fieldName in m_fields)
   {
    writer.WriteStartElement("TableCell");
    writer.WriteStartElement("ReportItems");

    // Textbox
    writer.WriteStartElement("Textbox");
    writer.WriteAttributeString("Name", null, fieldName);

    writer.WriteStartElement("Style");
    writer.WriteEndElement(); // Style

    writer.WriteElementString("Top", "0in");
    writer.WriteElementString("Left", "0in");
    writer.WriteElementString("Height", ".5in");
    writer.WriteElementString("Width", "1.5in");
    writer.WriteElementString("Value", "=Fields!" + fieldName + ".Value");
    writer.WriteElementString("HideDuplicates", "DataSet1");
    writer.WriteEndElement(); // Textbox

    writer.WriteEndElement(); // ReportItems
    writer.WriteEndElement(); // TableCell
   }  

   // End Details element and children  
   writer.WriteEndElement(); // TableCells
   writer.WriteEndElement(); // TableRow
   writer.WriteEndElement(); // TableRows
   writer.WriteEndElement(); // Details

   // End table element and end report definition file
   writer.WriteEndElement(); // Table
   writer.WriteEndElement(); // ReportItems
   writer.WriteEndElement(); // Body
   writer.WriteEndElement(); // Report

   // Flush the writer and close the stream
   writer.Flush();
   stream.Close();

  }
 }
}
  這只是我個人的一個想當然的做法,尚未經過測試,不知道性能是否可以.另外它的樣式太單一...用餅圖的話我還沒有試驗,這裏只是一個Table

公佈了兩個公開的函數.Generate()用以在服務器產生RDl報表文件,UPLoad用以上傳報表文件,使用時要實例化一個新實例.

僅做參考哈..我不知道一般的做法是怎麼樣的.我是這樣想的..不知道是否可以用rs webservice 的QueryText屬性做到同樣的效果.還有一個問題是報表名的不唯一問題.我想在沒有學會GUID的時候是否可以簡單的用時間代替.

報表服務中的編程

報表服務中的編程

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資源,而且便於最終用戶作更多的控制,實現最終用戶的個性化。

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章