• VS2005+SQL2005 Reporting Service动态绑定报表(Web)


    一、综述

            这里我要介绍的是如何使用
    VS2005中的ReportViewer控件动态显示需要绑定的报表(*.rdlc)。由于我们已经很习惯使用DataSet作为数据源去绑定类似于GridView或者DataGrid等控件,那么是否有方法将DataSet作为数据源就像绑定GridView这样去绑定报表呢?答案肯定的。

            让我们先看下最简单的连接方法Reporting Service使用dataset.xsd作为数据源,建立一个页面page.aspx对应一个reportviewer控件对应一张report.rdlc报表对应一个dataset.xsd数据源。运用这种模式,那么在VS2005中提供了一个强大的向导,只需按照向导操作,网上资料或者MSDN中都介绍的很详细如何使用这个向导,在此不再详细描述。

            其次,也是我主要要介绍的,动态绑定到ado.net dataset:由于大部分数据都是采用ado.net dataset作为数据源绑定,如果使用提供的向导操作便不能进行动态绑定,对于后台操作非常不便,故不能使用向导操作。现在要设法动态绑定ado.net dataset到指定的report。
            优点在于代码简单,操作灵活;
            缺点在于设计report文件将变得非常令人头疼。
            report文件是xml格式的,如果不使用向导那么就必须人为的去写这个xml文件(我研究了很久,没找到其他设计报表的方法,这麽写也是摸索出来的,掌握了就很方便了),特别当存储过程是动态的时候,设计这个报表的数据源将变得更为烦锁。但是同样的优点在于一切的问题只要掌握了如何去写这个文件,那么就等于解决了所有问题,独立性强。

    二、使用WebForms ReportViewer控件

            在一个WEB应用程序中,为了浏览在服务器上(report server)配置好的报表或者在本地文件系统(local file system)上的报表,你可以使用WebForms ReportViewer控件。

    增加一个ReportViewer控件到一个Web应用程序

    1、 增加一个新的Microsoft ASP.NET Web Site使用Microsoft Visual C# 或者 Microsoft Visual Basic

    2、 从工具箱中将ReportViewer控件拖到设计页面上,命名为reportViewer,当增加完之后,ReportViewer任务标签中会出现提示让你选择一个报表,此处可不去管它。

    3、使用远程处理模式(Remote Processing Mode)浏览报表

    下面的例子详细展示了如何提交一个报表存在于报表服务器上,这个例子使用Sales Order Detail Report。这张表报存在于SQL2005的示例(AdventureWorks)中,你只需安装SQL2005的示例,便能从里面找到,更详细信息关于示例,请看AdventureWorks Report Samples

           这个例子使用Windows综合认证,所以你必须首先在web.config中加入

    <!-- Web.config file. --> <identity impersonate="true"/>
    C#

     1protected void Page_Init(object sender, EventArgs e)
     2{
     3    if (!Page.IsPostBack)
     4    {
     5        // Set the processing mode for the ReportViewer to Remote
     6        reportViewer.ProcessingMode = ProcessingMode.Remote;
     7
     8        ServerReport serverReport = reportViewer.ServerReport;
     9
    10        // Set the report server URL and report path
    11        serverReport.ReportServerUrl =
    12            new Uri("http://localhost/reportserver");
    13        serverReport.ReportPath =
    14            "/AdventureWorks Sample Reports/Sales Order Detail";
    15
    16        // Create the sales order number report parameter
    17        ReportParameter salesOrderNumber = new ReportParameter();
    18        salesOrderNumber.Name = "SalesOrderNumber";
    19        salesOrderNumber.Values.Add("SO43661");
    20
    21        // Set the report parameters for the report
    22        reportViewer.ServerReport.SetParameters(
    23            new ReportParameter[] { salesOrderNumber });
    24    }

    25}

     VB

     1Imports Microsoft.Reporting.WebForms
     2
     3Partial Class _Default
     4    Inherits System.Web.UI.Page
     5
     6    Protected Sub Page_Init(ByVal sender As Object, _
     7            ByVal e As System.EventArgs) Handles Me.Init
     8
     9        If Not Page.IsPostBack Then
    10
    11            'Set the processing mode for the ReportViewer to Remote
    12            reportViewer.ProcessingMode = ProcessingMode.Remote
    13
    14            Dim serverReport As ServerReport
    15            serverReport = reportViewer.ServerReport
    16
    17            'Set the report server URL and report path
    18            serverReport.ReportServerUrl = _
    19                New Uri("http://localhost/reportserver")
    20            serverReport.ReportPath = _
    21                "/AdventureWorks Sample Reports/Sales Order Detail"
    22
    23            'Create the sales order number report parameter
    24            Dim salesOrderNumber As New ReportParameter()
    25            salesOrderNumber.Name = "SalesOrderNumber"
    26            salesOrderNumber.Values.Add("SO43661")
    27
    28            'Set the report parameters for the report
    29            Dim parameters() As ReportParameter = {salesOrderNumber}
    30            serverReport.SetParameters(parameters)
    31
    32        End If
    33
    34    End Sub

    35
    36End Class

     

    4、使用本地处理模式(Local Processing Mode)浏览报表

    这个例子同样使用了AdventureWorks Report Samples,你可以在本文章的最下面点击下载我做好的例子。

    (1)       打开一个Web Site提供报表的增加

    (2)       从菜单栏选择增加现有项

    (3)       C:\Program Files\Microsoft SQL Server\90\Samples\Reporting Services\Report Samples\AdventureWorks Sample Reports\ Sales Order Detail.rdl 报表文件加入项目

    (4)       重命名Sales Order Detail.rdlSales Order Detail.rdlc

    (5)       下面的例子将会在本地模式下建立一个dataset作为报表的数据源显示报表

     C#

      1protected void Page_Init(object sender, EventArgs e)
      2{
      3    if (!Page.IsPostBack)
      4    {
      5        // Set the processing mode for the ReportViewer to Local
      6        reportViewer.ProcessingMode = ProcessingMode.Local;
      7
      8        LocalReport localReport = reportViewer.LocalReport;
      9
     10        localReport.ReportPath = "Sales Order Detail.rdlc";
     11
     12        DataSet dataset = new DataSet("Sales Order Detail");
     13
     14        string salesOrderNumber = "SO43661";
     15
     16        GetSalesOrderData(salesOrderNumber, ref dataset);
     17
     18        ReportDataSource dsSalesOrder = new ReportDataSource();
     19        dsSalesOrder.Name = "SalesOrder";
     20        dsSalesOrder.Value = dataset.Tables["SalesOrder"];
     21
     22        localReport.DataSources.Add(dsSalesOrder);
     23
     24        GetSalesOrderDetailData(salesOrderNumber, ref dataset);
     25
     26        ReportDataSource dsSalesOrderDetail = new ReportDataSource();
     27        dsSalesOrderDetail.Name = "SalesOrderDetail";
     28        dsSalesOrderDetail.Value = dataset.Tables["SalesOrderDetail"];
     29
     30        localReport.DataSources.Add(dsSalesOrderDetail);
     31
     32        // Create the sales order number report parameter
     33        ReportParameter rpSalesOrderNumber = new ReportParameter();
     34        rpSalesOrderNumber.Name = "SalesOrderNumber";
     35        rpSalesOrderNumber.Values.Add("SO43661");
     36
     37        // Set the report parameters for the report
     38        localReport.SetParameters(
     39            new ReportParameter[] { rpSalesOrderNumber });
     40    }

     41}

     42
     43private void GetSalesOrderData(string salesOrderNumber,
     44                           ref DataSet dsSalesOrder)
     45{
     46    string sqlSalesOrder =
     47        "SELECT SOH.SalesOrderNumber, S.Name AS Store, " +
     48        "       SOH.OrderDate, C.FirstName AS SalesFirstName, " +
     49        "       C.LastName AS SalesLastName, E.Title AS " +
     50        "       SalesTitle, SOH.PurchaseOrderNumber, " +
     51        "       SM.Name AS ShipMethod, BA.AddressLine1 " +
     52        "       AS BillAddress1, BA.AddressLine2 AS " +
     53        "       BillAddress2, BA.City AS BillCity, " +
     54        "       BA.PostalCode AS BillPostalCode, BSP.Name " +
     55        "       AS BillStateProvince, BCR.Name AS " +
     56        "       BillCountryRegion, SA.AddressLine1 AS " +
     57        "       ShipAddress1, SA.AddressLine2 AS " +
     58        "       ShipAddress2, SA.City AS ShipCity, " +
     59        "       SA.PostalCode AS ShipPostalCode, SSP.Name " +
     60        "       AS ShipStateProvince, SCR.Name AS " +
     61        "       ShipCountryRegion, CC.Phone AS CustPhone, " +
     62        "       CC.FirstName AS CustFirstName, CC.LastName " +
     63        "       AS CustLastName " +
     64        "FROM   Person.Address SA INNER JOIN " +
     65        "       Person.StateProvince SSP ON " +
     66        "       SA.StateProvinceID = SSP.StateProvinceID " +
     67        "       INNER JOIN Person.CountryRegion SCR ON " +
     68        "       SSP.CountryRegionCode = SCR.CountryRegionCode " +
     69        "       RIGHT OUTER JOIN Sales.SalesOrderHeader SOH " +
     70        "       LEFT OUTER JOIN  Person.Contact CC ON " +
     71        "       SOH.ContactID = CC.ContactID LEFT OUTER JOIN" +
     72        "       Person.Address BA INNER JOIN " +
     73        "       Person.StateProvince BSP ON " +
     74        "       BA.StateProvinceID = BSP.StateProvinceID " +
     75        "       INNER JOIN Person.CountryRegion BCR ON " +
     76        "       BSP.CountryRegionCode = " +
     77        "       BCR.CountryRegionCode ON SOH.BillToAddressID " +
     78        "       = BA.AddressID ON  SA.AddressID = " +
     79        "       SOH.ShipToAddressID LEFT OUTER JOIN " +
     80        "       Person.Contact C RIGHT OUTER JOIN " +
     81        "       HumanResources.Employee E ON C.ContactID = " +
     82        "       E.ContactID ON SOH.SalesPersonID = " +
     83        "       E.EmployeeID LEFT OUTER JOIN " +
     84        "       Purchasing.ShipMethod SM ON SOH.ShipMethodID " +
     85        "       = SM.ShipMethodID LEFT OUTER JOIN Sales.Store" +
     86        "        S ON SOH.CustomerID = S.CustomerID " +
     87        "WHERE  (SOH.SalesOrderNumber = @SalesOrderNumber)";
     88
     89    SqlConnection connection = new
     90        SqlConnection("Data Source=(local); " +
     91                      "Initial Catalog=AdventureWorks; " +
     92                      "Integrated Security=SSPI");
     93
     94    SqlCommand command =
     95        new SqlCommand(sqlSalesOrder, connection);
     96
     97    command.Parameters.Add(
     98        new SqlParameter("SalesOrderNumber",
     99        salesOrderNumber));
    100
    101    SqlDataAdapter salesOrderAdapter = new
    102        SqlDataAdapter(command);
    103
    104    salesOrderAdapter.Fill(dsSalesOrder, "SalesOrder");
    105}

    106
    107private void GetSalesOrderDetailData(string salesOrderNumber,
    108                       ref DataSet dsSalesOrder)
    109{
    110    string sqlSalesOrderDetail =
    111        "SELECT  SOD.SalesOrderDetailID, SOD.OrderQty, " +
    112        "        SOD.UnitPrice, CASE WHEN " +
    113        "        SOD.UnitPriceDiscount IS NULL THEN 0 " +
    114        "        ELSE SOD.UnitPriceDiscount END AS " +
    115        "        UnitPriceDiscount, SOD.LineTotal, " +
    116        "        SOD.CarrierTrackingNumber, " +
    117        "        SOD.SalesOrderID, P.Name, P.ProductNumber " +
    118        "FROM    Sales.SalesOrderDetail SOD INNER JOIN " +
    119        "        Production.Product P ON SOD.ProductID = " +
    120        "        P.ProductID INNER JOIN " +
    121        "        Sales.SalesOrderHeader SOH ON " +
    122        "        SOD.SalesOrderID = SOH.SalesOrderID " +
    123        "WHERE   (SOH.SalesOrderNumber = @SalesOrderNumber) " +
    124        "ORDER BY SOD.SalesOrderDetailID";
    125
    126    using (SqlConnection connection = new
    127        SqlConnection("Data Source=(local); " +
    128                      "Initial Catalog=AdventureWorks; " +
    129                      "Integrated Security=SSPI"))
    130    {
    131
    132        SqlCommand command =
    133            new SqlCommand(sqlSalesOrderDetail, connection);
    134
    135        command.Parameters.Add(
    136            new SqlParameter("SalesOrderNumber",
    137            salesOrderNumber));
    138
    139        SqlDataAdapter salesOrderDetailAdapter = new
    140            SqlDataAdapter(command);
    141
    142        salesOrderDetailAdapter.Fill(dsSalesOrder,
    143            "SalesOrderDetail");
    144    }

    145}

     VB

    Imports System.Data
    Imports System.Data.SqlClient
    Imports Microsoft.Reporting.WebForms

    Partial 
    Class _Default
        
    Inherits System.Web.UI.Page

        
    Protected Sub Page_Init(ByVal sender As Object, _
                    
    ByVal e As System.EventArgs) Handles Me.Init

            
    If Not Page.IsPostBack Then

                
    'Set the processing mode for the ReportViewer to Local
                reportViewer.ProcessingMode = ProcessingMode.Local

                
    Dim localReport As LocalReport
                localReport 
    = reportViewer.LocalReport

                localReport.ReportPath 
    = "Sales Order Detail.rdlc"

                
    Dim dataset As New DataSet("Sales Order Detail")

                
    Dim salesOrderNumber As String = "SO43661"

                
    'Get the sales order data
                GetSalesOrderData(salesOrderNumber, dataset)

                
    'Create a report data source for the sales order data
                Dim dsSalesOrder As New ReportDataSource()
                dsSalesOrder.Name 
    = "SalesOrder"
                dsSalesOrder.Value 
    = dataset.Tables("SalesOrder")

                localReport.DataSources.Add(dsSalesOrder)

                
    'Get the sales order detail data
                GetSalesOrderDetailData(salesOrderNumber, dataset)

                
    'Create a report data source for the sales 
                'order detail data
                Dim dsSalesOrderDetail As New ReportDataSource()
                dsSalesOrderDetail.Name 
    = "SalesOrderDetail"
                dsSalesOrderDetail.Value 
    = _
                    dataset.Tables(
    "SalesOrderDetail")

                localReport.DataSources.Add(dsSalesOrderDetail)

                
    'Create a report parameter for the sales order number 
                Dim rpSalesOrderNumber As New ReportParameter()
                rpSalesOrderNumber.Name 
    = "SalesOrderNumber"
                rpSalesOrderNumber.Values.Add(
    "SO43661")

                
    'Set the report parameters for the report
                Dim parameters() As ReportParameter = {rpSalesOrderNumber}
                localReport.SetParameters(parameters)

            
    End If

        
    End Sub


        
    Private Sub GetSalesOrderData(ByVal salesOrderNumber As String, _
                                   
    ByRef dsSalesOrder As DataSet)

            
    Dim sqlSalesOrder As String = _
                
    "SELECT SOH.SalesOrderNumber, S.Name AS Store, " & _
                
    "       SOH.OrderDate, C.FirstName AS SalesFirstName, " & _
                
    "       C.LastName AS SalesLastName, E.Title AS " & _
                
    "       SalesTitle, SOH.PurchaseOrderNumber, " & _
                
    "       SM.Name AS ShipMethod, BA.AddressLine1 " & _
                
    "       AS BillAddress1, BA.AddressLine2 AS " & _
                
    "       BillAddress2, BA.City AS BillCity, " & _
                
    "       BA.PostalCode AS BillPostalCode, BSP.Name " & _
                
    "       AS BillStateProvince, BCR.Name AS " & _
                
    "       BillCountryRegion, SA.AddressLine1 AS " & _
                
    "       ShipAddress1, SA.AddressLine2 AS " & _
                
    "       ShipAddress2, SA.City AS ShipCity, " & _
                
    "       SA.PostalCode AS ShipPostalCode, SSP.Name " & _
                
    "       AS ShipStateProvince, SCR.Name AS " & _
                
    "       ShipCountryRegion, CC.Phone AS CustPhone, " & _
                
    "       CC.FirstName AS CustFirstName, CC.LastName " & _
                
    "       AS CustLastName " & _
                
    "FROM   Person.Address SA INNER JOIN " & _
                
    "       Person.StateProvince SSP ON " & _
                
    "       SA.StateProvinceID = SSP.StateProvinceID " & _
                
    "       INNER JOIN Person.CountryRegion SCR ON " & _
                
    "       SSP.CountryRegionCode = SCR.CountryRegionCode " & _
                
    "       RIGHT OUTER JOIN Sales.SalesOrderHeader SOH " & _
                
    "       LEFT OUTER JOIN  Person.Contact CC ON " & _
                
    "       SOH.ContactID = CC.ContactID LEFT OUTER JOIN" & _
                
    "       Person.Address BA INNER JOIN " & _
                
    "       Person.StateProvince BSP ON " & _
                
    "       BA.StateProvinceID = BSP.StateProvinceID " & _
                
    "       INNER JOIN Person.CountryRegion BCR ON " & _
                
    "       BSP.CountryRegionCode = " & _
                
    "       BCR.CountryRegionCode ON SOH.BillToAddressID " & _
                
    "       = BA.AddressID ON  SA.AddressID = " & _
                
    "       SOH.ShipToAddressID LEFT OUTER JOIN " & _
                
    "       Person.Contact C RIGHT OUTER JOIN " & _
                
    "       HumanResources.Employee E ON C.ContactID = " & _
                
    "       E.ContactID ON SOH.SalesPersonID = " & _
                
    "       E.EmployeeID LEFT OUTER JOIN " & _
                
    "       Purchasing.ShipMethod SM ON SOH.ShipMethodID " & _
                
    "       = SM.ShipMethodID LEFT OUTER JOIN Sales.Store" & _
                
    "        S ON SOH.CustomerID = S.CustomerID " & _
                
    "WHERE  (SOH.SalesOrderNumber = @SalesOrderNumber)"

            Using connection 
    As New SqlConnection( _
                          
    "Data Source=(local); " & _
                          
    "Initial Catalog=AdventureWorks; " & _
                          
    "Integrated Security=SSPI")

                
    Dim command As New SqlCommand(sqlSalesOrder, connection)

                
    Dim parameter As New SqlParameter("SalesOrderNumber", _
                    salesOrderNumber)
                
    command.Parameters.Add(parameter)

                
    Dim salesOrderAdapter As New SqlDataAdapter(command)

                salesOrderAdapter.Fill(dsSalesOrder, 
    "SalesOrder")

            
    End Using

        
    End Sub


        
    Private Sub GetSalesOrderDetailData( _
                               
    ByVal salesOrderNumber As String, _
                               
    ByRef dsSalesOrder As DataSet)

            
    Dim sqlSalesOrderDetail As String = _
                
    "SELECT  SOD.SalesOrderDetailID, SOD.OrderQty, " & _
                
    "        SOD.UnitPrice, CASE WHEN " & _
                
    "        SOD.UnitPriceDiscount IS NULL THEN 0 " & _
                
    "        ELSE SOD.UnitPriceDiscount END AS " & _
                
    "        UnitPriceDiscount, SOD.LineTotal, " & _
                
    "        SOD.CarrierTrackingNumber, " & _
                
    "        SOD.SalesOrderID, P.Name, P.ProductNumber " & _
                
    "FROM    Sales.SalesOrderDetail SOD INNER JOIN " & _
                
    "        Production.Product P ON SOD.ProductID = " & _
                
    "        P.ProductID INNER JOIN " & _
                
    "        Sales.SalesOrderHeader SOH ON " & _
                
    "        SOD.SalesOrderID = SOH.SalesOrderID " & _
                
    "WHERE   (SOH.SalesOrderNumber = @SalesOrderNumber) " & _
                
    "ORDER BY SOD.SalesOrderDetailID"

            Using connection 
    As New SqlConnection( _
                          
    "Data Source=(local); " & _
                          
    "Initial Catalog=AdventureWorks; " & _
                          
    "Integrated Security=SSPI")

                
    Dim command As New SqlCommand(sqlSalesOrderDetail, _
                                              connection)

                
    Dim parameter As New SqlParameter("SalesOrderNumber", _
                    salesOrderNumber)
                
    command.Parameters.Add(parameter)

                
    Dim salesOrderDetailAdapter As New SqlDataAdapter(command)

                salesOrderDetailAdapter.Fill(dsSalesOrder, _
                    
    "SalesOrderDetail")

            
    End Using

        
    End Sub


    End Class

     

    三、设计报表连接数据源

            当做完以上工作后,还需要设计报表的连接数据源,用记事本打开Sales Order Detail.rdlc。你只需详细关注里面的DataSourcesDataSets就可

     1 <DataSources>
     2
     3    <DataSource Name="AdventureWorks">       --报表数据源名称必须统一
     4
     5        <ConnectionProperties>
     6
     7        <ConnectString />
     8
     9        <DataProvider>SQL</DataProvider>
    10
    11      </ConnectionProperties>
    12
    13    </DataSource>
    14
    15 </DataSources>
    16
    17 <DataSets>
    18
    19   <DataSet Name="SalesOrderDetail">          --对应于程序中dsSalesOrderDetail.Name = "SalesOrderDetail"
    20
    21      <Fields>                                                      --所有dataset中有的列必须在此申明
    22
    23        <Field Name="SalesOrderDetailID">
    24
    25          <DataField>SalesOrderDetailID</DataField>
    26
    27          <rd:TypeName>System.Int32</rd:TypeName>
    28
    29        </Field>
    30
    31      </Fields>
    32
    33      <Query>
    34
    35        <DataSourceName>AdventureWorks</DataSourceName>
    36
    37        <CommandText>
    38
    39       </CommandText>
    40
    41        <Timeout>30</Timeout>
    42
    43        <rd:UseGenericDesigner>true</rd:UseGenericDesigner>
    44
    45      </Query>
    46
    47    </DataSet>
    48
    49 </DataSets>
    50


            其中DataSet <DataSet Name="SalesOrderDetail">属性对应于程序中的

     Dim dsSalesOrderDetail As New ReportDataSource()

     dsSalesOrderDetail.Name = "SalesOrderDetail"//对应该属性

     dsSalesOrderDetail.Value =dataset.Tables("SalesOrderDetail")//绑定已经存在的dataset

     localReport.DataSources.Add(dsSalesOrderDetail)

            只要rdlc文件符合规范,其中的Fields设置为所有得出列名,定义的datasource name没有规定,但是必须统一,既可。你只要按照这样的格式去写一个报表文件,那么任何dataset都是可以绑定上去的,也就是说比如从将一个存储过程返回的dataset绑定到一张报表上面。

    提示:

            所有的列名申明将是一个非常令人头疼的问题,我所能作到的最简单的方法是按照向导作出一张报表,然后提取里面的所有fields复制到我要产生的报表中,如果你有更好的方法还请尽快告诉我,谢谢。

        最后就是在报表上增加你想要显示的数据了,增加Reports Item,绑定参数等等,在此不作为本文介绍的内容。

    四、总结

            对于动态绑定报表的优点实在是太多了,你可以像绑定一个DataGrid那样去绑定一张报表,而且Reporting Services支持强大导出的功能也会让你的报表更满足你的需要。你可以从不同的页面传递不同的参数到同一个报表显示页面,根据参数的不同显示不同的报表,后台的代码是非常简单,唯一比较繁琐的任务都在于报表本身的设计。

           呵呵,总算写完了,如果你有更好的方法还请一定联系我,大家交流,共同进步。

    示例程序代码:/Files/Carlwave/reportSample.rar(要求:安装了SQL2005和VS2005即可)

  • 相关阅读:
    新浪微博学习的知识点
    新浪项目笔记
    2015年10月20日整理知识
    版本管理工具 (git 或者 svn)
    Coding 代码push/commit/pull/git clone
    fileurlwithpath urlwithstring 这俩有啥区别吗
    正则表达式
    地图
    各种杂项
    实时通讯
  • 原文地址:https://www.cnblogs.com/younger/p/571653.html
Copyright © 2020-2023  润新知