domingo, 17 de junio de 2012

Cargar y modificar un informe de Report Server

Enunciado

En ocasiones puede resultar interesante leer un informe definido en el servidor de  Microsoft Reporting Services, modificar la definición y volver subirlo al servidor para visualizar en un webform Report viewer.
Redactaré mas adelante algunos ejemplos de aplicación, por el momento.

Solución

El problema se divide en tres partes:

  1. Leer la definición del informe.
  2. Modificar el XML de esta definición mediante Linq to XML
  3. Establecer la definición modificada en el report Viewer.

Leer la definición del informe desde el servidor


Hay que acceder a los servicios web de Reporting Services, para ello se crea una un clase proxy mediante WSDL.EXE y una clase con las credenciales necesarias para autentificarse.
Una vez hecho esto es relativamente fácil.
 Private Function CargaInforme(nombre As String) As XDocument
        Dim SSRS As New ReportingService2010
        SSRS.Credentials = (New MyReportServerCredentials).NetworkCredentials
        Dim informe = SSRS.GetItemDefinition(My.Settings.mapas + nombre)
        SSRS = Nothing
        Dim stream = New System.IO.MemoryStream(informe)
        Dim lector = System.Xml.XmlReader.Create(stream)
        Dim doc As XDocument = XDocument.Load(lector, LoadOptions.None)
        Return doc
    End Function

En breve, el servicio veb me devuelve un array de bytes, que traslado a un memory stream que a su vez me permite crear un xdocument.

Modificar la definición de informe

Esto es lo mas fácil, aunque a veces engorroso. Por ejemplo vamos a cambiar la definición del Dataset "datos" en el informe.
Dim df = doc.Root.Name.Namespace
            Dim xdatos = (From f In doc.Root.Element(df + "DataSets").Elements(df + "DataSet")).First(
            Function(x As XElement) x.Attribute("Name") = "Datos").Element(df + "Query").Element(df + "CommandText")
            xdatos.SetValue(s)
S es un string con la sentencia SQL, MDX o lo que quiera que utilices, por supuesto tiene que se coherente con el resto del informe en lo que atañe a nombres de campo, parametros,...etc

Visualizar el informe modificado en Report Viewer

Para hacerlo necesitaremos convertir nuestro Xdocument que contiene la definición en un stream:
 Private Function XMLBytes(doc As XDocument) As System.IO.Stream
        Dim stream As New System.IO.MemoryStream
        Dim escritor = System.Xml.XmlWriter.Create(stream)
        doc.Save(escritor)
        escritor.Close()
        stream.Position = 0
        Return stream
    End Function
Lo que sigue es asignar este stream al visor de informes, establecer los parámetros que hagan falta y refrescar
Visor.ServerReport.LoadReportDefinition(e.Informe)
Visor.ServerReport.SetParameters(New ReportParameter("miParametro", suValor))
Visor.ServerReport.Refresh()

No hay comentarios: