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:

reporte jasper con spring

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:

image

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

spring mvc con jasperreport

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:

Reporte PDF generado con JasperReports en una aplicación web Spring MVC 

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.

Comentarios

  1. 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)
    public 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

    ResponderEliminar
  2. 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?
    Gracias.

    ResponderEliminar

Publicar un comentario

Temas relacionados

Entradas populares de este blog

tkinter Grid

Conectar SQL Server con Java

Controles y Contenedores JavaFX 8 - I

Histogramas OpenCV Python