openxava / documentación / Generación de informes - Lección 7: Múltiples colecciones

Video

En este video veremos cómo crear un informe maestro detalle trabajando con varias colecciones en el mismo informe.

¿Problemas con la lección? Pregunta en el foro

Código

Puedes descargar el proyecto de esta lección. También puedes copiar el código que se usa en el video por aquí:

En el archivo controllers.xml:
<controller name="Invoice">
    <extends controller="Invoicing"/>
    <action name="printInvoiceWithOrders"
	    class="com.yourcompany.invoicing.actions.PrintInvoiceWithOrdersAction"
	    mode="detail"
	    icon="printer"/>
</controller>
En el archivo PrintInvoiceWithOrdersAction.java:
public class PrintInvoiceWithOrdersAction extends JasperReportBaseAction {

	private Invoice invoice;
	
	@Override
	protected JRDataSource getDataSource() throws Exception {
		return new JREmptyDataSource();
	}

	@Override
	protected String getJRXML() throws Exception {
		return "InvoiceWithOrders.jrxml";
	}

	@Override
	protected Map getParameters() throws Exception {
		Messages errors = MapFacade.validate("Invoice", getView().getValues());
		if (errors.contains()) throw new ValidationException(errors);
		Map parameters = new HashMap();		
		parameters.put("customerNumber", getInvoice().getCustomer().getNumber());
		parameters.put("customerName", getInvoice().getCustomer().getName());
		parameters.put("invoiceNumber", getInvoice().getNumber());
		parameters.put("date", getInvoice().getDate().toString());
		parameters.put("vatPercentage", getInvoice().getVatPercentage());
		parameters.put("vat", getInvoice().getVat());
		parameters.put("totalAmount", getInvoice().getTotalAmount());
		
		parameters.put("details", new JRBeanCollectionDataSource(getInvoice().getDetails()));
		parameters.put("orders", new JRBeanCollectionDataSource(getInvoice().getOrders()));
		
		return parameters;
	}

	private Invoice getInvoice() {
		if (invoice == null) {
			int year = getView().getValueInt("year");
			int number = getView().getValueInt("number");
			invoice = Invoice.findByYearNumber(year, number);
		}
		return invoice;
	}
	
}

Transcripción

Hola, soy Mónica. En esta lección aprenderás a diseñar reportes para trabajar con dos o más colecciones enviando una JRDataSource como parámetro para cada colección.

En controllers creamos una acción para imprimir una factura en modo detalle. Lo llamaremos printInvoiceWithOrders y apuntará a la acción PrintInvoiceWithOrdersAction. Creamos esta nueva acción en el paquete actions y copiamos de PrintInvoiceDetailAction todo el código que tiene. Agregamos dos parámetros a enviar: las líneas de detalles de factura y los órdenes asociados. Hemos enviado colecciones de esta manera por data source; lo haremos de la misma manera en parámetros. Cambiamos el nombre del reporte por InvoiceWithOrders, que crearemos luego, y retornamos una data source vacía.

Creamos un nuevo reporte llamado InvoiceWithOrders y vamos a copiar algunos elementos del reporte InvoiceDetail.Seleccionamos la sección de título y lo pegamos. Aquí también, copiamos estos elementos y seleccionamos la sección de column footer para pegarlo allí. Luego eliminamos las secciones que no vamos a usar. Añadimos otra sección de detalle. Ahora copiamos los parámetros que hay en InvoiceDetail y los pegamos en los parámetros de nuestro reporte. Listo, ahora agregamos un nuevo elemento table a details 1. Apretamos next. En Dataset name ponemos un nombre para identificarlo y seleccionamos create an empty dataset. Hacemos doble clic en la tabla. Podemos ver que, al igual que el reporte, tenemos parámetros y campos. Eliminamos las líneas que no vamos a usar, dejando solo el header y el detail. Luego ajustamos el tamaño de la tabla para que ocupe todo el ancho del reporte. Y agregamos la cantidad de columnas que necesitemos. Por último, agregamos los fields copiándolos directamente de InvoiceDetail. Agregamos los fields en el orden que queremos mostrar. Y ajustamos el ancho de cada columna. Luego arrastramos static text a la línea header para nombrar cada columna. Listo.
Creamos otra tabla para mostrar la colección de órdenes asociadas a la factura.
Seleccionamos create a table using a new dataset. Lo nombramos orders y también seleccionamos create an empty dataset. Eliminamos las líneas que no nos interesan, agregamos fields y ajustamos la tabla. Volvemos al reporte y creamos los parámetros para recibir ambas colecciones. Lo hemos enviado como JRBeanCollectionDataSource, entonces lo recibiremos de esa manera también. Por último, le asignaremos a cada tabla usar el parámetro como data source. Guardamos. Copiamos el reporte.

Pegamos el reporte e iniciamos la aplicación. Hemos logrado mostrar ambas colecciones, quizá podamos mejorar un poco estéticamente, por ejemplo, separar un poco ambas colecciones y mostrar el column footer apenas terminen las líneas de detalle. Expandimos un poco las secciones de detalle para separar ambas colecciones. Hacemos clic fuera del reporte, luego seleccionamos float column footer. Guardamos, copiamos el reporte y reiniciamos la aplicación. Listo.

Hay muchas formas de mostrar varias colecciones diferentes en un informe; hemos visto una de ellas, que es enviando una JRDataSource por cada colección como un parámetro. Si tienes alguna duda o problema, puedes preguntarnos en el foro. También puedes descargar el código de esta lección en el enlace del repositorio; ambos enlaces se encuentran en la descripción del video.

Chao.