Crear un Reporte con JasperReports (Ejemplo: Factura)

domingo, marzo 12, 2017
Banner JasperReports

Hace ya un tiempo que he querido compartir con ustedes la librería JasperReports (apodada cariñosamente por mí como: “lo único que hasta ahora me gusta de Java” XD, ok no..., ok si XD). La verdad es que es una herramienta que actualmente me ayuda a desarrollar reportes muy completos de la manera más sencilla posible. Sin duda puede que existan herramientas más potentes para generar reportes, pero en el mundo de Software Libre, no he visto hasta ahora una mejor.



JasperReports en si, se trata de una biblioteca de creación de reportes escrita en Java; de manera adicional para construir y editar éstos reportes, usamos programas como IReports o Jaspersoft Studio que nos facilitan las opciones que tiene disponibles JasperReports. Para éste tutorial estaré usando Jaspersoft Studio versión 6 que es la versión más actual para el momento de creación de esta entrada.

Banner Jaspersoft Studio

Quiero comenzar por mostrarles un reporte completo para que vean todo el potencial que tiene ésta librería con unos sencillos pasos, más adelante tengo pensado hacer tutoriales más puntuales a detalle para ver las características más importantes y útiles de JasperReports.

El reporte que vamos a crear en ésta entrada es una Factura, que contará con un Título de Página, un Encabezado de Columna, un Detalle y un Pie de Columna.

Antes de comenzar

Primero necesitamos tener una base de datos con la información de la Factura que vamos a mostrar en el reporte. En mi caso voy a trabajar con una base de datos en PostgreSQL. Acá les dejo los scripts de creación de las tablas y los datos de prueba.

-- Tabla de Clientes

CREATE TABLE clientes
(
  id_cliente serial NOT NULL,
  nombre character varying(250),
  CONSTRAINT pkclientes PRIMARY KEY (id_cliente )
);
COMMENT ON COLUMN clientes.id_cliente IS 'ID DEL CLIENTE';
COMMENT ON COLUMN clientes.nombre IS 'NOMBRE';

-- Tabla de Productos

CREATE TABLE productos
(
  id_producto serial NOT NULL, 
  descripcion character varying(500), 
  precio double precision, 
  CONSTRAINT pkproductos PRIMARY KEY (id_producto )
);
COMMENT ON COLUMN productos.id_producto IS 'ID DEL PRODUCTO';
COMMENT ON COLUMN productos.descripcion IS 'DESCRIPCIÓN';
COMMENT ON COLUMN productos.precio IS 'PRECIO';

-- Tabla de Facturas

CREATE TABLE facturas
(
  id_factura serial NOT NULL, 
  id_cliente integer, 
  sub_total double precision, 
  porc_impuesto double precision, 
  impuesto double precision, 
  total_general double precision, 
  CONSTRAINT pkfacturas PRIMARY KEY (id_factura ),
  CONSTRAINT fkfacturas FOREIGN KEY (id_cliente)
      REFERENCES clientes (id_cliente) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
);
COMMENT ON COLUMN facturas.id_factura IS 'ID DE FACTURA';
COMMENT ON COLUMN facturas.id_cliente IS 'ID DEL CLIENTE';
COMMENT ON COLUMN facturas.sub_total IS 'SUBTOTAL';
COMMENT ON COLUMN facturas.porc_impuesto IS 'PORCENTAJE IMPUESTO';
COMMENT ON COLUMN facturas.impuesto IS 'IMPUESTO';
COMMENT ON COLUMN facturas.total_general IS 'TOTAL GENERAL';

-- Tabla de Detalles de Facturas

CREATE TABLE facturas_det
(
  id_factura integer NOT NULL, 
  renglon integer NOT NULL, 
  id_producto integer, 
  cantidad integer, 
  precio double precision, 
  total double precision, 
  CONSTRAINT pkfacturas_det PRIMARY KEY (id_factura , renglon),
  CONSTRAINT fkfacturas_det FOREIGN KEY (id_factura)
      REFERENCES facturas (id_factura) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT fkfacturas_det2 FOREIGN KEY (id_producto)
      REFERENCES productos (id_producto) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
);
COMMENT ON COLUMN facturas_det.id_factura IS 'ID DE FACTURA';
COMMENT ON COLUMN facturas_det.renglon IS 'RENGLON';
COMMENT ON COLUMN facturas_det.id_producto IS 'ID DEL PRODUCTO';
COMMENT ON COLUMN facturas_det.cantidad IS 'CANTIDAD';
COMMENT ON COLUMN facturas_det.precio IS 'PRECIO';
COMMENT ON COLUMN facturas_det.total IS 'TOTAL';

