Spring MVC Generar reportes JasperReports
JasperReport es una de las bibliotecas de generación de reportes mas populares en el lenguaje de programación Java, dedicaremos esta publicación a la integración de la librería JasperReport a una aplicación web desarrollada con el Framework Java Spring MVC, en este tutorial no profundizaremos en detalles sobre la creación y generación de reportes, nos centraremos en la integración de ambas tecnologías.
Para el ejemplo desarrollamos la siguiente plantilla para el reporte:
Esta plantilla corresponde al archivo report.jrxml visualizado y generado con la herramienta TIBCO Jasper Studio, lo compilamos y obtenemos el archivo report.jasper que usaremos para generar el reporte en la vista web.
Para integrar Spring MVC y JasperReport requerimos las siguientes dependencias:
<!-- Spring Web MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- JasperReport -->
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports</artifactId>
<version>6.3.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.7</version>
</dependency>
<!-- PDF View -->
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
<!-- XLS View -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
JasperReport utiliza librerías externas para generar los reportes en distintos formatos, por ejemplo, la librería iText para generar el reporte en formato PDF, o la librería Apache POI para generar el reporte en formato Excel XLS.
Configuramos el ViewResolver
para los reportes de manera muy similar a como lo hicimos con las vistas JSP, requerimos un bean de tipo JasperReportsViewResolver
.
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {
"carmelo.spring.controller",
"carmelo.spring.service"})
public class WebAppConfig {
@Bean
public JasperReportsViewResolver getJasperReportsViewResolver() {
JasperReportsViewResolver resolver = new JasperReportsViewResolver();
resolver.setPrefix("classpath:/jasperreports/");
resolver.setSuffix(".jasper");
resolver.setReportDataKey("datasource");
resolver.setViewNames("*_report");
resolver.setViewClass(JasperReportsMultiFormatView.class);
resolver.setOrder(1);
return resolver;
}
@Bean
public ViewResolver internalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setOrder(2);
return resolver;
}
}
La propiedad prefix establece la ubicación de los archivos de reporte compilados, siffix indica la extensión de estos archivos, mientras que viewNames establece el patrón que debe tener el nombre lógico de la vista devuelto por el controlador, el patrón: *_report
indica que el nombre siempre debe terminar con _report, un ejemplo sería: customer_report, si el controlador devuelve este nombre se obtendrá el archivo src/main/resources/jasperreports/customer_report.jasper.
Otras dos propiedades importantes son reportDataKey que establece el nombre que identificara la fuente de datos para el reporte, además viewClass define la clase usada para generar la vista, nosotros usaremos la clase JasperReportsMultiFormatView
ya que nos permite definir en tiempo de ejecución la vista que deseamos utilizar, tenemos las siguientes clases disponibles:
La clase JasperReportsMultiFormatView
usando la clave del formato, por ejemplo, para csv utilizará la clase JasperReportsCsvView
que se encargará de generar la vista para el formato CSV, ocurre del mismo modo con las otras clases.
Ahora podemos pasar a ver el controlador.
@Controller
public class CustomerController {
@Autowired
private CustomerService customerService;
@RequestMapping("/")
public ModelAndView verInicio() {
return new ModelAndView("customer");
}
@RequestMapping("/report")
public String verReporte(Model model,
@RequestParam(
name = "format",
defaultValue = "pdf",
required = false) String format) {
model.addAttribute("format", format);
model.addAttribute("datasource", customerService.findAll());
model.addAttribute("AUTOR", "Tutor de programacion");
return "customer_report";
}
}
Lo primero que debemos notar es que utilizamos un parámetro en la URL para definir el formato en que deseamos generar la vista, este es opcional y por defecto su valor es PDF, la clase encargada de manejar las vistas, JasperReportsMultiFormatView
accederá al formato a través del atributo format del modelo, el atributo datasource indica la fuente de datos, por último el atributo AUTOR será usado como parámetro para el reporte, podemos agregar los parámetros para el reporte que deseemos o necesitemos, solo lo agregamos al modelo con el nombre correcto.
Como fuente de datos usamos un objeto List<Customer>
el Framework Spring lo encapsulará dentro de un objeto JRBeanCollectionDataSource
que será manejado por JasperReport para generar el reporte correspondiente.
En JasperReport un parámetro se define como $P{NOMBRE_PARAMETRO}
, para acceder a un campo de un objeto $F{NOMBRE_CAMPO}
.
Nuestra fuente de datos es una colección de objetos Customer
, clase que se define de la siguiente manera:
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Customer {
private Integer ID;
private String FIRSTNAME;
private String LASTNAME;
private String STREET;
private String CITY;
}
Usamos Lombok para agilizar el desarrollo, este framework escribe los getter, setter, y constructores.
Si ejecutamos y vemos en el navegador, tendremos:
Si deseas generar otro formato de vista debes agregar el parámetro format= a la URL definiendo el formato deseado, algunos ejemplos:
- http://localhost:8084/jreport/report?format=xls
- http://localhost:8084/jreport/report?format=csv
Con esto terminamos, vimos lo fácil que es integrar la librería JasperReports a una aplicación web Spring MVC, generamos distintos tipos de reportes, en formatos diversos sin mucho esfuerzo, nos vemos en la próxima.
- Ver GitHub: JasperReport en Spring MVC
- Más Tutoriales: Cursos Spring Framework
Una consulta, mi datasource no es una lista, sino la misma base de datos, dime como podría hacer en ese caso? yo estoy haciendo algo como: @RequestMapping(value = { "/reporte"}, method = RequestMethod.GET)
ResponderEliminarpublic String verReporte(Model model,
@RequestParam(name = "format", defaultValue = "pdf", required = false) String format)
throws ClassNotFoundException, InstantiationException, SQLException, IllegalAccessException{
System.out.println("entramos a verReporte");
Conexion cnx = new Conexion();
model.addAttribute("format", format);
model.addAttribute("datasource",cnx.conexionCGC());
System.out.println("model: "+model);
return "Rep_AhorrosCero";
}
Pero me sale el error: Value [oracle.jdbc.driver.T4CConnection@60755388] cannot be converted to a JRDataSource
Sabrás porque me sale este error? Saludos
Hola. Muy buen tutorial. Consulta: ¿Cómo le seteás el nombre al PDF para que no te ponga como nombre la URL del Controller?
ResponderEliminarGracias.