lunes, 30 de marzo de 2009

Creación de Reportes con JasperRepots y iReports - Parte 3: Parámetros y Variables

En el tutorial anterior vimos como hacer uso de los Fields para indicar la posición dentro de nuestro reporte en la que deben quedar los valores que obtenemos de nuestra aplicación Java.

Ahora hablaré de los otros dos tipos de expresiones que proporciona JasperReports: Parameters y Variables. Y la forma en la que podemos usarlos para hacer más dinámicos nuestros reportes.

Para ello seguiremos usando el ejemplo del segundo tutorial , así que si no lo han leído les recomiendo que lo hagan en esta página.

Abrimos iReport y el reporte del tutorial anterior ("reporte2.jrxml"). En este momento nuestro reporte debe verse como en la siguiente imagen:



En donde solo tenemos textos estáticos y "fields" para mostrar un reporte básico de los datos de ciertos participantes. Si lo recuerdan, la salida del reporte al generarlo desde nuestra aplicación Java, era la siguiente:



Ahora pasaremos a agregar "Parameters" a este reporte. Como dije en el tutorial anterior: los parámetros son valores que usualmente se pasan al reporte desde el programa que crea el "JasperPrint" del reporte (nuestra aplicación Java) haciendo uso de un "java.util.Map".

En este caso pasaremos dos parámetros: el título del reporte, y el nombre del autor del mismo.

Al igual que con los Fields, para poder hacer uso de un parámetro primero hay que declararlo en el "Report Inspector" (situado en el panel izquierdo del iReport), por lo que nos dirigimos a esta ventana y hacemos clic derecho sobre el nodo "Parameters". Al hacer esto se abrirá un menú contextual. Seleccionamos la opción "Add Parameter" (la única habilitada).



Con esto se agregará un nuevo parámetro llamado "parameter1" de tipo "java.lang.String". Cambiamos en nombre del parámetro en la ventana de propiedades a "titulo" (recuerden que este nombre es el que deberemos usar desde nuestra aplicación Java para establecer el valor del parámetro).



Agregamos otro parámetro llamado "autor" de la misma forma que agregamos el de "titulo".



Ahora eliminamos el elemento que teníamos como título del reporte (el que contiene el texto estático "Reporte de Participantes") y lo reemplazamos por el parámetro "titulo" arrastrándolo desde la ventana del "Report Inspector" a la banda "Title".



Ajustamos este elemento para que tenga el mismo formato que el título que teníamos anteriormente.

Ahora agregamos el segundo parámetro ("autor") en la banda "Page Header", la cual se repite en la parte superior de cada una de las páginas (en la primer página aparece después del título), arrastrándolo a esta banda.



Si dejamos esta expresión tal y como está ("$P{autor}") solo se mostrará en nombre del autor en la parte superior de cada una de las páginas (por ejemplo si el autor del reporte es "Juan", solo veremos la palabra "Juan" en la parte superior de los reportes). Esto podría no ser claro para quienes revisen este reporte, por lo que queremos indicar de forma explícita que a lo que se refiere el valor de este parámetro es el nombre del autor. Para hacer esto nos dirigimos a la ventana de propiedades de este parámetro (para lo cual debemos tenerlo seleccionado) y buscamos la categoría "Text field properties". Ahi se encuentra una propiedad llamada "Text Field Expression" cuyo valor es "$P{autor}".



Lo que haremos es editar esta expresión para anteponer la palabra "Autor: ". Para hacer esto presionamos el botón "...", con lo que se abrirá una ventana que nos permitirá editar la expresión. En esta ventana modificamos la expresión "$P{autor}" para que quede "Autor: " + $P{autor}. Con esto lo que logramos es que a la cadena estática "Autor: " se le concatene el valor de la expresión dinámica "$P{autor}". Por lo que ahora el lo que aparecerá en la parte superior de cada página del reporte será la cadena "Autor: Juan".



Ahora presionamos el botón "Compile Report" para que se genere el reporte compilado "reporte2.jasper".

Veamos una vista previa del reporte, para esto hacemos clic en la pestaña "Preview". Nos pedirá los valores de los dos parámetros. Si colocamos para el parámetro "titulo" el valor "Reporte" y para el parámetro "autor" el valor "Alex" el preview que veremos será el siguiente:



Ahora veremos cómo pasarle estos valores desde nuestra aplicación Java, por lo que abrimos nuestro IDE de trabajo, NetBeans.

Ahí nos dirigimos a la clase "Main" que creamos la última vez y buscamos la línea en donde creamos nuestro objeto "JasperPrint":


JasperPrint jasperPrint = JasperFillManager.fillReport(reporte, null, new JRBeanCollectionDataSource(listaPariticipantes));


Y antes de esta línea crearemos un objeto "java.util.Map" que contendrá nuestros parámetros. Colocaremos el nombre de los parámetros (en este caso "autor" y "titulo") como llave y sus respectivos valores, "Juan" para el autor y "Reporte Participantes" para el título, como valores.


Map<String, String> parametros = new HashMap<String, String>();
parametros.put("autor", "Juan");
parametros.put("titulo", "Reporte Participantes");


Y pasamos este "Map" como el segundo parámetro del método "fillReport", al que hasta ahora le hemos pasado "null":


JasperPrint jasperPrint = JasperFillManager.fillReport(reporte, parametros, new JRBeanCollectionDataSource(listaPariticipantes));


El código de nuestro método "main" queda así:


