*** Note from the Editor(Joerg) ***
This is the first of (hopefully) lots of articles written by vcoportal’s very own student intern, Tobias.
Not to get him too bored 😈 , his task was to cover multiple topics in one article:
- How to create PDF-files in WaveMaker, using JasperReports
- How to “import” a WaveMaker JavaService into Eclipse
- How to use the iReport Designer to create report templates
- How to show the resulting PDF as preview in Web-UI
At the end of the Article you will find the exported WaveMaker project to download and referencing links to the external libraries, so that you can reproduce and expand the examples…
As usual, any comments are very welcome! (Just remember: It’s our intern’s first article, so please don’t be too rude 😎 )
***Here we go***
Preparations
Create a new project in WaveMaker without using any template
Now you have to do some small changes in your project’s folder
Go to …projects\yourProjectName\webroot and create a folder called “printtemp” (in which the created pdf-files will be stored)
Go to …\projects\yourProjectName\lib and put the following jar-files in there (see the origins in the References below)
Open up WaveMaker and create a new Java Service
Now you should see the Java code which was automatically created by WaveMaker. I deleted the comments and the sample method.
Go to your canvas and add a button, a text editor and an iFrame. Arrange those widgets just as you like.
Import WaveMaker JavaService to Eclipse
Time to do some programming… Open Eclipse and create a new Java Project. The Project’s name has to be the same one as you have used for your WaveMaker project. In addition, you have to choose your WaveMaker project’s directory as the location:
In order to avoid later errors inside your code (or at least: Eclipse not to find some classes of the WaveMaker core), you have to add an additional library to your Java project:
Right-click on your project folder which is shown in the upper-left corner inside your package explorer and choose “Properties”
Choose the property “Java Build Path” and the tab “Libraries”. Now you can add external JAR’s
You have to navigate to WaveMaker’s installation directory, which’s subfolder \launcher\lib contains “servlet-api-2.5.jar”
If everything was done right, the package explorer should show your WaveMaker project’s directories.
Now you can open the java file and type your code (or ours ;))
Please notice: You are now accessing the jave file both with Eclipse AND WaveMaker. After you made changes on the code, you have to press the refresh button and save it.
Create the PDF-File using JasperReports
Please notice that the fileName in line 63 has to be the name of the jasper template we will create. To keep the example easy, we also hardcode the relative subpath in which the pdf-files are created (here: “printtemp”), remember that this has to exist in your WaveMaker project’s webapp-root (see above).
package com.vcoportal; import com.wavemaker.runtime.RuntimeAccess; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Vector; import java.net.URL; import java.io.*; import net.sf.jasperreports.engine.JRExporterParameter; import net.sf.jasperreports.engine.JasperFillManager; import net.sf.jasperreports.engine.JasperPrint; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import net.sf.jasperreports.engine.export.JRPdfExporter; import net.sf.jasperreports.engine.util.JRLoader; public class ReportGenerator extends com.wavemaker.runtime.javaservice.JavaServiceSuperClass { public ReportGenerator() { super(INFO); } // some attributes holding the data private String titleText; private String subTitle; // getters & setters public String getTitleText() { return this.titleText; } public String getSubTitle() { return this.subTitle; } public void setTitleText(String ttext) { this.titleText = ttext; } public void setSubTitle(String stitle) { this.subTitle = stitle; } // a static method that initializes, stores and returns our data public static Collection<ReportGenerator> getData() { Vector<ReportGenerator> theData = new Vector<ReportGenerator>(); ReportGenerator myReportGen = new ReportGenerator(); myReportGen.setTitleText("Hello World!"); myReportGen.setSubTitle("This is a subtitle!"); theData.add(myReportGen); return theData; } // this is where the magic happens... public String printReport() { String fileName = "report.jasper"; String typeDocument = "PDF"; URL fileUrl = this.getClass().getResource(fileName); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put("just", new String("testing")); JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(this.getData()); try { JasperReport report = (JasperReport) JRLoader.loadObject(fileUrl); JasperPrint jasperPrint = JasperFillManager.fillReport(report, parameters, ds); String pathWR = RuntimeAccess.getInstance().getSession().getServletContext().getRealPath("/printtemp/"); File tempDir = new File(pathWR); String tempFileName = new String(); if (typeDocument.equals("PDF")) { File tempFile = File.createTempFile("tempReport", ".pdf", tempDir); tempFile.deleteOnExit(); tempFileName = tempFile.getName(); JRPdfExporter exporter = new JRPdfExporter(); exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint); exporter.setParameter(JRExporterParameter.OUTPUT_FILE_NAME, tempDir + "/" + tempFileName); exporter.exportReport(); } return "printtemp/" + tempFileName; } catch (Exception e) { log(ERROR, "Error in printReport(): " + e); return ""; } } }
Now we create a very basic jasper template:
Open Jaspersoft iReport Designer, create a new File and open it
For your report, you have to choose the same filename as in your java code. The location has to be the directory of your WaveMaker project’s Java-Service
Now you can add a new field to your template by right-clicking the property “field”. Fields are placeholders for the data we want the PDF to contain
On the lower-right part of the interface you can change the field’s properties. The name has to match the attribute’s name in your code. In my case that’s titleText and subTitle
The field class property has to match the used data type of your attribute.
When you drag your field from the Report Inspector on the left onto your template, a dialog will appear. Just hit OK.
Now you can select your field by clicking on it and change its properties
Create a second field for the attribute “subTitle” and your template could look just as spectacular as this…
By pressing the Preview-Button your template will be compiled and the .jasper-file will be created
Wire the JavaService to the Web-UI
Ok, just a few steps left to do…
Bring up WaveMaker again and create a new Service Variable that will use our Java Service
Remember the Button? It will call the Service Variable
The text editor will show the path and filename of the created PDF. So you can check the option “readonly” and bind its dataValue to the result of the Service Variable
You have to do bind the iFrame’s source to the result of the Service Variable too
And finally, it should look like this…
Cleaning up
In this example every time some user hits the button a new pdf-file will be created. This might not be a good idea for a real project (even if the files are “marked” as temp-files in the JavaVM and will be deleted when this closes, not good for a running-forever web-application). So you might include another method in the JavaService that deletes the report (e.g. after printing, or a certain timeframe) not to fill up the printemp-directory…
public void deleteTempPrintFile(String filename) { //delete temp pdf if (filename != null) { try { File toDelete = new File(filename); toDelete.delete(); } catch (Exception e) { log(ERROR, "Error in deleteTempPrintFile(): " + e); } }
References
- http://dev.wavemaker.com/wiki/bin/wmdoc_6.3/JavaServices
- http://dev.wavemaker.com/wiki/bin/Application+Showcase/Reports
- http://dev.wavemaker.com/forums/?q=node/7616
- http://jasperforge.org/projects/jasperreports
- http://jasperforge.org/projects/ireport
- http://commons.apache.org/digester/
- http://itextpdf.com/
- http://poi.apache.org/
- http://poi.apache.org/
Download
Exported from WaveMaker 6.4.6
Tobias,
Meticulously working through the code example using WM6.5.0.M4 and fails to progress at the point of adding a service variable for the java code did error as shown below (within WM when I same the project).
Service Compiled Successfully at 18:34:39
—
1. WARNING in servicesprintServicesrccomvcoportalReportGenerator.java (at line 68)
JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(this.getData());
^^^^^^^^^^^^^^
The static method getData() from the type ReportGenerator should be accessed in a static way
———-
1 problem (1 warning)
As a result, on selecting the service variable under the properties, there is shown the “printService” service but no operations exists as per the notes. The one listed “sampleJavaOperation” doesn’t exist anwyere in the code and I assume a remnant of the operation of adding a java service.
Will appreciate you assistance when you have time.
Regards,
Emma Cox
eomc40@yahoo.co.uk
Ich bin bis 17.09.2012 abwesend.
Sehr geehrte Damen und Herren,
Vielen Dank für Ihre E-Mail. Zur Zeit befinde ich mich nicht im Büro. Ankommende E-Mails werden während meiner Abwesenheit nicht weitergeleitet, aber sofort nach meiner Rückkehr beantwortet.
In dringenden Fällen können Sie gerne meinen Kollegen Christoph Leygraf ( Tel. +49 15118025121; christoph.leygraf@sva.de) oder Andreas Ehrenreiter ( Tel. +49 15111359466; andreas.ehrenreiter@sva.de) kontaktieren.
Dear Ladies and Gentlemen,
Thank you for your message.I am out of the office.
Your e-mail will not be forwarded, I will answer it as soon as I am back. For urgent matters please contact my colleagues Christoph Leygraf ( Tel. +49 15118025121; christoph.leygraf@sva.de) or Andreas Ehrenreiter ( Tel. +49 15111359466; andreas.ehrenreiter@sva.de).
Mit freundlichen Grüßen – Best regards
Christian Strijbos
Senior IT-Architekt
SVA System Vertrieb Alexander GmbH
Borsigstrasse 14
65205 Wiesbaden, Germany
Mobile: +49 151 18025123
Phone: +49 6122 / 536-0
Fax.: +49 6122 / 536-399
E-Mail: christian.strijbos@sva.de
http://www.sva.de
Geschäftsführung: Felix Alexander, Philipp Alexander, Sven Eichelbaum Sitz der Gesellschaft: Wiesbaden
Registergericht: Amtsgericht Wiesbaden, HRB 10315
Hinweis: Dies ist eine automatische Antwort auf Ihre Nachricht “[vcoportal] Re: Creating PDF in WaveMaker using JasperReports” gesendet am 15.09.2012 19:42:08.
Diese ist die einzige Benachrichtigung, die Sie empfangen werden, während diese Person abwesend ist.
Tobias,
An update: earlier text indicated WM6.5.0M4, but meant WM6.5.0M3
Went ahead and imported the project into WM6.5.0M3 and worked fine. Will comb through my code again and see where I went wrong. New to Java so that will be some task in itself.
Of the shown example, the two fields are hard coded values within the java script. How would I pass values between WM objects to the code to be printed instead of the default “Hello World” and “This is a subtitle”?
Please advice on the lines of variables, local to a page or global of the application and how that data can be passed….
Kind Regards,
Emma Cox
eomc40@yahoo.co.uk
Hi!
thanks for your comments, we developed the example on latest stable release of WM 6.4.
To pass information from the UI to a JavaService you have to change the methods getData() and printReport() and add parameters.
E.g. public String printReport(String theString) { …..
When you save/compli/reload the JavaService in the Wavemaker GUI again, and re-create the service-variable for that JavaService, you should be able to bind the inputs, for instance to a text-editor.
There is a screencast on http://www.wavemaker.com/product/screencasts.html which gives you a good introduction in JavaServices in WaveMaker.
Cheers,
Joerg
I strictly followed this tutorial step by step twice. First I got “The static method getData() from the type ReportGenerator should be accessed in a static way” in eclipse. Then I downloaded the project, imported and run; surprisingly it works. Then I went back to my project and made the following change. I made getDate() non-static, saved the changes and run. My project works then.
I appreciate the author of the article. I spent a week trying to integrate a report generated by JasperReport/iReport in wavemaker.
Thank you Joerg
Glad to hear that it helped you! Kudos go to Tobias, our student intern, who spend a week to put it all together 🙂
Cheers,
Joerg
The following code may be used for clean up purpose
public void DeleteFiles(String folder){
File file = new File(folder);
String[] myFiles;
if(file.isDirectory()){
myFiles = file.list();
for (int i=0; i<myFiles.length; i++) {
File myFile = new File(file, myFiles[i]);
myFile.delete();
}
}
}
Sorry, the code is here
http://www.coderanch.com/t/378308/java/java/delete-all-existing-files-dierectry
That is helpful! Thanks for sharing!
Hi Tobias, Jeorg,
I am a newbie on java – (have not worked on java for the last 13 years)
Thanks for the helpful article here.
Tobias, you have mentioned the following
quote————————–
Go to …projectsyourProjectNamelib and put the following jar-files in there (see the origins in the References below
Unquote————————–
those reference refer to the following files
1. commons-digester-1.7.jar
2. groovy-all-1.8.6.jar
3. iText-2.1.7.jar
4. jasperreports-4.6.0.jar
5. jasperreports-extensions-3.5.3.jar
6. jasperreports-fonts.4.6.0.jar
7. poi-3.5-FlNAL-20090928.jar
I have not been able to find a single source to copy these files on your site – or did I miss out something. Can I copy them from wherever I can find it on the net?
Pls let me know. I have managed to club together a wavemaker app. generated a jasper report comprising of a jrxml file. I am trying to generate the report (of the .jrxml file) from the wavemaker application.
Pls advice. Thanks in advance.
Hi!
The easiest way would be to download our sample project. You will find all the jar-files in the project’s lib folder.
But of course, you could also download those files from any (trusted) source 😉
Sample project:
http://www.vcoportal.de/download/workflow/ExampleReport.1.Alpha1.zip
I did find the files on my machine – since I had downloaded some app from your site.
The current issue that I am facing is as follows.
the Eclipse Platform that I am using is Version: 3.3.2 with Build id: M20080221-1800.
the step – “Import WaveMaker JavaService to Eclipse”
I am unable to do the following, as the GUI does not permit me to do the same
quote
… Open Eclipse and create a new Java Project. The Project’s name has to be the same one as you have used for your WaveMaker project. In addition, you have to choose your WaveMaker project’s directory as the location:
unquote
Would you pls take a look and let me know.
Thanks
Try:
File –> New –> Java Project.
Enter your Wavemaker project’s name.
Click on the radio button “Create project from existing source”.
Browse to your Wavemaker project’s path: …/projects/yourProject and click OK.
Click finish.
I am successfully able to integrate iReport into wavemaker. However, when the report contains non-english font the integration fails with the following error.
Error in printReport(): net.sf.jasperreports.engine.JRRuntimeException: Could not load the following font :
pdfFontName : jiret.ttf
pdfEncoding : Identity-H
isPdfEmbedded : true
printReport(): is the function that prints the report
I tried many suggestions from forums but non worked. Please help me
Hi! Try to put the font file into the resources folder of your wavemaker project, to make sure they get exported/deployed properly. Than you can refer to them from your report, like described here: http://zarathustrashallspeak.com/2008/08/27/jasperreports-tomcat-and-fonts/
Cheers,
Joerg
Thank you!
Hey Guys very new to Wavemaker but I am catching on..or so I thought until i received the same error as Antoni.
—
1. WARNING in servicesprintServicesrccomvcoportalReportGenerator.java (at line 69)
JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(this.getData());
^^^^^^^^^^^^^^
The static method getData() from the type ReportGenerator should be accessed in a static way
———-
1 problem (1 warning)
As well as this matching error in Eclipse
Description Resource Path Location Type
The static method getData() from the type ReportGenerator should be accessed in a static way ReportGenerator.java /Project1/services/printService/src/com/vcoportal line 69 Java Problem
Not really sure what to do…I have searched high and low.
Thanks so much!
Which version of WaveMaker are you using? The examples has been done on 6.4, the might not work in the same way on newer versions of WaveMaker…
Cheers,
Joerg
Great post helps heaps!
I have followed all the steps, it successfully generates reports, but in my case the reports I am trying to generate use SQL Queries, so at this point, the reports are coming out with the all text fields, and parameters set correctly. The SQL Stored procedure does not seem to be getting called to fill the report.
I am using WaveMaker 6.5.2 and iReport 4.7 Pro (I know this article is for an older version of WM, but there might be someone who can help)
Thank you for any help!
hm, hard to tell without seeing the code. First step: Try to make it run in the iReport Designer, if you want to call the SQL Stored Procedures directly.
As an alternative you can call them in the WaveMaker java service, and just transfer the results to the report (as ArrayList for example).
Find information about how to call database queries from the java service on http://dev.wavemaker.com/wiki/bin/view/Dev/Stored+Procedures
and http://dev.wavemaker.com/forums/?q=node/9351
Confirmed working on WaveMaker 6.6.0.M2 after removing the static part of the getData method. Didn’t realize the Eclipse part was optional 😛
Good to know that it works even with the new WaveMaker version! Thanks for sharing!
I am trying to use the code for wavemaker studio 7.5 but I am getting error when save the javaservice. the error read the method getSession() is undefined for the type RunTimeAccess. Any idea how to resolve it? tq
Hi El,
sorry, I have not used the new 7.x version of Wavemaker yet.
The error you receive however seems not to be related to the JasperReports integration in this post, but rather related to the WaveMaker platform itself.
So I recommend to ask in the WaveMaker communities about what changed for custom Java services from 6.x to 7.x…
(Feel free to share the link to the discussion here, too 🙂 )
Joerg
Tq. its due to the new version. we got to add the parameter ‘HttpServletRequest request’ to the printObject definition and then invoke the method as ‘request.getSession()’. we also have to import javax.servlet.http.HttpServletRequest.
Hallo, Ich finde den Aufbau der Seite super. Macht bitte weiter so.
Hallo, Ich finde den Aufbau der Seite klasse. Macht weiter so.