Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. ---
  2. title: Jasper Reports On Vaadin Sample
  3. order: 11
  4. layout: page
  5. ---
  6. [[jasper-reports-on-vaadin-sample]]
  7. = Jasper reports on Vaadin sample
  8. [[introduction]]
  9. Introduction
  10. ~~~~~~~~~~~~
  11. I meet JasperReports some years ago and I liked this report library;
  12. this year I did need to implement a report on a personal project using
  13. Vaadin, but surprisingly I was not able to found a sample of this, so I
  14. did this little sample and article.
  15. First, you will need a JDK Maven and Mysql in order to try the sample,
  16. and you can download the code here:
  17. http://sourceforge.net/projects/jrtutorial/files/VaadinJRSample/
  18. There is a README.txt file you can follow in order to run the sample,
  19. basically you need to:
  20. 1. Create database running resources/database.sql on Mysql or MariaDB
  21. 2. Compile the entire project: run "mvn install”.
  22. 3. Deploy the application in Jetty: run "mvn jetty:run"
  23. 4. Go to http://localhost:8080/  in your browser
  24. [[implementation]]
  25. Implementation
  26. ~~~~~~~~~~~~~~
  27. Let’s see the sample code step by step. +
  28. The data is only a _person_ table with some data. +
  29. The main class _MyUI.java_ has two UI components (the report generating
  30. button and a list component used to show current data in database.):
  31. [source,java]
  32. ....
  33. final Button reportGeneratorButton = new Button("Generate report");
  34. layout.addComponent(reportGeneratorButton);
  35. layout.addComponent(new PersonList());
  36. ....
  37. The list is implemented on _PersonList.java_, I am using a
  38. _FilteringTable_ (https://vaadin.com/directory/component/filteringtable),
  39. that loads the data using a Vaadin _SQLContainer_:
  40. [source,java]
  41. ....
  42. SQLContainer container=null;
  43. TableQuery tq = new TableQuery("person", new ConnectionUtil().getJDBCConnectionPool());
  44. container = new SQLContainer(tq);
  45. filterTable = buildPagedTable(container);
  46. ....
  47. And the _SQLContainer_ is provided with a _JDBCConnectionPool_ created
  48. from a properties file (_resources/database.properties_):
  49. [source,java]
  50. ....
  51. Properties prop=PropertiesUtil.getProperties();
  52. public JDBCConnectionPool getJDBCConnectionPool(){
  53. JDBCConnectionPool pool = null;
  54. try {
  55. pool = new SimpleJDBCConnectionPool(
  56. prop.getProperty("database.driver"),
  57. prop.getProperty("database.url"),
  58. prop.getProperty("database.userName"),
  59. prop.getProperty("database.password"));
  60. } catch (SQLException e) {
  61. e.printStackTrace();
  62. }
  63. return pool;
  64. ....
  65. The report generation is implemented on _ReportGenerator_ class, this
  66. class loads the report template:
  67. [source,java]
  68. ....
  69. File templateFile=new File(templatePath);       
  70. JasperDesign jasperDesign = JRXmlLoader.load(templateFile);
  71. ....
  72. Compile report template:
  73. [source,java]
  74. ....
  75. jasperReport = JasperCompileManager.compileReport(jasperDesign);
  76. ....
  77. Fill report with data:
  78. [source,java]
  79. ....
  80. HashMap fillParameters=new HashMap();       
  81. JasperPrint jasperPrint = JasperFillManager.fillReport(   
  82. jasperReport,                   
  83. fillParameters,                   
  84. conn);
  85. ....
  86. Export the _jasperPrint_ object to Pdf format:
  87. [source,java]
  88. ....
  89. JRPdfExporter exporter = new JRPdfExporter();
  90. exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
  91. exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(outputStream));
  92. exporter.exportReport();
  93. ....
  94. And finally execute all the logic to generate the report and sent it to
  95. an _OutputStream_:
  96. [source,java]
  97. ....
  98. JasperDesign jasperDesign=loadTemplate(templatePath);
  99. setTempDirectory(templatePath);       
  100. JasperReport jasperReport=compileReport(jasperDesign);       
  101. JasperPrint jasperPrint=fillReport(jasperReport, conn);       
  102. exportReportToPdf(jasperPrint, outputStream);
  103. ....
  104. But all the logic at _ReportGenerator.java_ is called from the
  105. _ReportUtil_ class, this class is the responsible to connect Vaadin
  106. layer with _ReportGenerator_ layer. There are two methods: the first one
  107. is _prepareForPdfReport_, this method creates a database connection,
  108. generates the report as a StreamResource (calling the another method)
  109. and finally extends the source button with a _FileDownloader_ component
  110. in order to upload the generated report stream, so all the uploading
  111. magic is done by _FileDownloader_ extension
  112. (https://vaadin.com/api/com/vaadin/server/FileDownloader.html):
  113. [source,java]
  114. ....
  115. Connection conn=new ConnectionUtil().getSQLConnection();
  116. reportOutputFilename+=("_"+getDateAsString()+".pdf");       
  117. StreamResource myResource =createPdfResource(conn,reportTemplate,reportOutputFilename);       
  118. FileDownloader fileDownloader = new FileDownloader(myResource);       
  119. fileDownloader.extend(buttonToExtend);
  120. ....
  121. The second method _createPdfResource_, uses _ReportGenerator_ class in
  122. order to return the generated report as a _StreamResource_:
  123. [source,java]
  124. ....
  125. return new StreamResource(new StreamResource.StreamSource() {
  126. @Override
  127. public InputStream getStream () {
  128. ByteArrayOutputStream pdfBuffer = new ByteArrayOutputStream();
  129. ReportGenerator reportGenerator=new ReportGenerator();
  130. try {
  131. reportGenerator.executeReport(baseReportsPath+templatePath, conn, pdfBuffer);
  132. } catch (JRException e) {
  133. e.printStackTrace();
  134. }
  135. return new ByteArrayInputStream(
  136. pdfBuffer.toByteArray());
  137. }
  138. }, reportFileName);
  139. ....
  140. So, in order to call the report generator process when only need to call
  141. ReportUtil like we did in ‘MyUI.java’:
  142. [source,java]
  143. ....
  144. final Button reportGeneratorButton = new Button("Generate report");
  145. new ReportsUtil().prepareForPdfReport("/reports/PersonListReport.jrxml",               
  146. "PersonList",               
  147. reportGeneratorButton);
  148. ....
  149. Finally, the jasper report design can be found in the
  150. _WEB-INF/personListReport.jrxml_ file
  151. This is a picture of the sample running and the generated report:
  152. image:img/VaadinJasperReportsSample_small.jpg[Running sample]
  153. And that’s all, I expect to help someone with this sample, thanks for
  154. reading.