Spring MVC Reportes con DynamicReports
En el tutorial Spring MVC JasperReports aprendimos a generar vistas (PDF, HTML, XLS, etc.) con la librería de reportes antes mencionada, en este post veremos como generar los reportes sin necesidad de utilizar las plantillas JRXML, el diseño del reporte será creado programáticamente con la biblioteca DynamicJasper diseñada para tal propósito, lo aprendido se puede aplicar a otras librerías similares como, DynamicReports por ejemplo.
Lo primero, como siempre, es agregar las dependencias para poder utilizar la librería DynamicJasper.
<!-- Dynamic Jasper -->
<dependency>
<groupId>ar.com.fdvs</groupId>
<artifactId>DynamicJasper</artifactId>
<version>5.0.10</version>
</dependency>
<!-- Excel XLS View -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
La segunda dependencia es opcional, la añadimos solo si deseamos generar vistas Excel XLS.
Nuestra configuración queda del siguiente modo, definimos dos ViewResolver uno para las vistas JSP y otro para los reportes.
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {
"carmelo.spring.controller",
"carmelo.spring.service"})
public class WebAppConfig {
@Bean
public ViewResolver reportViewResolver() {
JasperReportsViewResolver resolver = new JasperReportsViewResolver();
resolver.setViewNames("*_DynamicReport");
resolver.setViewClass(DynamicReportView.class);
resolver.setOrder(1);
return resolver;
}
@Bean
public ViewResolver jspViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setOrder(2);
return resolver;
}
}
El JasperReportsViewResolver
ya lo usamos en el tutorial Spring MVC con JasperReports, setViewNames("*_DynamicReport") estable el nombre de las vistas que manejaremos con este ViewResolver
, en este ejemplo todas la vistas cuyo nombre termine en _DynamicReport.
La clase DynamicReportView
la crearemos nosotros, esta es nuestra implementación, la cual será la encargada de generar las vistas, para facilitar nuestro trabajo de programación extenderemos la clase JasperReportsMultiFormatView
.
public class DynamicReportView extends JasperReportsMultiFormatView {
@Override
protected JasperReport loadReport() {
return null;
}
@Override
protected JasperPrint fillReport(Map<String, Object> model) throws Exception {
JRDataSource ds = new JRBeanCollectionDataSource((Collection<?>) model.get("datasource"));
ReportGenerator rg = (ReportGenerator) model.get("generator");
JasperReport jr = rg.generateReport(model);
JasperPrint jp = JasperFillManager.fillReport(jr, model, ds);
return jp;
}
}
El método loadReport()
carga el archivo .jrxml o .jasper pero ya no lo necesitamos, el método fillReport(Map model)
lo usaremos para generar el reporte, usando el modelo le pasaremos la fuente de datos y un objeto ReportGenerator
que se define de la siguiente manera.
import java.util.Map;
import net.sf.jasperreports.engine.JasperReport;
public interface ReportGenerator {
JasperReport generateReport(Map params);
}
Usando esta interface indicaremos cual será el método encargado de generar el reporte.
En nuestro controlador debemos agregar los atributos necesarios al modelo, datasource, generator y format, adicionalmente agregamos cualquier otros parámetro para el reporte.
@Controller
public class CustomerController {
@Autowired
private CustomerService customerService;
@RequestMapping("/report/{fmt}")
public String report(@PathVariable("fmt") String format, Model model) {
model.addAttribute("format", format);
model.addAttribute("datasource", customerService.findAll());
model.addAttribute("generator", (ReportGenerator) this::customerReport);
return "customer_DynamicReport";
}
private JasperReport customerReport(Map params) {
try {
FastReportBuilder drb = new FastReportBuilder();
drb
.addColumn("ID", "ID", Integer.class.getName(), 10)
.addColumn("FIRSTNAME", "FIRSTNAME", String.class.getName(), 50)
.addColumn("LASTNAME", "LASTNAME", String.class.getName(), 50)
.addColumn("STREET", "STREET", String.class.getName(), 50)
.addColumn("CITY", "CITY", String.class.getName(), 50)
.setTitle("Primer informe con Dynamic Jasper")
.setPrintBackgroundOnOddRows(true)
.setUseFullPageWidth(true);
return DynamicJasperHelper.generateJasperReport(
drb.build(), new ClassicLayoutManager(), params);
} catch (ColumnBuilderException | ClassNotFoundException | JRException ex) {
Logger.getLogger(CustomerController.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
}
El método customerReport(Map model)
es el encargado de generar el reporte usando la librería DynamicJasper dependiendo de tu proyecto aquí deberán agregar o quitar elementos del diseño del reporte, se puede utilizar cualquier otra librería.
El formato de salida de la vistas esta definido en una variable en la URL:
- Excel: localhost:8084/dynamicjasper/report/xls
- PDF: localhost:8084/dynamicjasper/report/pdf
- CSV: localhost:8084/dynamicjasper/report/csv
Es todo por ahora nos vemos en la próxima.
- Ir a GitHub: Proyecto Spring MVC DynamicReport
- Ir a Inicio: Serie Spring Framework
Hola muchas Gracias por tu tutorial pero como deberia de modificar si quiero usar esta opcion en spring boot pero REST API ?
ResponderEliminarDe antemano muchas Gracias
Dos ejemplos de uso con REST:
Eliminarhttps://acodigo.blogspot.com/2015/05/spring-data-rest-accediendo-datos.html
https://acodigo.blogspot.com/2015/03/servicios-restful-con-spring.html
Los vi pero a lo que me refiero es como hago con jasperreport con Spring boot API REST por que ahi no he visto que se use el WebAppConfig
ResponderEliminar