jueves, 27 de noviembre de 2008

Como crear Reportes Dinámicos con Crystal Reports y C# en WebForms usando DataSets y DataTables

Hace tiempo me tope con la necesidad de generar reportes en ASP.NET e imprimirlos. Investigando un poco, me tope con el detalle que no es tan fácil realizarlo como sería en un ambiente de escritorio. De hecho, se complicaba un poco más ya que debía de utilizar DataSets dinámicos, es decir, generados durante el uso de la aplicación, no desde un principio.

Decidí utilizar Crystal Reports, ya que se encuentra implementado dentro de Visual Studio 2005, incluyendo opciones como exportación a diferentes formatos como Excel y PDF.

Investigando un poco, me encontré con un código proporcionado por Fernando Berenguer Doménech en el cuál explicaba el método para realizarlo. Basándome en este gran apoyo, pude dar con la solución que a continuación expongo:

Principalmente agregó al proyecto un reporte Crystal Reports desde el Explorador de Soluciones. Yo le deje el nombre de CrystalReport.rpt

Más adelante le daremos formato al reporte. Por mientras lo dejaremos tal cuál como se agrego. Posteriormente insertamos a nuestro formulario un CrystalReportViewer, al cuál yo le puse de nombre crv1; este control será por el cuál mostraremos nuestro reporte o archivo .rpt


Es importante mencionar que ya contamos con el DataSet que queremos imprimir. Recordando que dentro de este contamos con diferentes DataTables identificados por un índice o nombre.

public static DataSet ds1 = new DataSet();

Durante el desarrollo de la aplicación lleno mi DataSet con una consulta SQL.

Ahora veremos el código que utilicé para enviar a imprimir un DataSet generado dinámico.

/*Yo lo puse dentro del evento Page_Load*/
protected void Page_Load(object sender, EventArgs e)
{
/*Construimos un DataSet y un DataTable para ser enviados como origen de datos a Crystal Reports. El DataTable lo indentificaremos con un nombre especifico*/

DataSet myDS = new DataSet();

DataTable myDT = new DataTable("dataset");


/*Mezclamos el DataTable que acabamos de crear con el DataTable que proviene de nuestro DataSet donde esta el resultado de una consulta SQL. Para esto utilizamos el método Merge*/


myDT.Merge(ds1.Tables[0]);

/*Agregamos el nuevo DataTable al DataSet que será el origen de datos de Crystal Reports
*/
myDS.Tables.Add(myDT);


/*Ahora creamos un archivo XML que contendrá nuestro DataSet. En teoría, este será escrito temporalmente en este archivo, que a su vez se convertirá en el origen de datos en el Reporte de Crystal Reports. Cabe mencionar que es muy importante que se tengan los permisos necesarios en la carpeta*/
myDS.WriteXml(@"C:\Inetpub\wwwroot\proyecto\xml\report.xml");

/*Ahora cargamos el archivo .rpt De igual manera hay que considerar los permisos necesarios*/

CrystalDecisions.CrystalReports.Engine.ReportDocument myrpt;

myrpt = new CrystalDecisions.CrystalReports.Engine.ReportDocument();

myrpt.Load(@"C:\Inetpub\wwwroot\proyecto\rpts\CrystalReport.rpt");


/*Establecemos como Origen de Datos el DataSet que llenamos */

myrpt.Database.Tables["preview"].SetDataSource(myDS);


/*Llenamos el CrystalReportViewer con la información*/
crv1.ReportSource = myrpt; crv1.DataBind();
}

Ahora… aun no funciona como debería ser. Es turno de trabajar con el reporte CrystalReport.rpt y prepararlo para que muestre la información como debería de ser. En este archivo tendremos que configurar en el Explorador de Campos el origen con un DataSet creado en un archivo xml.

Aquí es muy importante considerar que en el DataSet, el DataTable y los campos deben de llamarse igual que a los del resultado de la consulta SQL. A continuación creamos el archivo report.xml


Nótese el nombre del campo después de “NewDataSet”, ”preview” es como se llama nuestro DataTable.

Una vez tengamos creada esta “Base de Datos Temporal”, nos ubicaremos en el CrystalReport.rpt y utilizaremos el Explorador de Campos para dar de alta nuestro DataSet del XML.


Sobre la opción Campos de Base de Datos, daremos clic derecho y elegiremos Asistente de Base de Datos. En la ventana nueva, abriremos la carpeta Datos del Proyecto y Objetos .NET; será entonces donde podremos elegir en Ruta del Archivo el XML que creamos anteriormente.


Ya que tengamos cargado el DataSet, lo pasaremos por completo a la lista de Tablas Seleccionadas. De esta manera habremos determinado como Origen de Datos nuestro DataSet, con un DataTable llamado “preview” y con sus campos; los cuáles podremos pasar manualmente a nuestro CrystalReport .rpt



A estos campos podremos darle el formato que deseemos, la ubicación en el reporte, etc. Si todo salió bien, al momento en que probamos nuestra aplicación, el DataSet en el XML será llenado y el reporte lo podrá visualizar desglosando el listado de registros.

Cualquier duda ya saben donde encontrarme.

4 comentarios:

Laura dijo...

Buenas tardes Mauricio, muy interesante tu tema, mira yo quiero generar un reporte dinámico pero las columnas me van a variar de acuerdo a la selección que se haya realizado previamente no siempre tendré las mismas columnas. Motivo por el cual mi xml cambiaria, entonces mi pregunta surge ¿Como hago para diseñar mi reporte ya que tendría que arrastrar desde el explorador de campos los campos que contiene el XML, pero no entiendo cómo se me genera el reporte sino siempre van hacer las mismas columnas?
Laura

Mauricio Moo Aguilar (Dr. Omm) dijo...

Saludos Laura. Lamentablemente conseguir eso que mencionas es algo complicado que aun no he podido conseguir. De forma muy fija se me ocurre algo como preparar de antemano una serie de reportes con las columnas ya preparadas, pero eso depende directamente de la cantidad de variantes que pueden haber.

En lo personal, si tuviera la oportunidad, optaría por usar otro reporteador o incluso algún exportador a PDF que fuera mas sencillo de manejar dinamicamente hablabando.

Anónimo dijo...

Hola Mauricio, tengo un pequeño problema y pense que tu me puedes ayudar, necesito crear un sitio web asp el cual me cargue un reporte generado con crystal report XI. Y luego desde us sistema hacer el llamado al visual para que imprima el reporte.lo que me interesa es la parte de visual..podrias ayudarme o si sabes de algun blog que tenga información al respecto te lo agradecería..trabajo con visual Studio 2008 y SQL

Mauricio Moo Aguilar (Dr. Omm) dijo...

Saludos... no me quedo muy claro cuando te refieres a la parte del visual. Creo entender que será una aplicación en Windows Forms que obtenga el rpt para poder imprimirlo. Buscando un poco, encontre un ejemplo que tal vez te pueda servir, utilizando la propiedad ReportSource de un CrystalReportViewer. Espero sea útil.

http://msdn.microsoft.com/es-es/library/aa288187(v=vs.71).aspx