Java 如何在Spring MVC中使用JasperReports?

Java 如何在Spring MVC中使用JasperReports?,java,spring,spring-mvc,jasper-reports,spring-4,Java,Spring,Spring Mvc,Jasper Reports,Spring 4,我一直在研究如何使用JasperReports(6.0.0)和springmvc(4.1.3)生成PDF报告。Spring采用“特定于Spring”的方式与JasperReports集成以生成PDF: 使用依赖于现在已弃用的JasperReport功能 使用 使用 我努力在网上找到好的、完整的例子,并想分享我的发现(见) 请随意添加与“如何将JasperReports与Spring4集成”相关的其他方法和/或改进 根据我的研究,我发现了以下使用方法。这些方法从最直接的(幼稚的)方法开始,涉及

我一直在研究如何使用JasperReports(6.0.0)和springmvc(4.1.3)生成PDF报告。Spring采用“特定于Spring”的方式与JasperReports集成以生成PDF:

  • 使用依赖于现在已弃用的JasperReport功能
  • 使用
  • 使用
我努力在网上找到好的、完整的例子,并想分享我的发现(见)


请随意添加与“如何将JasperReports与Spring4集成”相关的其他方法和/或改进

根据我的研究,我发现了以下使用方法。这些方法从最直接的(幼稚的)方法开始,涉及较少的前期复杂性/配置,并逐渐变得更抽象,但对Spring/更复杂的Spring配置有更多的依赖性

方法1:在控制器中直接使用JasperReports API 只需将内容写入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);
  }
此视图可以插入或连接到控制器中以供使用:

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

方法3:使用XML或ResourceBundle视图解析器将逻辑视图名称映射到JasperReport视图 配置一个新的视图解析器,在本例中,
ResourceBundleViewResolver
internalresourceviewsolver
之前运行。这基于所设置的顺序值(0发生在1之前):

然后,在类路径的根目录下,
jasperreport views.properties
文件可以包含逻辑视图名称以及与呈现jasperreport相关的类和属性值(即url和reportDataKey):

helloReport3.(class)=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
helloReport3.url=classpath:/jasperreports/HelloWorld3.jasper
helloReport3.reportDataKey=myDataSourceKey
控制器代码如下所示:

@RequestMapping(value = "helloReport3", method = RequestMethod.GET)
public ModelAndView getRpt3(ModelMap modelMap, ModelAndView modelAndView) {
  modelMap.put("myDataSourceKey", new JREmptyDataSource());
  return new ModelAndView("helloReport3", modelMap);
}
我喜欢这种方法。控制器保持“哑”,只处理字符串值,名称到视图的映射可以在一个位置发生


方法4:使用JasperReportsViewResolver 配置一个零序的
jasperreportviewsolver
,诀窍是使用
setViewNames
告诉Spring您希望该解析器处理哪些逻辑视图名称(否则会出现“无法从类路径资源[JasperReports/index.jasper]加载JasperReports报告”类型错误):

在控制器内部:

@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;
}
这是我喜欢的方法。控制器解析jasper报告的方式与使用
InternalResourceViewResolver
解析jsp视图的方式非常相似,因此不需要像上面方法#3中的xml或属性文件方法那样使用显式映射文件

编辑

提到它使用了不推荐的
jreporter
API。是否有更好(更新)的JasperReports视图可供使用?也许选择是一个更好的选择,因为它似乎没有使用
jreporter

我的方法:

   @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);
}
@RequestMapping(value=“getPDF”,method=RequestMethod.GET)
public void generatePDF(int idPredstave,HttpServletResponse)引发异常{
Predstava p=pr.findById(idPredstave.get();
列表uloge=ur.findByPredstava(p);
response.setContentType(“text/html”);
JRBeanCollectionDataSource=新的JRBeanCollectionDataSource(uloge);
InputStream InputStream=this.getClass().getResourceAsStream(“/jasperreports/Uloge.jrxml”);
JasperReport-JasperReport=JasperCompileManager.compileReport(inputStream);
Map params=新的HashMap();
参数put(“nazivPredstave”,p.getNaziv());
参数put(“trajanje”,p.getTrajanje());
参数put(“opis”,p.getOpis());
参数put(“zanr”,p.getZanr().getNaziv());
参数put(“reziser”,p.getReziser().getIme()+”+p.getReziser().getPrezime());
JasperPrint JasperPrint=JasperFillManager.fillReport(jasperReport,参数,数据源);
inputStream.close();
setContentType(“应用程序/x下载”);
addHeader(“内容处置”、“附件;文件名=Uloge.pdf”);
OutputStream out=response.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint,out);
}

帮了我很多忙,我在这里用同样的方法制作了一个示例应用程序,我尝试了XLS的方法#4,效果很好。但是,生成的文件没有扩展名。如何使用方法#4设置文件名以及生成文件的扩展名?@Brice-Ronance:您能帮我吗?我一直在看我的jasperreport@Brice,你能告诉我“REPORT\u VIRTUALIZER”将如何在这里使用吗?谢谢@Brice Roncace的精彩解释。我使用的是方法3,我总是有一个空的pdf。检查日志似乎没有从BeanNameViewResolver:74中找到modelview-找不到与视图名称“blue”匹配的bean。你有什么建议吗?感谢这是在spring mvc项目中使用jasper report的一个示例:
@RequestMapping(value = "helloReport3", method = RequestMethod.GET)
public ModelAndView getRpt3(ModelMap modelMap, ModelAndView modelAndView) {
  modelMap.put("myDataSourceKey", new JREmptyDataSource());
  return new ModelAndView("helloReport3", modelMap);
}
@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;
}
@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;
}
   @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);
}