Sie sind auf Seite 1von 21

Pasar una imagen a Crystal Reports

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á).

Botón derecho -> Insert -> Picture

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// ...

2string path = @"c:\dinPictures\pic1.png";

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.

Posteriormente enviamos el Parametro al nuestro reporte de Crystal desde nuestra aplicacion:

Dim RutaImagen As String


RutaImagen = "C:\ImagenEmpresa\Logotipo.png"

Dim objRpt As New rptReporteEmpresa


objRpt.SetDatabaseLogon(UserSQL, Pass)
objRpt.SetParameterValue("Leyenda", Leyenda)
objRpt.SetParameterValue("RutaImagen", RutaImagen.ToString)
frmReporte.CrystalReportViewer.ReportSource = objRpt
objRpt.RecordSelectionFormula = ("{Empresa.ID} =" & lblId.Text)
frmReporte.CrystalReportViewer.ReportSource = objRpt
frmReporte.CrystalReportViewer.Refresh()
frmReporte.Show()
Crystal Reports – Cargar imagen usando una capa de reportes

En esta oportunidad se profundizara el trabajo de imágenes pero apuntando a Reportes, concretamente con
el uso de Crystal Reports.

Para este artículo se continua con el ejemplo de uno previo:

[WinForms] Edición Empleados – Grabar imagen en base de datos

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.

El resultado del reporte final del reporte seria:

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:

- Encapsular la diseño del reporte

- 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.

Definición y carga de datos en el DataSet

Para este reporte se definió un dataset tipado con dos datatable en su


interior.

Para al carga de los empleados se hará uso de la funcionalidad de la clase EmpleadosDAL definida dentro
del propio proyecto de Reportes.

1 internal static class EmpleadosDAL


2 {
3
internal static Empleados ObtenerTodos()
4 {
5 Empleados empleados = new Empleados();
6
7 using (SqlConnection conn = new
8 SqlConnection(ConfigurationManager.ConnectionStrings["default"].ToString()))
{
9 conn.Open();
10
11 string query = @"SELECT IdEmpleado, Nombre, Apellido,
12 FechaNacimiento, EstadoCivil, Imagen
13 FROM Empleados";
14
15 SqlCommand cmd = new SqlCommand(query, conn);
16
SqlDataAdapter da = new SqlDataAdapter(cmd);
17 //es necesario indicar la tabla del dataset que se quiere cargar
18 da.Fill(empleados, "Empleados");
19
20 }
21
22 return empleados;
}
23 }
24
25
Allí se define la consulta en donde las columnas coinciden en nombre con los definidos en timepo de diseño
en el dataset tipado, además vale aclarar que la clase ha sido declarada como internal de forma intencional,
para que solo la capa de Reportes pueda usar esta funcionalidad, es mas la idea es que se limite al máximo
el acceso a funcionalidad que solo esta clase debería utilizar, por eso el dataset tipado también tiene el
modificador de acceso asignado a internal.

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.

Retorno del Reporte

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

Lanzar el Reporte en al Presentación

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:

Sección 1: Encabezado del Informe.


Sección 2: Encabezado de página.
Sección 3: Detalles.
Sección 4: Pie del Informe.
Sección 5: Pie de Página.

-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:

Private Sub Sección3_Format(ByVal pFormattingInfo As Object)


Dim Archivo As StdPicture
Set Archivo = LoadPicture(Campo4.Value) 'Campo4 es el campo Ruta
Set Imagen1.FormattedPicture = Archivo
End Sub

Y en el formulario que muestra el Reporte con el CrViewer lo siguiente:

Dim Report As New CrystalReport1'CrystalReport1 es el Reporte en Visual Basic

Private Sub Form_Load()


Screen.MousePointer = vbHourglass
CRViewer1.ReportSource = Report
CRViewer1.ViewReport
Screen.MousePointer = vbDefault
End Sub

Private Sub Form_Resize()


CRViewer1.Top = 0
CRViewer1.Left = 0
CRViewer1.Height = ScaleHeight
CRViewer1.Width = ScaleWidth
CRViewer1.Zoom (100)
End Sub
Ejecuta el formulario y listo!!!! Espero haber sido bastante explicito, no lo he probado aun pero me imagino que
funcionara igual si la Base de Datos esta en MySql, SqlServer u otra, utilizo Visual Basic 6.0 y Crystal Report 8.0, esto
hasta ahora habia sido un gran problema al cual no se le encontraba solución ni en Internet (eso lo digo porque vi
muchas preguntas acerca de esto en varios foros y quizas estoy equivocado pero no consegui respuestas) pero
gracias a DIOS ya esta solucionado, cualquier duda continuen escribiendo en esta nota que estare pendiente y si les
sirve o averiguan mejoras tambien escribanme por aqui o a mi correo indicado en el titular de la nota arriba.

Como Pasar Parametros/Variables a un Crystal Reports

