Beruflich Dokumente
Kultur Dokumente
Hola, si trabajas con Crystal Reports seguro te has encontrado con el problema de agregar una imagen de
forma dinámica. Si es así a continuación te mostraré una forma sencilla de agregar una
imagen dinámicamente (en tiempo de ejecución) en un reporte de Crystal Reports utilizando C#
Básicamente la estrategia consiste en agregar un placeholder para la imagen, pasar la ruta donde esta
nuestra imagen como un parámetro al reporte y por ultimo decirle a la imagen que utilice el parámetro
como fuente para la imagen.. Manos a la obra.
1.- Agregar una imagen al reporte, en la posición y el tamaño que deseamos (nos pedirá que imagen
deseamos agregar, es recomendable agregar una imagen de ejemplo similar a la que modificaremos en
tiempo de ejecución, si no cualquier imagen servirá).
2.- Después de ubicar la imagen y ajustarla a las dimensiones que deseamos, creamos un nuevo parámetro
que llamaremos picturePath (aquí hay un post anterior sobre como hacerlo).
3.- Lo siguiente es decirle al objeto imagen que agregamos que el parámetro picturePath es de donde
tomara la imagen.
Botón derecho sobre la imagen, seleccionar Format Object, en la nueva pantalla que
aparece seleccionar la pestaña Picture. En Graphic Location presionamos el botón de
Fórmula (X-2), en el editor de fórmulas agregamos {?picturePath} y presionamos Save
and Close.
Y estamos listos, ahora en código solo es cuestión de localizar o crear en tiempo de ejecución la imagen
que deseamos agregar al reporte y pasar la ubicación como parámetro.
1// ...
3 rpt.SetParameterValue("picturePath", path);
4/// ...
Paso 1: Se inserta Objeto Picture1
Primero que nada se inserta el objeto Picture1 en Crystal:
Paso 2: Creamos un Parametro tipo string que nos permitirá enviar la ruta de la imagen a nuestro reporte:
Nombramos nuestro parametro: RutaImagen
Paso 3: Ahora entramos a las propiedades de nuestro Picture1 del Reporte de CrystalReports en la opcion
Format Object:
Una vez en la ventana de propiedades nos vamos a la pestaña Imagen, y de ahy nos vamos a la opcion de:
Ubicacion del: Como se muestra en la imagen, dentro le predeterminamos el parametro que creamos para
enviar la ruta de la imagen: {?RutaImagen} , le damos guardar y cerrar, y aceptar.
En esta oportunidad se profundizara el trabajo de imágenes pero apuntando a Reportes, concretamente con
el uso de Crystal Reports.
En el anterior se listaba y editaba los datos del empleado, incluida sus fotografías, en cambio en este
artículo se vera como listar en un reporte esta misma información.
Se analizara además como incluir las imágenes provenientes de una base de datos, y también un logo
tomado de un archivo de imagen.
Capa de Reportes
Esto quizás aplique un poco mejor con una arquitectura en capas, pero en este caso aunque no las haya
definido del todo, se puede separa en un proyecto concreto la responsabilidad de crear los reportes.
Es por eso que se observara en la solución un proyecto de nombre ReportsLayer, este será el encargado de:
- Definición y estructura de datos que requieres el reporte, en este caso implementada en dataset tipados
- La carga de la información, conectándose para ello directamente a los datos, esta capa no hará uso del
DataAccess, porque al usar dataset la carga de datos se torna particular, por lo tanto su funcionalidad
requiere una conexión directa.
La idea con esto es separar funcionalidad y además cubrir un defecto que
tiene Crystal Reports, en donde el diseñador solo toma como entidades
objetos que estén local al proyecto donde se encuentra el rpt. Muchas
veces poner en la Presentación un reporte implicaría además poner allí
mismo los dataset tipados, lo cual ensucia el modelo.
Para al carga de los empleados se hará uso de la funcionalidad de la clase EmpleadosDAL definida dentro
del propio proyecto de Reportes.
Un punto adicional es la carga de una imagen externa que representa el logo de la empresa, el mismo no se
encuentra en la db sino que es un archivo, es por eso que luego de cargar el reporte se observan las líneas:
?
1Empleados.EmpresaRow row = empleado.Empresa.NewEmpresaRow();
2row.Logo = ImageHelper.ImageToByteArray(ImageHelper.ObtenerImagenLogoEmpresa());
3empleado.Empresa.Rows.Add(row);
encargadas justamente de crear una row en al datatable con la imagen del logo. En este caso se hace uso de
la funcionalidad del Helper de Imágenes creado para tomar la imagen embebida como recurso.
Esta cada de reportes solo debería ser accedida por medio de la clase Reports con su metodo
ObtenerReporteEmpleados() este devolverá la instancia del reporte con la información asignada lista para
ser mostrada en pantalla, o exportada si es necesario.
?
1 public static class Reports
2 {
3
public static ReporteEmpleados ObtenerReporteEmpleados()
4 {
5 ReporteEmpleados report = new ReporteEmpleados();
6
7 //
8 // Se obtienen los datos de la lista de empleados
9 //
10 Empleados empleado = EmpleadosDAL.ObtenerTodos();
11
//
12 // Se agrega el logo de la empresa a la informacion del listado
13 //
14 Empleados.EmpresaRow row = empleado.Empresa.NewEmpresaRow();
15 row.Logo =
ImageHelper.ImageToByteArray(ImageHelper.ObtenerImagenLogoEmpresa());
16 empleado.Empresa.Rows.Add(row);
17
18 //
19 // Se asigna los datos a la instancia del reporte
20 //
21 report.SetDataSource(empleado);
22
return report;
23 }
24
25 }
26
27
28
El ultimo punto por tratar es como se usara lo anteriormente explicado desde la presentación.
Por un lado contamos con un formulario especialmente creado para desplegar el reporte, el mismo solo
cuanta con el CrystalReportViewer y recibe por parámetro la instancia del reporte que debe mostrar.
?
1
2 public partial class Reporte : Form
3 {
4 private ReportClass _report = null;
5
6 public Reporte()
7 {
InitializeComponent();
8 }
9
10 public Reporte(ReportClass report)
11 :this()
12 {
_report = report;
13 }
14
15 private void Reporte_Load(object sender, EventArgs e)
16 {
17 crystalReportViewer1.ReportSource = _report;
18 }
}
19
20
Se define un nuevo constructor del formulario para pasar la instancia del reporte al formulario y es en el
Load del mismo que se asigna al Viewer, para desplegar el reporte en pantalla.
Por otro lado tenemos un botón en la pantalla de ListaEmpleados, el cual recupera el reporte, con los datos
asignados, y se la pasa a la instancia del formulario para que la muestre en pantalla.
?
1private void btnListar_Click(object sender, EventArgs e)
2{
3
4 ReporteEmpleados report = Reports.ObtenerReporteEmpleados();
5
6 Reporte frmReporte = new Reporte(report);
7 frmReporte.Show();
8
}
9
Código de ejemplo
La base de datos utilizada en el ejemplo es la Sql Server Express 2008 R2, como ver en la solución el mdf
esta integrado al Visual Studio, por lo tanto con solo tener el sql server express instado esta debería
funciona adjuntándose sola al servicio.
En la carpeta “script” del proyecto “DataAccess” se encuentra un archivo .sql con las instrucciones para
crear la estructura de tablas y datos que se requieren para este articulo.
Esta es la Solución a Imagenes Dínamicas en los reportes solo guardando la Ruta de la Foto en un campo en la Base
de Datos, explicare detalladamente como lo realize:
-Diseñé una Base de Datos sencilla en Access con una tabla que contiene los siguientes campos: Cedula, Apellidos,
Nombres y un campo Ruta donde almaceno la ruta donde se encuentra el archivo de imagen, por ejemplo en este
campo se guardaria algo como esto C:\MiFoto.jpg sin incluir dobles comillas ni al principio ni al final.
-Luego diseñé un reporte dentro de Visual Basic usando una conexion Ado con el Asistente de Informes de Crystal
Report y este reporte lo muestra al ejecutar el programa un CrViewer, el reporte posee 5 secciones de la siguiente
manera:
-En la Sección 3 agrege los campos Cedula, Apellidos, Nombres, Ruta y LO MÁS IMPORTANTE inserte manualmente
una imagen en esta sección al lado del campo ruta dandole un tamaño apropiado porque si se inserta una imagen
muy grande el reporte tendra mal aspecto, esta imagen es un Objeto ICROleObject y por defecto Visual Basic le
asigna como nombre Imagen1 ya que es la primera imagen en este reporte.
-Finalmente solo necesite de 3 Líneas de Programación para que esta imagen varie segun lo que tiene el campo
Ruta, prestar mucha atención a lo siguiente: le di Doble click a la Sección 3 del Repote y allí agregre este código:
Si te has preguntado la manera de pasar un valor, o variable a un reporte de Crystal Reports, sin la
necesidad de crear una columna en la Base de Datos, pues que no tendría sentido hacerlo para un solo
valor.
La forma de hacerlo es:
Listo, ahora ya tenemos el elemento ParametroEjemplo disponible para arrastrarlo y acomodarlo dentro del
reporte.
En caso de que estemos agregando el Reporte al CrystalReportViewer desde código, tenemos que poner
el código de paso de parámetros antes de asignar el ReportSource.
Espero les sea de utilidad el post, y como siempre, se agradecerán todos los comentarios.
13 Votes
Pues bien, veamos cuales son los pasos básicos para generar nuestro primer reporte de Crystal Reports.
Para este ejemplos los datos a utilizar en el reporte son escritos manualmente, pero la idea es solo poner
datos en la tabla, para una aplicación mas real, no importa si los datos lo obtienes de capturas de usuario o
de alguna base de datos. En la segunda versión de este tutorial, profundizaremos un poco mas en esos
aspectos.
Lo primero que debemos hacer es agregar a nuestro proyecto un DATASET con el nombre de Datos.
Agreguemos nuevamente un nuevo elemento a nuestro proyecto, pero esta vez será un CrystalReport, y
demosle el nombre de Reporte (haciendo un alarde de originalidad en el nombre :D)
Nos aparecerá un pequeño menu, seleccionemos OK, y en la siguiente ventana presionemos Finish. Esto
debido a que no queremos ayuda para elegir los datos a mostrar. Para fines educativos, lo haremos “Como
los hombres” (manualmente).
Ahora estamos en el “Diseñador de Reportes”, en la parte izq, presionamos botón derecho sobre Database
Fields y seleccionamos Database Expert…
Del nuevo menu, expandemos Project Data >> ADO.NET DataSets y seleccionamos nuestra Tabla y la
agregamos a la lista de Selectes Tables, para esto presionamos el botón con el simbolo “>“.
Al final tendremos algo
asi:
Presionamos OK. Ahora bajo DataBase Fields podremos ver las columnas que creamos para nuestra Tabla.
Ahora solo tenemos que arrastrar cada una de las columnas hacia la Sección 3 (Details) que para fines
prácticos, es donde se mostrará el cuerpo de nuestro reporte.
Pasemos al Código.
5 VerReporte VER;
6
13
// Inicializar el visor de reportes y mandarle la tabla con los datos
14
VER = new VerReporte(DS.Tabla);
15
VER.ShowDialog();
16
Finalmente, modificamos el codigo del constructor de la forma VerReporte para que se vea de la siguiente
manera:
1
public VerReporte(DataTable DT)
2
{
3 InitializeComponent();
4
9 RP.SetDataSource(DT);
10
//Asignar reporte creado al visor de reportes
11
this.crystalReportViewer1.ReportSource = RP;
12
}
13
Por fin, ya todo esta listo para ejecutar nuestro código, presionar el botón y ver nuestro reporte de
Crystal Reports.
Pasar Parametros a Crystal Report
Algunas veces en nuestra aplicación de escritorio hay que pasar información(parametros) directamente desde el
formulario(VB o C#) hasta nuestro reporte, información que pueden variar en cada presentación de reporte y que
el usuario debe especificar como por ejemplo el autor del reporte o simplemente notas especificas para cada
reporte y que no se pueden obtener desde la base datos o con alguna formula elaborada, por eso muestro como
pasar parametros desde el Windows Form hacia el Crystal Report.
Lo primero va ser crear el reporte, en caso no puedan hacerlo o quieran dar una revisada aquí hay un link en que
muestro como hacerlo reporte !!!
Ahora, el ejemplo va para Visual Basic, mas abajo lo muestro para C# y lo primero que debemos hacer es ir a
nuestro reporte y declarar un campo parametro del tipo Parameter Field desde el Field Explorer
Luego especificamos el nombre y tipo del parametro a enviar y luego le damos aceptar con lo que tendremos
disponible el campo para colocarlo en cualquier parte del informe, en mi caso llame al parametro ejemplo y lo
coloque en el pie del reporte:
da.Fill(ds, "empleado")
rpt.SetDataSource(ds)
CrystalReportViewer1.ReportSource = rpt
End Using
End Using
End Sub
End Class
Pero en caso quieras mandar un valor dentro de una variable, por ejemplo que capture la info desde un textbox
para ser mostrado en el informe, haz esto:
rpt.SetParameterValue("ejemplo", variable)
using System.Data.SqlClient;
using System.Configuration;
namespace WindowsFormsApplication1
SqlConnection sql;
SqlDataAdapter da;
string conexion =
ConfigurationManager.ConnectionStrings["pruebaConnectionString"].ConnectionString;
public Form1()
InitializeComponent();
da.Fill(ds, "empleado");
rpt.SetDataSource(ds);
this.crystalReportViewer1.ReportSource = rpt;
this.ShowDialog();