web-dev-qa-db-ja.com

JasperReportsをSpring MVCで使用する方法

私は、Spring MVC(4.1.3)でJasperReports(6.0.0)を使用してPDFレポートを生成します。Springは、 PDFを生成します。

私はオンラインで良い完全な例を見つけるのに苦労しました、そして、私の発見を共有したかったです( 以下の私の答え を見てください)。

「JasperReportsとSpring4を統合するにはどうすればよいですか」に関連する追加のメソッドや改善を追加してください。

36
Brice Roncace

私の研究に基づいて、次の使用方法を見つけました。これらの方法は、最初の複雑さ/構成を最小限に抑える最も直接的な(単純な)アプローチから始まり、より抽象的になるように進化しますが、Spring /より複雑なSpring構成に依存します。

方法1:コントローラーでJasperReports APIを直接使用する

サーブレットの出力ストリームにコンテンツを書き出すだけです。

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

このビューは、使用するためにコントローラーに挿入または配線できます。

@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ビューにマッピングする

新しいビューリゾルバを構成します。この場合、ResourceBundleViewResolverInternalResourceViewResolverの前に実行します。これは、設定される順序値に基づいています(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);
}

私はこのアプローチが好きです。コントローラは「ダム」のままであり、文字列値のみを処理し、ビューへの名前のマッピングはすべて1つの場所で実行できます。


方法4:JasperReportsViewResolverを使用する

ゼロ順序のJasperReportViewResolverを構成します。トリックはsetViewNamesを使用して、このリゾルバーに処理する論理ビュー名をSpringに伝えます(そうしないと、「クラスからJasperReportsレポートをロードできませんでした」パスリソース[jasperreports/index.jasper] "タイプエラー):

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

これは私の好みのアプローチです。コントローラは、InternalResourceViewResolverを使用してjspビューを解決する方法と非常に似た方法でジャスパーレポートを解決します。したがって、上記の方法#3のxmlまたはプロパティファイルアプローチのように明示的なマッピングファイルは必要ありません。

[〜#〜] edit [〜#〜]

JasperReportsPdfViewのjavadocs は、廃止されたJRExporter AP​​Iを使用することを記載しています。使用するより良い(新しい)JasperReportsビューはありますか?おそらく JasperReportsMultiFormatView を選択するほうが、JRExporterを使用していないように見えるため、より良いオプションです。

75
Brice Roncace