Como pasar un Valor, parametro o variable a Crytal Reports


En esta ocasión compartiré con ustedes una manera fácil de pasar un valor, parámetro o variable a un
reporte de Reporte de Cyrstal Reports desde codigo de C# .net.

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:

Declarar un parámetro del tipo Parameter Field dentro de nuestro Reporte.


Para esto, en Field Explorer hacer clic derecho sobre Parameter Field y elegir New
Definir el Nombre y el tipo del parametro.

Para el ejemplo, Nombre: ParametroEjemplo, Tipo: String

Listo, ahora ya tenemos el elemento ParametroEjemplo disponible para arrastrarlo y acomodarlo dentro del
reporte.

Para pasar el valor/variable al Reporte de Crystal Reports desde código C#.


En caso de que estemos agregando el Reporte al CrystalReportViewer de manera automática, tenemos que
poner el código de paso de parámetros antes de llamar el 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.

El Código de paso de Parámetros

1 // Pasando una caneda/valor


2 rpt.SetParameterValue("ParametroEjemplo", "Hola Mundo");
// Pasando una variable
3 string var1 = "Hola Mundo";
4 rpt.SetParameterValue("ParametroEjemplo", var1);
5

Espero les sea de utilidad el post, y como siempre, se agradecerán todos los comentarios.
13 Votes

Pasos BASICOS para hacer tu PRIMER Crystal Report.

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.

 Después de agregar el nuevo elemento, automáticamente seremos direccionados al “editor” de Datasets,


de la parte izq arrastramos una DataTable y le cambiamos el nombre a Tabla.
 Posteriormente presionamos botón derecho sobre la tabla y seleccionamos Add >> Column. Agregamos 3
columas de tal forma que nuestra tabla quede asi:
Pues bien, ya tenemos nuestro Dataset y nuestra tabla que tendrá los datos para nuestro reporte, ahora
crearemos el reporte.

 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.

 Agregamos a nuestro proyecto un nuevo Windows Forms y le damos el nombre de VerReporte


 Al nuevo VerReporte le agregamos un componente CrystalReportViewier

Pasemos al Código.

 Agregamos el botón desde el cual generaremos nuestro reporte.


 En el evento del botón (doble clic sobre el nuevo botón) agregaremos el siguiente codigo

1 // Crear Objeto de Dataset


2
Datos DS = new Datos();
3

4 // Crear Objeto del visor de reportes

5 VerReporte VER;
6

7 //Agregar Datos a la(s) tabla(s) que nos interesa(n) del dataset

9 // En este caso llenare datos manualmente (SOLO PARA EJEMPLIFICAR)

10 DS.Tabla.Rows.Add("Sergio", "sergio@example.com", "123 44 55");


11 DS.Tabla.Rows.Add("Alberto", "Alberto@example.com", "123 44 55");

12 DS.Tabla.Rows.Add("Inzunza", "Inznuza@example.com", "123 44 55");

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

5 //Crear Objeto REPORTE

6 Reporte RP = new Reporte();

8 //Asignar datos al reporte

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:

y luego desde el Windows Form en VB ponemos este código:


Imports System.Data
Imports System.Data.SqlClient

Public Class Form1

Dim ds As New datos <---- a="a" crea="crea" dataset="dataset" el="el" font="font"


informe="informe" instancia="instancia" llenar="llenar" para="para" que="que" se="se">

Dim rpt As New reporte <---- a="a" crystal="crystal" el="el" instancia="instancia"


report="report" span="span">

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

Using Sql As New SqlConnection(My.Settings.pruebaConnectionString)

Using da As New SqlDataAdapter("select * from empleado", Sql)

da.Fill(ds, "empleado")

rpt.SetDataSource(ds)

rpt.SetParameterValue("ejemplo", "Hola Mundo")

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:

Dim variable As String = "lo que quieras"

rpt.SetParameterValue("ejemplo", variable)

pero si lo quieren en C#, aqui esta:

using System.Data.SqlClient;
using System.Configuration;

namespace WindowsFormsApplication1

public partial class Form1 : Form

SqlConnection sql;
SqlDataAdapter da;

reporte rpt = new reporte();

datos ds = new datos();

string conexion =
ConfigurationManager.ConnectionStrings["pruebaConnectionString"].ConnectionString;

public Form1()

InitializeComponent();

private void Form1_Load(object sender, EventArgs e)

using (sql = new SqlConnection(conexion)) {

using (da = new SqlDataAdapter("select * from empleado", sql)) {

da.Fill(ds, "empleado");

rpt.SetDataSource(ds);

rpt.SetParameterValue("ejemplo", "Hola mundo");

this.crystalReportViewer1.ReportSource = rpt;

this.ShowDialog();

y de nuevo las lineas para pasar el valor de una variable al reporte:

string variable = "Hola mundo";


rpt.SetParameterValue("ejemplo", variable);

Das könnte Ihnen auch gefallen