public static void main(String[] args) throws Exception
{
    List<Participante> listaPariticipantes = new ArrayList<Participante>();
    
    for (int i = 1; i <= 10; i++)
    {
        Participante p = new Participante(i, "Particpante " + i, "Usuario " + i, "Pass " + i, "Comentarios para " + i);
        listaPariticipantes.add(p);
    }

    JasperReport reporte = (JasperReport) JRLoader.loadObject("reporte2.jasper");

    Map<String, String> parametros = new HashMap<String, String>();
    parametros.put("autor", "Juan");
    parametros.put("titulo", "Reporte Participantes");

    JasperPrint jasperPrint = JasperFillManager.fillReport(reporte, parametros, new JRBeanCollectionDataSource(listaPariticipantes));

    JRExporter exporter = new JRPdfExporter();
    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
    exporter.setParameter(JRExporterParameter.OUTPUT_FILE, new java.io.File("reporte3PDF.pdf"));
    exporter.exportReport();
}


Si ejecutamos nuestro reporte obtendremos un archivo con el siguiente contenido:



Como podemos ver los parámetros "titulo" y "autor" han sido reemplazados por los valores "Reporte Participantes" y "Juan" respectivamente.

Gracias a los parámetros podemos pasar valores (como en este caso cadenas, pero podemos pasar prácticamente cualquier tipo de objeto) a nuestro reporte directamente desde nuestra aplicación Java.

Ahora veremos el último tipo de expresión que JasperReports nos proporciona, las Variables.

Como dije en el post anterior: las variables son objetos usados para almacenar valores como los resultados de cálculos.

En este caso usaremos dos variables. La primera será una de las variables internas que ya proporciona JasperReports: PAGE_NUMBER, que nos dice el número de la página actual. En este caso como el reporte solo tendrá una página solo aparecerá el número 1, pero pueden extender el ejemplo para que se generen más páginas.

La segunda variable que usaremos será una variable creada por nosotros mismos y nos mostrará la suma de los puntos de los Participantes (en este momento los Participantes no tienen puntos, por lo que tendremos que agregarlos).

Lo primero que haremos es modificar la clase "Participante" agregando el atributo "puntos" de tipo "int" con sus correspondientes setters y getters:


private int puntos;

public int getPuntos()
{
    return puntos;
}

public void setPuntos(int puntos)
{
    this.puntos = puntos;
}


y en nuestro método "main" agregamos, en el ciclo que crea los objetos "Participante", el siguiente código para establecer los puntos de cada uno de los Participantes:


p.setPuntos(i);


Ahora regresamos a iReport y agregamos un nuevo Field en la ventana "Report Inspector" llamado "puntos" de tipo "java.lang.Integer". Este field será usado para mostrar los puntos que tiene cada uno de los Participantes.



Agregamos una columna, dentro de la banda "Details 1", para mostrar este field:



Si compilamos nuestro reporte y ejecutamos nuestra aplicación Java debemos ver un reporte con el siguiente contenido:



Ahora agregaremos la variable que realizará la suma de los puntos de todos los Participantes. Para esto agregamos una nueva variable en el nodo "Variables" de la ventana "Report Inspector" haciendo clic derecho sobre este nodo y seleccionando la opción "Add Variable" del menú contextual que se abre.



Modificamos sus propiedades en la ventana "Properties" cambiando su nombre a "sumaPuntos", su "Variable Class" a "java.lang.Integer", y "Calculation" a "Sum" (con esto indicamos que la variable mantendrá la suma de los valores que indicaremos más adelante, otras opciones incluyen un contador, el promedio, el valor más alto, etc.).

Ahora indicaremos la suma de cuáles valores son los que queremos que se almacene en este variable. Para eso hacemos clic en el botón "..." de la propiedad "Variable Expression", con lo que se abrirá una nueva ventana. Es esta nueva ventana indicaremos de dónde se tomarán los valores para la suma. Podemos usar una expresión tan compleja como necesitemos. Como en este caso solo queremos realizar la suma de los puntos escribimos "F{puntos}". Y presionamos el botón "OK" para confirmar.



Al final las propiedades de nuestra variable deben quedar así:



Ahora solo arrastramos nuestra variable "sumaPuntos" desde el "Report Inspector" hasta la banda "Summary". Esta banda se muestra cuando ya se han mostrado todos los datos de la banda "Details 1" y se muestra justo abajo de ella.

Agregaré un texto estático y una línea en esta banda solo para que se vea un poco mejor. Nuestro reporte hasta ahora debe verse así:



Ahora para terminar agregaremos la variable "PAGE_NUMBER" que nos dice el número de página actual en el reporte. Arrastramos esta variable desde el "Report Inspector" hasta la banda "Page Footer", la cual se muestra en la parte inferior de cada página.

Podría parecer un poco extraño que la banda "Summary" que se encuentra abajo de la banda "Page Footer" en el designer vaya a aparecer antes en el reporte final, pero confíen en mi, así será ^_^.

Agregaré también un texto estático solo para indicar que el valor que estamos mostrando corresponde al número de página. Al final el reporte queda así:



Ahora guardamos y compilamos nuestro reporte y ejecutamos nuestra aplicación desde el NetBeans. El reporte generado debe verse así:



Como podemos ver, la variable "sumaPuntos" contiene la suma de los puntos de todos los participantes (55).

Nuestra clase "Participante" queda de la siguiente forma:


public class Participante
{
    private int id;
    private String nombre;
    private String username;
    private String password;
    private String comentarios;
    private int puntos;
    

    public Participante()
    {
    }
    
    public Participante(int id, String nombre, String username, String password, String comentarios)
    {
        this.id = id;
        this.nombre = nombre;
        this.username = username;
        this.password = password;
        this.comentarios = comentarios;
    }

    public String getComentarios()
    {
        return comentarios;
    }

    public void setComentarios(String comentarios)
    {
        this.comentarios = comentarios;
    }

    public int getId()
    {
        return id;
    }

    public void setId(int id)
    {
        this.id = id;
    }

    public String getNombre()
    {
        return nombre;
    }

    public void setNombre(String nombre)
    {
        this.nombre = nombre;
    }

    public String getPassword()
    {
        return password;
    }

