Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 230 Vote(s) - 3.43 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to use JasperReports with Spring MVC?

#1
I've been investigating the use of JasperReports (6.0.0) with Spring MVC (4.1.3) to generate PDF reports. Spring is rife with "Spring specific" ways to integrate with JasperReports to generate PDFs:

- Use [`JasperReportsPdfView`][2] *relies on now deprecated JasperReport features*
- Use [`JasperReportsMultiFormatView`][3]
- Use [`JasperReportsViewResolver`][4]

I struggled to find good, complete examples online and wanted to share my findings (see [my answer below][1]).

Feel free to add additional methods and/or improvements related to "How can I integrate JasperReports with Spring4"?

[1]:

[To see links please register here]

[2]:

[To see links please register here]

[3]:

[To see links please register here]

[4]:

[To see links please register here]

Reply

#2
Based on my research, I've found the following usage methods. The methods begin with the most direct (naive) approach involving less up front complexity / configuration and evolve to become more abstract but with more dependencies on Spring / more complex Spring configuration.

Method 1: Use the JasperReports API directly in the Controller
------------------------------------------------------------------
Just write out the content to the servlet output stream.

@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);
}


----------


Method 2: Inject JasperReportPdf View into Controller
-----------------------------------------------------
Given the JasperReportsPdfView bean:

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

This view can be injected or wired into the Controller for use:

@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;
}

Note that using the `JasperReportsPdfView` (or the more versatile `JasperReportsMultiFormatView`) requires a dependency on spring-context-support:

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

----------


Method 3: Use XML or ResourceBundle view resolver to map logical view names to JasperReport views
-----------------------------------------------------

Configure a new view resolver, in this case the `ResourceBundleViewResolver` to run before the `InternalResourceViewResolver`. This is based on the order values being set (0 happens before 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;
}

Then, at the root of our classpath, the `jasperreport-views.properties` file can contain the logical view name paired with the class and property values (i.e. url and reportDataKey) pertinent to rending a JasperReport:

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

The controller code looks like this:

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


I like this approach. Controllers stay "dumb" and only deal with String values and the mapping of names to views can happen all in one location.

----------

Method 4: Use JasperReportsViewResolver
-----------------------------------------------------

Configure a zero-ordered `JasperReportViewResolver` and the trick is use `setViewNames` to tell Spring which logical view names you want this resolver to deal with (otherwise you end up with "Could not load JasperReports report from class path resource [jasperreports/index.jasper]" type errors):

@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;
}

And inside the controller:

@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;
}

This is my preferred approach. Controllers resolve jasper reports in a very similar fashion to how jsp views are resolved using the `InternalResourceViewResolver` and there is therefore no need for an explicit mapping file as with the xml or properties file approach in method #3 above.


**EDIT**

The [javadocs for `JasperReportsPdfView`][1] mention it uses the deprecated `JRExporter` API. Is there a better (newer) JasperReports view to use? Perhaps opting for the [`JasperReportsMultiFormatView`][2] is a better option as it does not appear to use `JRExporter`.




[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#3
My Method:



@RequestMapping(value="getPDF", method=RequestMethod.GET)
public void generatePDF(int idPredstave, HttpServletResponse response) throws Exception{

Predstava p = pr.findById(idPredstave).get();
List<Uloga> uloge = ur.findByPredstava(p);

response.setContentType("text/html");
JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(uloge);
InputStream inputStream = this.getClass().getResourceAsStream("/jasperreports/Uloge.jrxml");
JasperReport jasperReport = JasperCompileManager.compileReport(inputStream);
Map<String, Object> params = new HashMap<String, Object>();
params.put("nazivPredstave", p.getNaziv());
params.put("trajanje", p.getTrajanje());
params.put("opis", p.getOpis());
params.put("zanr", p.getZanr().getNaziv());
params.put("reziser", p.getReziser().getIme()+" "+p.getReziser().getPrezime());
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, dataSource);
inputStream.close();


response.setContentType("application/x-download");
response.addHeader("Content-disposition", "attachment; filename=Uloge.pdf");
OutputStream out = response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint,out);
}
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through