Introducción

Cuando se quiere exportar reportes hechos en Crystal Reports y vistos a través del CrystalReportViewer en aplicaciones ASP.NET, este no cuenta con un botón exportar, que dentro de aplicaciones Windows existe. Este ejemplo permite exportar a diferentes formatos (EXCEL, PDF, RTF y WORD) usando la funcionalidad que trae el Crystal Reports para dicho objetivo.

Explicación

Para empezar con el ejemplo se crea un nuevo proyecto Web, en este ejemplo toma el nombre de WebApp. Luego se crea un reporte simple, pero antes de eso, tomando en cuenta el diseño de aplicaciones multicapa, en la cual, por ejemplo en el modelo de tres capas, la capa de presentación no debe tener ningún acceso directo a la base de datos, sino a través de la capa de lógica de negocios; para lograr este objetivo y dado que Crystal Reports dá la posibilidad de diseñar los reportes a partir de un DataSet, entonces primero se agrega un DataSet al proyecto y se obtiene su estructura arrastrando desde el ServerExplorer la tabla Customers de la base de datos Northwind (también se puede hacer manualmente, pero para efectos de prueba se hizo por este camino)

DataSet creado a partir de la tabla Customers de la base de Datos Northwind

Una vez creado el DataSet, se procede a crear el reporte:

Creación de un reporte a partir del DataSet
Columnas que aparecerán en el reporte

En esta parte se mostrará partes importantes que hacen que funcione el ejemplo

vbnet:

Private Sub Page_Load(ByVal sender As System.Object, _
                ByVal e As System.EventArgs) Handles MyBase.Load
        ' ***********************************************************************
        Dim strConexion As String = ConfigurationSettings.AppSetting("strConexion")
        Dim da As New SqlClient.SqlDataAdapter("select * from Customers", strConexion)
        ds = New DataSet
        da.Fill(ds, "Clientes")
        ' ***********************************************************************       
        rptClientes.SetDataSource(ds.Tables("Clientes"))
        crvClientes.ReportSource = rptClientes
End Sub
 

En la parte encerrada entre *, debería ir código que utilize la Capa de Negocios para establecer el DataSource del reporte y así evitar el acceso directo a la base de datos (como aparece en el código mostrado).

vbnet:

' Crea un stream
Dim rptStream As New System.IO.MemoryStream
' Se exporta el reporte a un stream,
' luego se hace una conversión para el tipo adecuado
rptStream = CType(rptClientes.ExportToStream(Integer.Parse(ddlTipos.SelectedValue)), _
                                        System.IO.MemoryStream)
' Limpia el buffer
Response.Clear()
Response.Buffer = True
' Establece el tipo de documento
Response.ContentType = TipoDocumento()
' Fuerza a hacer un download del archivo
Response.AddHeader("Content-Disposition", "attachment;filename=" + Me.nombreXdefecto)
' Escribe el contenido del stream
Response.BinaryWrite(rptStream.ToArray())
Response.End()
 

En el código mostrado, básicamente lo que se hace es exportar el reporte a un Stream, de acuerdo al tipo de documento seleccionado en el combo y enviarlo al cliente con dichas opciones utilizando el método Response.BinaryWrite que toma como parámetro un array.

Actualización

Gracias al aporte de Felix Azuaje, uno de los lectores del artículo, pongo a disposición el código que me envió en el cuál utiliza otro tipo de conexión (ADODB) para cargar los datos en los reportes y no usando DataSet's. Pueden descargarlo de aquí

Elementos utilizados

Referencias y enlaces relacionados

Autor

Alexander Concha Abarca
Instructor 3ra Estrella - VB.NET
xknown at hotmail.com