    public void setPassword(String password)
    {
        this.password = password;
    }

    public String getUsername()
    {
        return username;
    }

    public void setUsername(String username)
    {
        this.username = username;
    }
    
    public int getPuntos()
    {
        return puntos;
    }

    public void setPuntos(int puntos)
    {
        this.puntos = puntos;
    }
}


y nuestra clase "Main" de la siguiente forma (omitiendo los imports):


public class Main
{
    public static void main(String[] args) throws Exception
    {
        List<Participante> listaPariticipantes = new ArrayList<Participante>();
        for (int i = 1; i <= 10; i++)
        {
            Participante p = new Participante(i, "Particpante " + i, "Usuario " + i, "Pass " + i, "Comentarios para " + i);
            p.setPuntos(i);
            
            listaPariticipantes.add(p);
        }

        JasperReport reporte = (JasperReport) JRLoader.loadObject("reporte2.jasper");

        Map<String, String> parametros = new HashMap<String, String>();
        parametros.put("autor", "Juan");
        parametros.put("titulo", "Reporte Participantes");

        JasperPrint jasperPrint = JasperFillManager.fillReport(reporte, parametros, new JRBeanCollectionDataSource(listaPariticipantes));

        JRExporter exporter = new JRPdfExporter();
        exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
        exporter.setParameter(JRExporterParameter.OUTPUT_FILE, new java.io.File("reporte3PDF.pdf"));
        exporter.exportReport();
    }
}


Para terminar solo recuerden: los parámetros son expresiones que nos permiten pasar valores, desde nuestra aplicación Java, a los reportes generador por JasperReports. Y las variables almacenan valores que son el resultado de cálculos de distinta naturaleza sobre los valores que recibimos en nuestro reporte.

Bien, este es el final de este tercer tutorial sobre JasperReports. Espero que les sea de utilidad. No olviden dejar sus comentarios, dudas y sugerencias.

En el siguiente tutorial veremos cómo mostrar los reportes generados desde una aplicación web.

Saludos.

Descarga los archivos de este tutorial desde aquí:

Entradas Relacionadas:

