/src/main/scala/org/example/web/report/jasper/JasperReportGenerator.scala

https://github.com/hao0111/spring-mvc-jasper · Scala · 146 lines · 57 code · 16 blank · 73 comment · 0 complexity · df6af45102b6eeffa86e7c4a269b963e MD5 · raw file

  1. package org.example.web.report.jasper
  2. import java.io.OutputStream
  3. import java.util.Collection
  4. import java.util.HashMap
  5. import javax.servlet.http.HttpServletRequest
  6. import javax.servlet.http.HttpServletResponse
  7. import net.sf.jasperreports.engine.JRExporter
  8. import net.sf.jasperreports.engine.JRExporterParameter
  9. import net.sf.jasperreports.engine.JasperCompileManager
  10. import net.sf.jasperreports.engine.JasperFillManager
  11. import net.sf.jasperreports.engine.JasperPrint
  12. import net.sf.jasperreports.engine.JasperReport
  13. import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
  14. import net.sf.jasperreports.engine.export.JRHtmlExporter
  15. import net.sf.jasperreports.engine.export.JRHtmlExporterParameter
  16. import net.sf.jasperreports.engine.export.JRPdfExporter
  17. import net.sf.jasperreports.engine.export.JRXlsExporter
  18. import net.sf.jasperreports.j2ee.servlets.BaseHttpServlet
  19. object JasperReportGenerator {
  20. /**
  21. * Generates an Excel report using a specified report template and a
  22. * bean-collection data source for the report.
  23. *
  24. * @param reportPath Path to the JRXML file to use for generating the
  25. * report.
  26. * @param dataSource A {@link Collection} of objects to use as the
  27. * data source for the report.
  28. * @param response The {@link HttpServletResponse} to which the report
  29. * should be written.
  30. */
  31. def generateExcel(reportPath: String, dataSource: Collection[_], response: HttpServletResponse) {
  32. this.generate(reportPath, dataSource, new JRXlsExporter, None, response, Some("application/vnd.ms-excel"))
  33. }
  34. /**
  35. * Generates an HTML report using a specified report template and a
  36. * bean-collection data source for the report.
  37. *
  38. * @param reportPath Path to the JRXML file to use for generating the
  39. * report.
  40. * @param dataSource A {@link Collection} of objects to use as the
  41. * data source for the report.
  42. * @param request The current {@link HttpServletRequest}.
  43. * @param response The {@link HttpServletResponse} to which the report
  44. * should be written.
  45. */
  46. def generateHTML(reportPath: String, dataSource: Collection[_], request: HttpServletRequest, response: HttpServletResponse) {
  47. this.generate(reportPath, dataSource, new JRHtmlExporter, Some(request), response)
  48. }
  49. /**
  50. * Generates a PDF report using a specified report template and a
  51. * bean-collection data source for the report.
  52. *
  53. * @param reportPath Path to the JRXML file to use for generating the
  54. * report.
  55. * @param dataSource A {@link Collection} of objects to use as the
  56. * data source for the report.
  57. * @param response The {@link HttpServletResponse} to which the report
  58. * should be written.
  59. */
  60. def generatePDF(reportPath: String, dataSource: Collection[_], response: HttpServletResponse) {
  61. this.generate(reportPath, dataSource, new JRPdfExporter, None, response, Some("application/pdf"))
  62. }
  63. /**
  64. * Generates a compiled report using a specified report template and a
  65. * collection data source for the report.
  66. *
  67. * @param reportPath Path to the JRXML file to use for generating the
  68. * report.
  69. * @param dataSource A {@link Collection} of objects to use as the
  70. * data source for the report.
  71. * @param exporter A {@link JRExporter} to use to generate the report.
  72. * @param request The current {@link HttpServletRequest}.
  73. * @param response The {@link HttpServletResponse} to which the report
  74. * should be written.
  75. * @param contentType The HTTP response content type for the report.
  76. */
  77. private def generate(reportPath: String, dataSource: Collection[_], exporter: JRExporter, request: Option[HttpServletRequest], response: HttpServletResponse, contentType: Option[String] = None) {
  78. val output = response.getOutputStream
  79. try {
  80. this.prepare(this.print(JasperCompileManager.compileReport(this.load(reportPath)), dataSource), exporter, request, output)
  81. exporter.exportReport()
  82. contentType match {
  83. case Some(s) => response.setContentType(s)
  84. case _ =>
  85. }
  86. output.flush()
  87. } finally {
  88. output.close()
  89. }
  90. }
  91. /**
  92. * Loads a JRXML report template.
  93. *
  94. * @param reportPath Path to the JRXML file to load.
  95. * @return An {@link InputStream} that can be used to read the JRXML
  96. * report template.
  97. */
  98. private def load(reportPath: String) = this.getClass.getClassLoader.getResourceAsStream(reportPath)
  99. /**
  100. * Prepares to generate a report.
  101. *
  102. * @param print The report to prepare
  103. * @param exporter The exporter to use.
  104. * @param request The current {@link HttpServletRequest}.
  105. * @param output The {@link OutputStream} to which the report must be written.
  106. */
  107. private def prepare(print: JasperPrint, exporter: JRExporter, request: Option[HttpServletRequest], output: OutputStream) {
  108. request match {
  109. case Some(request) =>
  110. // Add the compiled report to the HTTP Session because any graphics
  111. // embedded in the report are generated by a Servlet that is invoked
  112. // after the web page has been rendered.
  113. request.getSession.setAttribute(BaseHttpServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, print)
  114. case None =>
  115. }
  116. exporter.setParameter(JRExporterParameter.JASPER_PRINT, print)
  117. exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, output)
  118. exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "/report/graphics?image=")
  119. exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, false)
  120. exporter.exportReport()
  121. }
  122. /**
  123. * Merges a compiled report with data.
  124. *
  125. * @param report The compiled report to merge.
  126. * @param dataSource A {@link Collection} of objects to merge.
  127. * @return A {@link JasperPrint}.
  128. */
  129. private def print(report: JasperReport, dataSource: Collection[_]) = JasperFillManager.fillReport(report, new HashMap[String, Object], new JRBeanCollectionDataSource(dataSource))
  130. }