-- Datos de Prueba

INSERT INTO clientes (id_cliente, nombre) VALUES (1, 'TONY STARK');
INSERT INTO productos (id_producto, descripcion, precio) VALUES (1, 'CHOCOLATE CARRE', 1300);
INSERT INTO productos (id_producto, descripcion, precio) VALUES (3, 'CHOCOLATE CRI CRI', 900);
INSERT INTO productos (id_producto, descripcion, precio) VALUES (2, 'TORONTO', 250);
INSERT INTO facturas (id_factura, id_cliente, sub_total, porc_impuesto, impuesto, total_general) VALUES (1, 1, 2700, 0.12, 324, 3024);
INSERT INTO facturas_det (id_factura, renglon, id_producto, cantidad, precio, total) VALUES (1, 1, 1, 1, 1300, 1300);
INSERT INTO facturas_det (id_factura, renglon, id_producto, cantidad, precio, total) VALUES (1, 2, 2, 2, 250, 500);
INSERT INTO facturas_det (id_factura, renglon, id_producto, cantidad, precio, total) VALUES (1, 3, 3, 1, 900, 900);

¡Ahora sí, comencemos!

1. Abrir el programa Jaspersoft Studio y nos ubicamos en el botón New JasperReport o en el menú File->New->Jasper Report.


2. A continuación nos aparecerá el Asistente de Creación de Reportes (New Report Wizard) que nos guiará en la creación del reporte. Primero seleccionamos el Template adecuado para nuestro reporte, para éste ejemplo una hoja en blanco (Blank Letter) y hacemos clic en Next.


3. Ahora seleccionamos la carpeta donde se va a guardar el reporte y el nombre que va a tener. Lo llamaremos Factura.jrxml.

La extensión de los archivos de JasperReports es .jrxml y como su nombre lo sugiere están escritos en xml.


4. Ahora nos pide seleccionar el origen de los datos, vamos a hacer clic en el botón New. Nos abrirá un Asistente de Conexión a la Base de Datos (Data Adapter Wizard).


5. Seleccionamos Database JDBC Connection.


6. Ahora escribimos los datos de nuestra conexión a la base de datos en PostgreSQL que ya creamos en los pasos previos Antes de comenzar. Hagamos clic en el botón Test para probar la conexión y una vez que este listo hacemos clic en Finish para terminar con el Asistente de Conexión a la Base de Datos.


7. Llego el momento de indicar la consulta principal del reporte. Una vez copiada hacemos clic en Next.

-- Obtener la Factura Nro. 1 de la Base de Datos

SELECT 
	f.id_factura, 
	c.nombre, 
	f.sub_total, 
	f.impuesto, 
	f.porc_impuesto, 
	f.total_general,
	fd.renglon,
	p.descripcion,
	fd.cantidad,
	fd.precio,
	fd.total
FROM facturas f
INNER JOIN clientes c ON (f.id_cliente = c.id_cliente)
INNER JOIN facturas_det fd ON (f.id_factura = fd.id_factura)
INNER JOIN productos p ON (fd.id_producto = p.id_producto)
WHERE f.id_factura = 1
ORDER BY fd.renglon

8. Ahora seleccionamos los campos de la consulta que vamos a requerir en el reporte. Seleccionaremos todos >>. Por último hacemos clic en Finish para terminar con el Asistente de Creación de Reportes.


9. En este momento nos encontramos con el entorno de trabajo de Jaspersoft Studio.


10. Procedemos a insertar un Static Text para crear en encabezado de la empresa y otro para el titulo de la factura. Para ello nos dirigimos la sección Palette a la derecha del entorno y arrastramos el elemento al lugar requerido, en éste caso en la banda Title.


11. Una vez que escribamos los títulos procederemos a usar los distintos campos de nuestra consulta que se encuentran en la columna izquierda del entorno dentro de los Fields. Vamos a tomar el id_factura y lo vamos a arrastrar a la posición en la cual queremos mostrar el número de la factura.


12. Al arrastrar el id_factura a la banda Title, nos preguntará si queremos hacer algún tipo de cálculo con ese campo, ya que el Title es algo que se muestra solo una vez. Entonces seleccionamos la primera opción No Calculation Function para que solo nos muestre el primer valor de la consulta.