82 comentarios:

  1. Muy buen tutorial, creo qe ma va a servir en el proyecto que recien comienzp, gracias.

    Espero el siguiente articulo

    ResponderEliminar
  2. hola saludos, oye en mi reporte yo manejo cantidades monetarias y estaba tratando de meterle el formato de moneda con una variable y con la clase java.text.Format pero ps me sale un error en iReport y en programita de java normal no, nose si tenga que ser con variables o con un scriptlet y si es con un scriptlet como lo puedo hacer¡??? muchas gracias

    PD. esta excelente el tutorial

    ResponderEliminar
  3. Una duda, si tengo un parametro como string, cual es la sintaxis para pasarlo a tipo date cuando lo llamo. Ya que cuando lo llamo en el query lo necesito tipo string, pero para el titulo del reporte como date.
    Graxias

    ResponderEliminar
  4. Hola Luna;

    Todo lo que quieras mostrar en los reportes debe ser una cadena. Lo que podrías hacer es, pasar el parámetro dos veces (una para usarlo en el query y otro para usarlo en el título) o pasar el objeto Date como parámetro y posteriormente usar (dependiendo de los formatos que uses en ambos casos) el método String.format para formatearlo como lo necesitas en cada lugar.


    http://www.j2ee.me/javase/6/docs/api/java/lang/String.html#format(java.lang.String,%20java.lang.Object...)

    Espero que esto te sirva, sino vemos cómo solucionarlo.

    Saludos

    ResponderEliminar
  5. Como funcionan los parametros List, o parametros Collection?????
    Se podrian enviar 3 parametros los cuales sean 3 listas?

    ResponderEliminar
  6. Hola Franklin, los parametros que son Collection (incluyendo List) funcionan como el resto de los parámetros, y, en teoría, si deberias poder pasar varios parámetros de este tipo.

    Saludos y perdona la demora en la contestación.

    ResponderEliminar
  7. Hola, muy buen manual =)

    Pero no sé como hacer algo.

    Mira quiero hacer que me aparezca un encabezado(por ejemplo profesor - materia) y que después en el Detail se desplieguen los datos que le envío de una List.

    Pero inmediatamente después de desplegar lo anterior quiero que aparezca otro encabezado(por ejemplo alumno - calificacion) y también que se desplieguen los datos que le envio de otra List.

    Mi problema es que no entiendo como poder hacerlo, ya que solo tengo una banda "ColumHeader" y una banda "Detail".

    Cómo podría hacerlo? Alguna idea? De antemano Gracias!

    ResponderEliminar
  8. Hola de nuevo, bueno, solo quería comentarte que ya pude hacer lo que quería. Pero, como que no estoy al 100% convencido de que le dí la mejor solución.

    Lo que hice fue hacer un subreporte por cada lista que quería que se mostrara en el reporte, pero quedaron "anidados" los subreportes. No sé si me compliqué la vida, me interesaría tu opinión. Te dejo lo que hice:

    http://rapidshare.com/files/269084334/07_Reporte_con_subreportes_anidados.rar

    Como ves? existe otra forma mas fácil? Porque de esta forma es un poco tedioso pasar los parámetros de reporte en reporte y se puede hacer un poco confuso.

    Saludos!

    ResponderEliminar
  9. Hola Raúl. Ejecute tu ejemplo pero lamentablemente el reporte me lo mostró vacio (tanto en la ventana que se abre como en el PDF generado) por alguna razón que no entiendo ya que aparentemente todo está bien.

    Sin embargo los reportes anidados si se ven algo estraños. Si entiendo bien lo que hace en este momento tu reporte es mostrar toda la lista de alumnos después, por cada alumno, te muestra toda la lista de profesores, y después por cada profesor te muestra toda la lista de materias cierto?

    Si entiendo bien lo que tu quieres es que se muestre la lista de alumnos, después los alumnos asociados con ese profesor y después tal vez la materia que da ese profesor a ese alumno o algo así?.

    Si este es el caso entoces deberás hacer tus objetos un poco más complejos (al alumno ponerle una lista de profesores o materias y asociar estos últimos).

    ¿Lo que quieres hacer es algo cómo esto?

    Saludos.

    ResponderEliminar
  10. Hola nuevamente!

    Que raro que te genere los reportes vacios :s Tal vez necesitas compilar nuevamente todo. Bueno, ahora te envío el PDF que a mi me genera, para que lo veas y me des tu opinión de como lo harías.

    Y, creo que cuando lo veas vas a entender que lo que quiero hacer. No quiero hacer lo que tu me escribiste, eso suena un poco mas complejo...

    Yo simplemente quiero meter 3 ó n listas en un reporte. Pero, si las meto todas en el mismo reporte en la banda de detail se van intercalando, osea que no es la solución. También probé en poner 3 subreportes (uno para cada lista) en el reporte Maestro, pero tampoco funcionó porque me encima las listas. Por eso recurrí a ocupar estos subreportes "anidados"(que no sé si sea el término correcto para llamarlos). Mira, aquí te dejo el PDF que me da de salida:

    http://rapidshare.com/files/269296419/ReportePrueba.pdf

    Espero que quedó claro. Otra vez gracias.

    ResponderEliminar
  11. Hola Raúl;

    Si me imaginaba que querías una cosa distinta. Y me siguen pareciendo extraños los subreportes anidados. Me parece que sería más correcto que lo hicieras con grupos. ¿Revisaste este tutorial?:

    http://javatutoriales.blogspot.com/2009/04/creacion-de-reportes-con-jasperrepots-y_17.html

    Me parece que sería mejor que intentaras crear las tes listas usando tres grupos distintos en un mismo grupo.

    Saludos

    ResponderEliminar
  12. qué tal Alex, gracias por contestar tan pronto.

    Efectivamente ya había checado ese tutorial que me mencionas. Y lo he vuelto a checar, pero no logro entender tu idea de usar grupos para este caso, debido a que son 3 listas independientes que no tienen una propiedad en común. Es decir, cuando elija en iReport crear un nuevo grupo no sé que campo eligiría para se que creen los grupos(En tu ejemplo era el campo consola, pero aquí no sé :s )

    De cualquier forma ahora estoy experimentando con los grupos para ver si logro hacerlo.

    Me podrías explicar mejor tu idea. Gracias.

    ResponderEliminar
  13. Hola Raul, perdón por dejar de contestar, pero tuve un problema en el trabajo.

    Sobre los grupos, puedes agrupar las clases por su clase (getClass()). Te dejo un ejemplo muy sencillo a ver si te sirve.


    http://sites.google.com/site/javatutoriales/home/ReporteGrupos.zip

    Fijate en el archivo reporteGrupo.jrxml que el fiel class (sobre el que está hecho el grupo) es de tipo java.lang.Class.

    Ojalá te sirva.

    Saludos

    ResponderEliminar
  14. Hola Alex,

    No te preocupes, comprendo :)

    Me gustó tu idea, pero de esta forma no se podría listar todas las propiedades de cada clase, o si? Porque por en el ejemplo todas las clases tienen las propiedades "id" y "nombre", pero que pasa si la primer clase tiene una propiedad llamada "datosClaseUno" y la segunda clase una propiedad "datosClaseDos", pasa que no puedes agregar un Field en el reporte que se llame "datosClaseUno" porque no todos los Beans que agregues a la lista van a tener esa propiedad y va a marcar error al momento de ejecutarlo. Cierto?

    Regresando a lo que yo quiero hacer, mi clase Alumno tiene una propiedad "apellido" la cual no existe en la clase Profesor ni en la clase Materia, y si agrego este field al reporte marca error.

    Al principio pensé que sólo tenía que validar el campo cuando lo quisiera imprimir en el reporte, pero luego me di cuenta que aunque no trate de imprimir este field, con el simple hecho de crearlo marca error porque no encuentra esta propiedad en los beans agregados de Profesor y Materia. :(

    Es muy buena idea la que me diste, pero no puedo lograr desplegar todos los datos de cada clase :(

    ResponderEliminar
  15. Bueno, seguí intentando hacer lo que quería en base a tu idea y por fin lo conseguí, todo me queda en un sólo archivo .jrxml, aunque la verdad siento que el nivel de complejidad para entender que hace e incluso puede ser que lleve mas tiempo en hacerlo de esta comparado con lo que hice de los reportes anidados.

    solucioné el problema de poder imprimir fields que no existan en todas las clases pasandole también como parámetro la lista de Objetos que se le manda como DataSource y a la vez haciendo uso de condiciones en las expresiones y usando la variable Report_count.

    Entonces, al final no sé que solución fue mejor jeje o tal vez sigo complicandome la vida, no lo sabré hasta que algún día vea si alguien lo hizo de alguna otra forma.

    Te agradezco toda tu ayuda (y). Muy buen Tutorial.

    Para los demás usuarios que leen esto, les recomienda que lean todo el tutorial y al final serán capaces de hacer cualquier reporte. Saludos

    ResponderEliminar
  16. Hola como puedo pasar parametros de distinto tipo por ej. tengo una consulta como la siguiente

    SELECT * FROM ingresos
    WHERE
    rut = $P{_rut} AND
    fecha between $P{fechaA} AND $P{fechaB} ORDER BY fecha

    pero no puedo enviarle los parametros

    String rut = null;
    String total = null;
    Date fecha1 = null;
    Date fecha2 = null;
    // para agregar mas parametros solo hay que agregar mas parametros.put
    Map parametro = new HashMap();
    parametro.put("_rut",rut); // lo que esta entre parecntesis es el nombre del parametro
    parametro.put("_total",total);
    parametro.put("fechaA",fecha1);
    parametro.put("fechaB",fecha2);
    Mensaje de Error:Incompatible java.lang.String value assigned to parameter fechaA in the report name dataset.

    es muy parecido a lo que postio esta persona

    http://www.javahispano.org/forum/j2se/es/diferentes_tipos_de_datos_en_jasperfillmanager/

    porfa necesito ayuda urgente con eso

    ResponderEliminar
  17. Mario,

    Pasas como parámetro un String y el parámetro en tu reporte lo declaraste como tipo Date, he ahí tu error.

    ResponderEliminar
  18. Hola Mario;

    De acuerdo a lo que dice el foro, si los parámetros con nombres "fechaA" y "fechaB" son de tipo java.util.Date entonces debería de funcionar, ya que fecha1 y fecha2 son de tipo Date. ¿Dentro de iReport estas definiendo "fechaA" y "fechaB" como Date?.

    De lo que dice el foro, aparentemente el error era que el mapa de parámetros lo declaraba en la referencia como HashMap en lugar de Map, pero parece que tu lo estas haciendo de forma correcta.

    Lo que se me ocurre es que el campo en la base de datos pudiera no ser una DATE o un TIMESTAMP, o que tu base de datos este esperando recibir la fecha en un formato particular. Para resolver esto podrías formatear tu fecha a como lo espera la base de datos, por ejemplo 2009-08-29 o el formato particular de tu base de datos, y pasar los parámetros como Strings (ya con formato). ¿O es necesario que los pases como objetos Date por alguna razón particular?

    Saludos.

    ResponderEliminar
  19. Hola Raúl;

    Fijate que pensando un poco en el problema que mencionaste con las listas de datos recordé que las nuevas versiones de JasperReports y iReports soportan listas, aunque no estoy seguro si es el mismo tipo de listas. La verdad no los he probado, pero puede ser que te ayuden a solucionar ese pequeño problema.

    Saludos

    ResponderEliminar
  20. ya lo solucione de esta forma

    Antes -> parametro.put("fechaA",fecha1);

    Despues -> parametro.put("fechaA", new Date(fecha1));

    solo cambiando eso asi ya puedo enviar el parametro de tipo Date y los demas de tipo String

    Ahora tengo otro problema

    a la hora de imprimir el reporte por la impresora me tira el siguiente error

    net.sf.jasperreports.engine.JRException: Error printing report.
    at net.sf.jasperreports.engine.print.JRPrinterAWT.printPages(JRPrinterAWT.java:198)
    at net.sf.jasperreports.engine.print.JRPrinterAWT.printPages(JRPrinterAWT.java:86)
    at net.sf.jasperreports.engine.JasperPrintManager.printPages(JasperPrintManager.java:354)
    at net.sf.jasperreports.engine.JasperPrintManager.printReport(JasperPrintManager.java:245)
    at net.sf.jasperreports.view.JRViewer$21.run(JRViewer.java:1201)
    at java.lang.Thread.run(Thread.java:619)
    Caused by: java.awt.print.PrinterException: Printer is not accepting job.
    at sun.print.RasterPrinterJob.print(RasterPrinterJob.java:1296)
    at sun.print.RasterPrinterJob.print(RasterPrinterJob.java:1247)
    at net.sf.jasperreports.engine.print.JRPrinterAWT.printPages(JRPrinterAWT.java:184)
    ... 5 more


    eso pasa solo cuando imprimo directamente a la impresora, importar a otros formatos com PDF funciona super bien

    ResponderEliminar
  21. Holaaaa!!!!

    Oye necesito ponerle un formato de moneda ami reportes, es decir me sale una cantidad de 3000.00 pero quiero que aparezca $3,000.00 y ya probe creando un objeto java.text.Format pero no me sale, me marca un error el iReport como le hago??

    ResponderEliminar
  22. Hola que tal esta muy bueno el tutorial , pero me quedo una duda , como puedo hacer para tener el subtotal por grupo , por ejemplo: los he agrupado por un articulo en especial y por cada grupo quiero ver el total de items vendidos por ejemplo. Por que en el ejemplo se muestra un total general. Como? podria hacerlo.

    ResponderEliminar
  23. Hola te agradezco por el tutorial me parece excelente. Tengo un pequeno problema, cuando genero el reporte en el iReport me sale perfecto, pero cuando lo ejecuto desde el codigo, no me muestra ningun valor, solo el titulo, me gustaria saber que podria ser, muchas gracias.

    ResponderEliminar
  24. Hola Jorge;

    Gracias por tus comentarios.

    Lo que te está pasando parece ser algo frecuente ya que varias personas me han preguntado lo mismo. Me parece que es por la diferencia entre las versiones de iReports y JasperReports que se usan, ya que las actualizan con bastante frecuencia. Asegurate de estas usando las mismas en ambos casos y de agregar todas las librerias necesarias (que en las ultimas versiones son más que las que indico en el tutorial).

    La segunda razón es que tengas un field o un parámetro o algo asi con un tipo de dato incorrecto. Por ejemplo, que lo tengas declarado como un long y le estes pasando o estés recibiendo un String.

    Espero haberte ayudado si no, no dudes en seguir preguntando hasta que se resuelva.

    Saludos

    ResponderEliminar
  25. Lis

    Hola Alex muy bueno tu tutorial. Tengo una duda, yo quiero pasar por parametro a mi reporte datos desde una base de datos. Eso se puede? y si se puede como seria el mecanismo? Gracias

    ResponderEliminar
  26. Hola Lis;

    No se si te entendí bien. ¿Lo que quieres es obtener el valor de un registro de tu base de datos y posteriormente usar este valor como un parámetro dentro de tu reporte?

    ¿Podrías darme un ejemplo más detallado de lo que quieres hacer?

    Saludos

    ResponderEliminar
  27. hola Alex como estas?, en realidad lo que quiero hacer es poder ver mi reporte en una aplicacion web pero viendo los datos desde una base de datos. Es decir hacer lo del post 4, pero con un ejemplo como el del post 1. Estoy trabajando con una aplicacion en donde el usuario ingresa datos al sistema y luego me muestre esos datos en el reporte y los pueda imprimir.

    ResponderEliminar
  28. Hola... el tipo de reporte que tengo que generar no maneja listas lo que necesito manejar es el contenido de una factura, ya la aplicación esta completamente terminada el crear la factura es lo que falta. Por lo tanto estoy tratando de manejar la información por medio de los parámetros ingresando los valores directamente por medio del mapeado, al que le paso los valores desde el mismo actionPerformed del botón que se encarga de hacer la captura de datos. El problema esta en que me lanza una JRException pero no logro arreglar el problema.. este es el codigo que de momento esta fallando..

    JasperReport reporte = (JasperReport)JRLoader.loadObject("ReporteEnvio.jasper");

    Map parametros = new HashMap();
    parametros.put("titulo", "Transportes Ramírez");
    parametros.put("cliente", nombreCliente);

    JasperPrint jasperPrint = JasperFillManager.fillReport(reporte, parametros);

    JRExporter exporter = new JRPdfExporter();
    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
    exporter.setParameter(JRExporterParameter.OUTPUT_FILE, new java.io.File("reporteEnvio.pdf"));
    exporter.exportReport();

    Donde nombreCliente es un String capturado desde un JTextField.

    ResponderEliminar
  29. Hola Marlon;

    ¿Y cúal es la excepción?

    ResponderEliminar
  30. ok.. con un catch(JRException jre) imprimiendo la excepción con un System.out.print lo que lanza el System es esto:

    net.sf.jasperreports.engine.JRException: java.io.FileNotFoundException: ReporteEnvio.jaspernet.sf.jasperreports.engine.JRException: java.io.FileNotFoundException: ReporteEnvio.jasper

    ResponderEliminar
  31. Hola Marlon;

    Lo que ocurre es que la aplicación no está encontrando el archivo de tu reporte ("ReporteEnvio.jasper"). Puede ser que estes colocando este archivo en una ruta equivocada. Recuerda que debes tener en cuenta esto si estas usando rutas relativas.

    Saludos

    ResponderEliminar
  32. De momento eso fue lo primero que pensé, pero como estoy usando netbeans con el plugin del Ireport no creí que el problema fuera la ruta ya que el mismo netbeans se encarga de guardarlo en la carpeta src. Ahora estoy empezando a creer que el problema lo esta dando el plugin... o que se te ocurre??

    ResponderEliminar
  33. Pues puede ser, aunque yo nunca he utilizado el plugin (tuve problemas con la instalación) así que no puedo estar seguro. ¿En dónde te está colocando el archivo? Recuerda que este debe estar en la raíz de tu proyecto de NetBeans

    ResponderEliminar
  34. Bueno yo no tuve ningún problema con la instalación el único cambio que vi es que si vuelve un poco mas pesado el programa.
    NetBeans guarda el archivo en la carpeta src del proyecto junto con los demás .java, intenté cambiar la ruta en el programa a "src/ReporteEnvio.jasper" pero en este caso lanza un java.lang.NoClassDefFoundError.

    Que me sugieres que haga??

    ResponderEliminar
  35. Prueba moviendo el archivo al directorio raíz de tu proyecto de NetBeans, como indica este tutorial.

    http://javatutoriales.blogspot.com/2009/02/creacion-de-reportes-con-jasperrepots-y.html

    La otra excepción es de que no encuentra cuál clase?

    ResponderEliminar
  36. Moviendo la el archivo sucede lo mismo: Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/springframework/core/io/Resource

    Voy a intentar con la versión standalone tal como lo hiciste en el tutorial

    ResponderEliminar
  37. Marlon;

    La última excepción que te aparece es porque no debes haber incluido el jar "spring.jar" en el classpath de tu aplicación y que aparentemente usan las últimas versiones de jasperReports.

    Saludos

    ResponderEliminar
  38. Listo.. solucionado ese problema... pero ahora me surgió otro... crea el pdf en blanco..

    Muchas gracias por toda la ayuda!!!

    ResponderEliminar
  39. Hola Alex, he estado trabajando con ireport ultimamente y me han salido casi todos los problemas que en este blog se comentan. Lo que me funcionó a mi fue compilar el jrxml desde la aplicación, este es el código para hacerlo y mandar directamente a la impresora predeterminada del sistema:

    //carga el archivo jrxml, deberia estar donde esta la aplicacion
    String jasperName = JasperCompileManager.compileReportToFile( "archivo.jrxml" );
    //carga el reporte
    JasperReport report = (JasperReport) JRLoader.loadObject(jasperName);
    //llena y llama a la impresora
    JasperPrintManager.printReport(JasperFillManager.fillReport(report, pars,new JREmptyDataSource()), true);

    Para los que les genera el reporte en blanco, compilen con ireport (a mi me pasaba esto de las páginas en blanco, lo compilaba con el plugin de netbeans 6.7, sin error, entonces bajé e instalé la versión standalone de ireport y ahí saltaron todos los errores de formato), si no les da error debería funcionar; tengan en cuenta si usan imagenes o texto estático que no se solape y que quede dentro del area de impresión.
    El código que puse arriba esta funcionado, cualquier duda pregunten, si está a mi alcance respondo con gusto. Fernando.-

    ResponderEliminar
  40. (*_*)
    Uno de los mejores Tutoriales
    del Tema
    (*Muy buena Explicacion*)
    Sigue asi

    ResponderEliminar
  41. LA VERDAD MUCHISIMAS FELICITACIONES.

    DE LO MEJOR EXPLICADO Y CON EXCELENTE CALIDAD DE INTERPRETACION QUE HE ENCONTRADO EN IREPORT

    ResponderEliminar
  42. Hola, quiero usar parametros desde un formulario para el informe un request.getParameter(), pero no me funciona, primero entra en en doPost( y lee los parametros y luego no se por que entra al doGet( y ya no tiene los parametros, que debo hacer?

    ResponderEliminar
  43. lo arregle usando <form name="form1" method="get"

    ResponderEliminar
  44. Amigo me bota un erro cuando, colo la ruta en el JasperReport reporte = (JasperReport) JRLoader.loadObject(getClass().getResource("/Reportes/ReporteGOC.jasper");
    te agradezco de antemano, ah trabajo en una aplicacion de escritorio!!!!

    ResponderEliminar
  45. Hola Carlos;

    El problema es la primera diagonal en tu ruta. Si lo colocar así lo que hace es buscar tu archivo .jasper en tu directorio raíz. Lo que puedes hacer es colocar la ruta completa a tu archivo (C:\algo\algo\reporte.jasper) o quitar la primer diagonal para que busque el archivo en la raiz del proyecto de NetBeans.

    Saludos

    ResponderEliminar
  46. Gracias Alex, el problema q tenia era con una version de las librerias, ya lo solucione. quisera preguntarte algo, tu no sabes como mostras un reporte de estos por pantalla osea q no me lo exporte a pdf, solo q lo muestre por pantalla. Gracias!!!!!

    ResponderEliminar
  47. Hey amigo te quiero dar las gracias por tu blog y la paciencia que habrás tenido para hacerlo la verdad me ha servido de mucho.

    ResponderEliminar
  48. Hola amigo quiero agradecerte por tu exelente tutorial, me has ayudado de sobremanera.

    Muchas gracias de nuevo.

    Hasta pronto.

    ResponderEliminar
  49. Excelente tuto, genial aprendi mucho seguire con el siguiente!!! http://javatutoriales.blogspot.com/2009/04/creacion-de-reportes-con-jasperrepots-y.html

    ResponderEliminar
  50. Tengo un reporte de jasperreport diseñado en ireport versiones 4.02, mi idea principal es pasar un parámetro desde JAVA al reporte.jasper, esto yo lo sé hacer , mi inquietud es cuando ya esta armado por ejemplo “ select * from tabla” el reporte me develve todos los registros, ahora bien si yo quiero filtrar el select seria algo asi “select * from tabla where columna=$P{parametro} ” pero si no quiero un where me devuelve vacio, mi idea que no funciona en el ireport seria algo asi “select * from tabla $P{parametro} ” ya que da error de sintaxis, lo que quisiera es algo así:
    Si $P{parametro} =””;
    Sentencia sql del jasper queda asi “select * from tabla”
    Si $P{parametro} =” where columna=1”;
    Sentencia sql del jasper queda asi “select * from table where columna=1”
    Si $P{parametro} =” where columna=1 and columna2=masculino”;
    Sentencia sql del jasper queda asi “select * from table where columna=1 and columna2=masculino”, y asi dependiendo lo que quiera mandar.
    Espero me ayuden o me den una solución parecida gracias.

    ResponderEliminar
  51. @OCTAVIO

    Buen día.

    En la construcción de la sentencia sql debes de escribir el nombre del parámetro con un signo de cerrar admiración antes del corchete para que se agregue como texto al sql:

    $P!{parametro}

    ResponderEliminar
    Respuestas
    1. Hola Miguel, y cómo seria la sintaxis en el caso de ser mas de un parámetro??

      Eliminar
    2. Hola. No soy Miguel. Pero si lo que quieres es generar tu consulta con más de una restricción, lo puedes hacer de esta forma:

      SELECT [valores] FROM [tabla] WHERE columna1 = $P{parametro1} AND columna2 = $P{parametro2};

      Eliminar
  52. Saludos buen dia e seguido al pie de la letra el tuto desde el capitulo 1, ahora me encuentro con un pronblema que me tira en la linea del jasper print no se por que motivo me marca error esa linea y esta exactamente igual a tu codigo, de hecho me baje el proyecto e inserte tu misma clase main pero igual me genera error saludos

    ResponderEliminar
  53. HOla, he estado buscando informacion sobre como crear una variable que pueda indicar la ultima pagina que se genero, debido que al reporte que tengo que hacer es dinamico.

    Alguien sabe como poder hacer una variable que logre lo que digo??, seria de mucha ayuda gracias
    me puede contactar a este email, muchas gracias.
    exequiel.ser@gmail.com

    ResponderEliminar
  54. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  55. Muy buen tutorial.

    En este momento estoy generando un reporte donde tengo dos campos fechas (Fecha_1 y Fecha_2) la idea es con una variable sacar la diferencia en días de los campos Fecha_1 y Fecha_2.

    Mi pregunta es, si puedo sacar el cálculo de la diferencia en días entre los campos fechas por medio de una variable ? y me puedes ayudar como quedaría la expresión de la variable para sacar la diferencia.

    Muchas gracias por tu colaboración.

    ResponderEliminar
  56. Saludos.
    Mi tesis es un sistema de facturación en java web y para los reportes estoy trabajando con Jasper Ireports 4.0.2, y gracias a tu ayuda ya puedo generar el reporte de la cabecera y el detalle de la factura.
    Ahora necesito generar el reporte de varias facturas pero en el mismo archivo, como puedo hacer esto.????
    Ya que para cada factura se me genera un solo archivo, y cuando genero las facturas en rango por ejemplo de la número 1 a la 5 se me abren 5 reportes.
    como puedo hacer para que todo se me habra en un solo archivo o reporte, para poderlo imprimir.
    y tambien como puedo enviar directamente a la impresora sin que se abra el reporte???

    Espero que me puedan ayudar gracias.

    ResponderEliminar
  57. Eres mi héroeeeeeeeeeeeeeeeeeeeeeee =D

    Si tuviera dinero te daria 1000000 de dolares..
    muchas gracias este es el blog mas completo que he vistooo, lo recomendare

    ResponderEliminar
  58. Hola, mi siguiente problema es como usar la sentencia BETWEEN en ireport, lo que quiero hacer es ver cuantas personas tengo registradas de tal fecha a tal fecha, si pongo mi consulta estática si me funciona, pero cuando uso parámetros me suma datos que no son. yo lo estoy usando de esta manera:

    to_char(fecha,'dd-mm-yyyy') between $P{fecha} and $P{fecha1}

    quisiera saber si es la forma correcta de usar el between en ireport.

    ResponderEliminar
  59. Hola, de verdad estos tutoriales me han servido mucho, Pero ¿quisiera saber si existe alguna manera de auto ajustar un texto estático de acuerdo a la longitud del parámetro enviado,para que no queden grandes espacios en blanco en la plantilla ya compilada?


    De antemano gracias!

    ResponderEliminar
  60. hola muchas gracias por tu aporte, esta buenísimo

    me gustaría saber como seria si necesito insertar mas de 2 parametros

    ResponderEliminar
  61. UNA PREGUNTA LO CORRO Y ME SALE UNA VENTANA QUE DICE SELECT JAVA APPLICATION Y NO SE QUE HACER AHY TRABAJO CON MYECLIPSE 9 Y IREPORTS 3.7.1

    ResponderEliminar
  62. Hola como estas yo tengo un problema con un reporte en el cual se tiene que imprimir un pedido con detalles de hasta 200 items en una impresora de 3 pulgadas, el problema es que solo me imprime hasta el item 85 lo que causa problemas a los clientes, he intentado aumentar el tamaño del reporte pero sigue imprimiendo hasta el mismo item, como podria solucionar este problema. gracias por la ayuda atentamente Marcelo Moyano

    ResponderEliminar
  63. me sigue saliendo en blanco el reporte y ya lo compile en ireport y no me da inconvenientes

    ResponderEliminar
  64. Excelentes tutoriales, muchas gracias por compartir tus conocimientos con los demás.

    ResponderEliminar
  65. Buen Tutorial, pero tengo una Duda.

    Es que estoy haciendo la creación del reporte desde otra clase. Pero en otra es que le paso todos los datos que se necesitan. Pero me sale el PDF vacio. No se que hacer.

    Otra cosa es con la ruta. No querio colocar toda la ruta desde C: sino de la manera en que tu lo haces pero no me lo encuentra :/ Lo tengo en una carpeta dentro del src del proyecto de netbeans.

    Otra cosa, como hago para guardar el pdf en otro sitio?

    Gracias por tu atencion. Buen Tutorial

    ResponderEliminar
    Respuestas
    1. Bueno. Parece que solucione ese error. Ahora me sale otro error -_-

      SEVERE: null
      net.sf.jasperreports.engine.JRException: Error retrieving field value from bean : codProducto
      Caused by: java.lang.NoSuchMethodException: Unknown property 'codProducto' on class 'class Interfaz.ProductosFactura'

      Eliminar
  66. Buen dia , excelente tutorial , me gustaria saber si alguien puede ayudarme con esta duda:

    Me encuentro generando un reporte en jasper reports donde me conecto a una base de datos mysql, uno de los campos que necesito manejar tiene en sus registros valores similares a un archivo xml, necesito cortar ese xml para que solo me exprese un valor ,en especifico: el valor de un string que se encuentra entre ciertos tags

    Es posible hacer esto desde jasper reports ?

    Gracias y agradezco su atencion.

    Saludos.

    ResponderEliminar
  67. Quiero usar varias consultas en mi informe. Pero el informe principal que me permite sólo una consulta principal, sin embargo, he encontrado una manera de tener varias consultas en mi informe y que se realiza por subdataset en iReport . Pero no estoy en condiciones de acceder a los campos de mi subdataset en mi principal-informe. ¿Cómo hacer eso?

    Gracias!

    ResponderEliminar
  68. buenas tardes como puedo dejar el fiel dinámico para la cantidad de datos que me trae el field? gracias

    ResponderEliminar
  69. por que al aumentar la fuente en el diseño del irpport si se noat el cambio ,,pero en la ejecucion ya no,,,alguien puede ayudarme


    ResponderEliminar
  70. buenas tardes como hago para que en el parámetro de entrada del jasper me muestre lo q escribo en asteriscos es un parámetro de clave que valido con data base pero no se como ocultar esa clave en el parametro

    ResponderEliminar
  71. Muchas gracias por el tutorial me sirvió mucho.

    ResponderEliminar
  72. yo uso el programa Euroges como BBDD, mi pregunta es como conecto Euroges con el Ireport que al final sera el formulario de mi factura que quiero que use Euroges.

    gracias

    ResponderEliminar
  73. Hola una consulta... como puedo hacer para generar el reporte de una factura a la hora de efectuar una venta??? osea que va a tener que mostrar datos de diferentes tablas relacionadas y que sean los datos de un solo cliente con sus respectiva compra. espero que me puedas ayudar, debido a que no se como encararlo y es para presentar la tesis. saludos

    ResponderEliminar
  74. ¿no hay forma mas sencilla de hacer este proceso?

    ResponderEliminar
  75. tengo un problema con el texto alguien puede ayudarme?

    cuando mando a imprimir un informe, si unas letras son mas largas, se amontonan y mis text estatic cambian de lugar

    ResponderEliminar