当前位置: 首页 > 面试题库 >

如何在Spring MVC中使用JasperReports?

壤驷穆冉
2023-03-14
问题内容

我一直在研究将JasperReports(6.0.0)与Spring
MVC(4.1.3)结合使用以生成PDF报告。Spring充斥着与JasperReports集成以生成PDF的“特定于Spring”的方式:

  • 使用 依赖于现已弃用的JasperReport功能JasperReportsPdfView __
  • 采用 JasperReportsMultiFormatView
  • 采用 JasperReportsViewResolver

我很难在网上找到好的完整示例,并想分享我的发现。

随意添加与“如何将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);
  }

方法2:将JasperReportPdf视图注入控制器

鉴于JasperReportsPdfView bean:

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

该视图可以注入或连接到Controller中以供使用:

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

请注意,使用JasperReportsPdfView(或更通用JasperReportsMultiFormatView)需要依赖spring-
context-support:

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

方法3:使用XML或ResourceBundle视图解析器将逻辑视图名称映射到JasperReport视图

配置一个新的视图解析器,在这种情况下,ResourceBundleViewResolver将在之前运行InternalResourceViewResolver。这基于设置的订单值(0发生在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;
}

然后,在我们的类路径的根目录下,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

配置零序JasperReportViewResolver,技巧是setViewNames用来告诉Spring您希望此解析器处理的逻辑视图名称(否则,您将得到“无法从类路径资源[jasperreports
/ index.jasper]加载JasperReports报告”类型错误):

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

这是我的首选方法。控制器以与使用jsp视图解析方式非常相似的方式解析jasper报告,InternalResourceViewResolver因此,与上述方法3中的xml或properties文件方法一样,不需要显式映射文件。

编辑

提及的JavadocsJasperReportsPdfView使用不推荐使用的JRExporterAPI。是否有更好的(较新的)JasperReports视图可以使用?也许选择s
JasperReportsMultiFormatView是更好的选择,因为它似乎没有使用JRExporter



 类似资料:
  • 我试图测试我的Spring MVC控制器,但我不断收到与Thymeleaf模板相关的错误。我真的不想在控制器测试中处理模板错误,因为这不是我真正感兴趣的。当模板不存在时让测试失败是可以的,但现在我收到了与根据错误代码找不到消息相关的错误。 当我运行应用程序时,这个问题不存在。我一直在尝试弄清楚如何设置测试环境来解决这个问题,但在那里我找不到任何有效的方法。现在,我只是真的想让控制器代码正常工作。

  • 我试图在我的应用程序中实现jpa 发展能力 所以,我的DataConfig看起来像这样: 但是,当我尝试启动应用程序时,会出现错误消息。制造战争- 已连接到服务器[2018-09-26 09:54:32631]工件未命名:正在部署工件,请稍候。。。2018年9月26日09:54:34.460警告[RMI TCP连接(3)-127.0.0.1]组织。阿帕奇。公猫dbcp。dbcp2。基本资源工厂。g

  • 问题内容: 我在SpringMVC项目中将新的Java API(JSR 353)用于JSON。 这个想法是生成一些Json数据并将其返回给客户端。我所拥有的控制器看起来像这样: 当我访问它时,我没有得到JSON的预期表示,而是得到了这些: 为什么是这样?到底是怎么回事?以及如何使其正确返回预期的JSON? 问题答案: 当您意识到新的JSR 353 API 没有特殊要求时,答案很简单。相反,在这种情

  • 我怎么能访问变量我添加到模型中的Spring MVC内胸腺模板?我有以下控制器代码: 如何访问thymeleaf模板中的变量var1、var5、var6等?

  • 我想使用@SessionAttributes注释在SpringMVC中的两个控制器之间共享会话属性。 下面是我用来测试属性共享的一个简单代码:AController。JAVA a.jsp BController.java b.jsp 我期望的行为是转到 /aURL,myParam将被设置为0到99之间的随机值,然后该值将在两个控制器之间共享。 但是,会发生以下情况:我转到/a URL,myPara

  • 我试图创建一个springmvc项目配置与Hibernate使用web.xml 我的问题是,当我运行时,它不会自动创建用户表。 这是我的代码: 文件spring-config.xml 文件web.xml: 文件UserDAO: 文件UserDaoImpl: 文件用户: 这是我的日志:

  • 本文向大家介绍SpringMVC @ControllerAdvice使用场景,包括了SpringMVC @ControllerAdvice使用场景的使用技巧和注意事项,需要的朋友参考一下 这篇文章主要介绍了SpringMVC @ControllerAdvice使用场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 @ControllerAdvic

  • 对于字段绑定,我需要指向JSP中特定键的ArrayList的第I项。我怎么做?这种双括号表示法行得通吗?假设'key'和'index'是JSP中已知的JSTL变量。