13. Repetimos el proceso con el campo nombre como se ve a continuación.


14. Ahora viene una parte interesante, seleccionamos los campos renglon, descripcion, cantidad, precio y total y los arrastramos dentro de la banda Detail 1. Automáticamente los campos se distribuirán uniformemente a lo ancho de la banda como se aprecia en la imagen y en el Column Header se agregará como título el comentario de la columna de tabla de la base de datos.


15. Ahora mejoramos un poco más nuestra factura ajustando el alto de las bandas para proceder a ver el primer resultado y agregando al final en el Column Footer los campos sub_total, porc_impuesto, impuesto y total_general.


16. Procedemos a generar la vista previa del reporte la pestaña inferior Preview.

Éste proceso procederá a compilar el reporte y a generar un archivo .jasper que será el que llamemos desde nuestras aplicaciones.


17. Éste es el primer resultado que obtendremos de nuestra Factura.


18. Como extra podemos darle formato a los números para mejorar nuestro reporte. Eso lo conseguimos haciendo clic derecho sobre el Text Field al que le vamos a dar formato y luego vamos a la opción Show Properties->Text Field->Pattern. Allí ajustaremos el formato chequeando la opción Use 1000 separator y modificando Decimal places a 2.


19. Finalmente nuestra Factura quedará de la siguiente manera.


Eso es todo por este tutorial, espero que les sea de utilidad y muy pronto continuar con esta serie de JasperReports. No duden en dejar en los comentarios si quieren aprender algo en particular de esta herramienta, que si está a alcance con gusto lo puedo incluir en mis entradas.

Solo me queda mencionar que en una entrada anterior explique como generar reportes desde Laravel con JasperReportes.

También te puede interesar

Cuando navego por los sitios web, mi parte favorita es leer los comentarios. Es por eso que tus comentarios son un complemento valioso para mis entradas. Cualquier duda o aporte no dejes de escribirlo, en breve lo estaré publicando. ¡Gracias!


10 comentarios

  1. Hola, gracias por este artículo y el anterior,
    sabes, quiero comenzar a implementar JR en un proyecto con PHP, pero tengo una duda,
    necesito tener un servidor jasperreports ademas? o basta con las librerías jasperphp y el archivo de reporte compilado? si se puede ambos casos, cual sería la ventaja de usar o no un servidor

    De antemano muchas gracias

    Saludos desde Chile


    Carlos


    ResponderBorrar
    Respuestas
    1. Saludos Carlos! Es correcto, lo único que necesitas es:

      1) tener instalada la JVM (Máquina Virtual de Java) en tu servidor,
      2) instalar en tu proyecto la librería JasperPHP y
      3) tener el compilado del reporte que vas a ejecutar.

      Si son posibles las dos opciones que mencionas, personalmente prefiero éste método que te comento y te explico en mi otra entrada "Generación de reportes en Laravel 5 con JasperPHP (JasperReports)" ya que no requiere tener que instalar un servidor web adicional con Java (P.ej. GlassFish) para que tus reportes puedan ejecutarse.

      Borrar
  2. ¿Cómo haría si quiero que el HEADER se muestre sólo en la primera página?, de antemano muchas gracias por tu ayuda.

    ResponderBorrar
    Respuestas
    1. Hola Monica, ya ha pasado algún tiempo pero igual dejo ésto por aquí... Si usas la banda "Page Header", para hacer que sólo se muestre en la primera página, dirígete a "Properties"->"Advanced", y coloca en "Print When Expression" la siguiente expresión: $V{PAGE_NUMBER}.intValue() == 1, y listo!

      Borrar
  3. Gracias por el aporte, es lo que estaba buscando. Saludos de un carabobeño en Perú

    ResponderBorrar
  4. Hola, gracias por el articulo.
    Necesito hacer algo parecido, pero por cliente. Como se podría hacer sin tener que filtrar uno por uno?

    ResponderBorrar
    Respuestas
    1. Hola!! No entiendo muy bien lo que buscas. Pero si puedes hacer que la consulta se filtre por id_cliente en vez de id_factura y obtener todas las facturas asociadas a un cliente. Tal vez se tenga que ajustar un poco el reporte para ello. Saludos!!

      Borrar
  5. Muchas gracias por el tutorial. Me fue muy útil. Saludos desde México.

    ResponderBorrar

Lo más reciente

¡Bendiciones para mi Venezuela!

¡Bendiciones para mi Venezuela!