mvc modelandview jasperreportspdfview jasperreports jasperreport jasper example java spring spring-mvc jasper-reports spring-4

java - modelandview - spring jasperreports maven



¿Cómo usar JasperReports con Spring MVC? (1)

He estado investigando el uso de JasperReports (6.0.0) con Spring MVC (4.1.3) para generar informes en PDF. La primavera está plagada de formas "específicas de Spring" para integrarse con JasperReports para generar archivos PDF:

Luché para encontrar buenos ejemplos completos en línea y quería compartir mis hallazgos (ver mi respuesta a continuación ).

Siéntase libre de agregar métodos adicionales y / o mejoras relacionadas con "¿Cómo puedo integrar JasperReports con Spring4"?


Basado en mi investigación, he encontrado los siguientes métodos de uso. Los métodos comienzan con el enfoque más directo (ingenuo) que implica una complejidad / configuración menos avanzada y evolucionan para volverse más abstractos pero con más dependencias en Spring / configuración de Spring más compleja.

Método 1: use la API JasperReports directamente en el controlador

Simplemente escriba el contenido en la secuencia de salida del servlet.

@RequestMapping(value = "helloReport1", method = RequestMethod.GET) @ResponseBody public void getRpt1(HttpServletResponse response) throws JRException, IOException { InputStream jasperStream = this.getClass().getResourceAsStream("/jasperreports/HelloWorld1.jasper"); Map<String,Object> params = new HashMap<>(); JasperReport jasperReport = (JasperReport) JRLoader.loadObject(jasperStream); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, new JREmptyDataSource()); response.setContentType("application/x-pdf"); response.setHeader("Content-disposition", "inline; filename=helloWorldReport.pdf"); final OutputStream outStream = response.getOutputStream(); JasperExportManager.exportReportToPdfStream(jasperPrint, outStream); }

Método 2: inyecte la vista JasperReportPdf en el controlador

Dado el JasperReportsPdfView bean:

@Bean @Qualifier("helloWorldReport2") public JasperReportsPdfView getHelloWorldReport() { JasperReportsPdfView v = new JasperReportsPdfView(); v.setUrl("classpath:jasperreports/HelloWorld2.jasper"); v.setReportDataKey("datasource"); return v; }

Esta vista se puede inyectar o conectar en el controlador para su uso:

@Autowired @Qualifier("helloWorldReport2") private JasperReportsPdfView helloReport; @RequestMapping(value = "helloReport2", method = RequestMethod.GET) public ModelAndView getRpt2(ModelAndView modelAndView) { Map<String, Object> parameterMap = new HashMap<>(); parameterMap.put("datasource", new JREmptyDataSource()); modelAndView = new ModelAndView(helloReport, parameterMap); return modelAndView; }

Tenga en cuenta que el uso de JasperReportsPdfView (o el más versátil JasperReportsMultiFormatView ) requiere una dependencia en spring-context-support:

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.1.3</version> </dependency>

Método 3: Use XML o ResourceBundle view resolver para asignar nombres de vista lógica a las vistas de JasperReport

Configure una nueva resolución de vista, en este caso ResourceBundleViewResolver para ejecutar antes de InternalResourceViewResolver . Esto se basa en los valores de orden establecidos (0 ocurre antes de 1):

@Bean public ResourceBundleViewResolver getResourceBundleViewResolver() { ResourceBundleViewResolver resolver = new ResourceBundleViewResolver(); resolver.setBasename("jasperreport-views"); resolver.setOrder(0); return resolver; } @Bean public InternalResourceViewResolver getInternalResourceViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setOrder(1); return resolver; }

Luego, en la raíz de nuestro classpath, el archivo jasperreport-views.properties puede contener el nombre de vista lógica emparejado con la clase y los valores de propiedad (es decir, url y reportDataKey) pertinentes para rasgar un JasperReport:

helloReport3.(class)=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView helloReport3.url=classpath:/jasperreports/HelloWorld3.jasper helloReport3.reportDataKey=myDataSourceKey

El código del controlador se ve así:

@RequestMapping(value = "helloReport3", method = RequestMethod.GET) public ModelAndView getRpt3(ModelMap modelMap, ModelAndView modelAndView) { modelMap.put("myDataSourceKey", new JREmptyDataSource()); return new ModelAndView("helloReport3", modelMap); }

Me gusta este enfoque. Los controladores se mantienen "tontos" y solo se ocupan de los valores de cadena y la asignación de nombres a las vistas puede realizarse en un solo lugar.

Método 4: utilice JasperReportsViewResolver

Configura un JasperReportViewResolver ordenado por cero y el truco es usar setViewNames para decirle a Spring qué nombres de vista lógica quieres que setViewNames este resolvedor (de lo contrario terminarás con "No se pudo cargar el informe JasperReports del recurso de ruta de clase [jasperreports / index.jasper]" tipo de errores):

@Bean public JasperReportsViewResolver getJasperReportsViewResolver() { JasperReportsViewResolver resolver = new JasperReportsViewResolver(); resolver.setPrefix("classpath:/jasperreports/"); resolver.setSuffix(".jasper"); resolver.setReportDataKey("datasource"); resolver.setViewNames("rpt_*"); resolver.setViewClass(JasperReportsMultiFormatView.class); resolver.setOrder(0); return resolver; } @Bean public InternalResourceViewResolver getInternalResourceViewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".jsp"); resolver.setOrder(1); return resolver; }

Y dentro del controlador:

@RequestMapping(value = "helloReport4", method = RequestMethod.GET) public ModelAndView getRpt4(ModelMap modelMap, ModelAndView modelAndView) { modelMap.put("datasource", getWidgets()); modelMap.put("format", "pdf"); modelAndView = new ModelAndView("rpt_HelloWorld", modelMap); return modelAndView; }

Este es mi enfoque preferido. Los controladores resuelven los informes de jaspe de forma muy similar a cómo se resuelven las vistas de jsp utilizando InternalResourceViewResolver y, por lo tanto, no es necesario un archivo de mapeo explícito como con el enfoque de archivo xml o de propiedades en el método n.º 3 anterior.

EDITAR

Los JasperReportsPdfView mencionan que usa la API JRExporter desuso. ¿Hay una mejor (más reciente) vista de JasperReports para usar? Tal vez optar por JasperReportsMultiFormatView es una mejor opción, ya que no parece usar JRExporter .