Jump to content
We've recently updated our Privacy Statement, available here ×

Usage of Scriptlets in Dynamic Reports


mekatoka

Recommended Posts

Hello,

 

I have the need to generate dynamic reports and so we create JasperDesign object, fill it and pass on the print object to presentation layer and export to the required format.

 

I am using JFreeChart for chart generation and am unable to set the variable into the JasperDesign object. I am following the samples/jfreechart example and am trying to do the following

 

Code:


JasperDesign designObj = new JasperDesign();

/*** setting the scriptlet class ***/
designObj.setScriptletClass("com.my.pkg.testScriptlet"«»);

/***setting variable (IS THIS CORRECT)***/
JRDesignVariable scritpletVar = new JRDesignVariable();
scritpletVar.setName("Chart"«»);
scriptletVar.setSystemDefined(true);

/*** setting an image to the report ***/
JRDesignImage image = new JRDesignImage(reportDesignObj);
image.setX(0);
image.setY(110);
image.setHeight(300);

image.setScaleImage(JRAlignment.VERTICAL_ALIGN_MIDDLE);
JRDesignExpression expression = new JRDesignExpression();

expression.setValueClass(net.sf.jasperreports.engine.JRRenderable.class);
expression.setText("[$V{Chart}"«»);

image.setExpression(expression);

band.addElement(band);

 

I am using the same scriptlet class present in samples and when I try to compile I get the error that it is not able to find the variable called Chart.

 

Questions

 

What is the right way to set a variable when using dynamic reports (using JasperDesign object) ?

 

The documentation says that scriptlets are executed after, before ... initializations of report based on implementation. In case of dynamic reports when is a report initialized?

Link to comment
Share on other sites

  • Replies 13
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Thanks for the reply.

 

I have that statement in the code and the scriptlet class is never called (I have debug statements in there).

 

Now when I use the following statement

 

expression.setText("[$V{Chart}");

 

I get an error

 

Code:

net.sf.jasperreports.engine.JRException: Report design not valid :
1. Variable not found : Chart
at net.sf.jasperreports.engine.design.JRAbstractCompiler.verifyDesign(JRAbstractCompiler.java:267)
at net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:144)
at net.sf.jasperreports.engine.design.JRDefaultCompiler.compileReport(JRDefaultCompiler.java:105)
at net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager.java:211)

 

 

When I use the statement

 

expression.setText("Chart");

 

I get the following error

 

 

Code:
[code]
net.sf.jasperreports.engine.JRException: Errors were encountered when compiling report expressions class file:
1. Chart cannot be resolved
value = (net.sf.jasperreports.engine.JRRenderable)(Chart);
<----->
2. Chart cannot be resolved
value = (net.sf.jasperreports.engine.JRRenderable)(Chart);
<----->
3. Chart cannot be resolved
value = (net.sf.jasperreports.engine.JRRenderable)(Chart);
<----->
3 errors

at net.sf.jasperreports.engine.design.JRAbstractCompiler.compileReport(JRAbstractCompiler.java:193)
at net.sf.jasperreports.engine.design.JRDefaultCompiler.compileReport(JRDefaultCompiler.java:105)
at net.sf.jasperreports.engine.JasperCompileManager.compileReport(JasperCompileManager.java:211)

 

 

My question in the original post still stays. In case of dynamic reports when is the scritplet class called? Is it just when rendering the report or after compiling or after verifying?

 

Thanks

Mekatoka

Link to comment
Share on other sites

Hmm, that would then cause a problem.

Please read the following sequence

 

In case of dynamic reports

 

(1) I create a DesignObject

(2) Compile it to get a JasperReport object

(3) Fill the JasperReport object from step 2 to get the JasperPrint object

 

Based on what you said Scriptlet class is only called at Step 3, but step 2 fails in report compilation as the variable still does not have a value in it?

 

Please point in the right direction

 

Thanks

Mekatoka

Link to comment
Share on other sites

I have the code but I would rather not post the it here but I can send it via email or IM.

 

As posted in my reply (2007/04/05 14:22) I get the errors stated in that post . The report compiles and displays fine without that variable.

 

Here is something for more detail

 

Code:

JRDesignImage image = new JRDesignImage(reportDesignObj);
image.setX(0);
image.setY(50);
image.setHeight(450);
image.setWidth(1050);
image.setScaleImage(JRAlignment.VERTICAL_ALIGN_MIDDLE);
JRDesignExpression expression = new JRDesignExpression();
expression.setValueClass(net.sf.jasperreports.engine.JRRenderable.class);
expression.setText("[$V{Chart}"«»);
/** expression.setText("Chart"«»); **/
image.setExpression(expression);
image.setLazy(true);

 

What is the correct way to use setText() on the image

 

Code:
[code]
expression.setText("[$V{Chart}"«»);

OR

expression.setText("Chart"«»);

 

Thanks

Mekatoka

Link to comment
Share on other sites

The correct expression text is (note that there is no [)

Code:
expression.setText("$V{Chart}"«»);

 

However, this is not the cause of the "no such variable" exception. Without seeing the full code/replicating the error I can only guess what might cause the error, and we can play the guessing game for hours without reaching a resolution.

 

So, my first guess: are compiling the JasperDesign object directly or are you serializing it first as JRXML and then compiling the JRXML? If you are going through JRXML, drop the scriptletVar.setSystemDefined(true); line as this would skip the variable when writing the JRXML.

 

Regards,

Lucian

Link to comment
Share on other sites

Thanks for being patient. I appreciate that.

 

I concur with you. I think I need to send the code to you rather than playing the guessing game but like I said I would like to email it to you.

 

Is there anywhere I can email?

 

To answer your earlier questions,

 

(1) I am not saving the report to jrxml

(2) I compile the design object, fill it to get a jasperprint, use a htmlexporter and store output to a string and then set it in an object thats made availalble to the jsp

(3) the string is just displayed at the right place

 

Thanks

Link to comment
Share on other sites

Ok, I found my mistake and I feel stupid about it. I used more debug statements to see that the scriptlet class was not available in designobject just before compiling and the reason for this was that somewhere in the code the designoject was being reinitialized.

 

Thanks for being patient.

Link to comment
Share on other sites

Hi lucianc,

 

I still haven't been able to get the image displayed and so I have tested multiple times before posting this.

 

To avoid you guessing my problem I have written a small class to test scriptlets and I am posting everything that is relevant so that you don't have to answer multiple times

 

 

 

Code that generates the report

 

Code:

private JasperPrint getReportForImageTesting() {

JasperPrint reportPrintObj = null;

try {

//Setting the scriptlet class
JasperDesign reportDesignObj = new JasperDesign(); reportDesignObj.setScriptletClass("com.mypkg.JFreeChartScriptlet"«»);

//Setting the scriptlet variable
JRDesignVariable scriptletVar = new JRDesignVariable();
scriptletVar.setName("Chart"«»);
scriptletVar.setValueClass(net.sf.jasperreports.engine.JRRenderable.class);
scriptletVar.setSystemDefined(true);
reportDesignObj.addVariable(scriptletVar);
reportDesignObj.setName("Sample Report Name"«»);

JRDesignBand band = new JRDesignBand();
band.setHeight(500);

reportDesignObj.setTitle(band);

//** DYNAMIC IMAGE FROM SCRIPTLET **//
JRDesignImage dynamicImageFromScriptlet = new JRDesignImage(reportDesignObj);
dynamicImageFromScriptlet.setX(0);
dynamicImageFromScriptlet.setY(50);
dynamicImageFromScriptlet.setHeight(300);
dynamicImageFromScriptlet.setWidth(515);
dynamicImageFromScriptlet.setScaleImage(JRImage.SCALE_IMAGE_CLIP);

JRDesignExpression dynamicImageExpression = new JRDesignExpression();
dynamicImageExpression.setValueClass(net.sf.jasperreports.engine.JRRenderable.class);
dynamicImageExpression.setText("$V{Chart}"«»);
dynamicImageFromScriptlet.setExpression(dynamicImageExpression);
band.addElement(dynamicImageFromScriptlet);

//** STATIC IMAGE RESIDING ON LOCAL MACHINE **//
JRDesignImage staticImage = new JRDesignImage(reportDesignObj);
staticImage.setX(0);
staticImage.setY(50);
staticImage.setHeight(300);
staticImage.setWidth(700);
staticImage.setScaleImage(JRImage.SCALE_IMAGE_CLIP);
staticImage.setLazy(true);

JRDesignExpression staticImageExpression = new JRDesignExpression();
staticImageExpression.setValueClass(String.class);
staticImageExpression.setText(""C:/chart.jpg""«»);
staticImage.setExpression(staticImageExpression);

//**Adding both images to the band **//
band.addElement(dynamicImageFromScriptlet);
band.addElement(staticImage);

//Compile the report
JasperReport reportObj = JasperCompileManager.compileReport(reportDesignObj);

//Fill the report
reportPrintObj = JasperFillManager.fillReport(reportObj, null, new JREmptyDataSource());

/** Content in JRXML file of samples/jfreechart directory **/
// <variable name="Chart" class="net.sf.jasperreports.engine.JRRenderable" calculation="System"/>
// <image scaleImage="Clip" hAlign="Center" hyperlinkType="Reference">
// <reportElement x="0" y="110" width="515" height="300"/>
// <graphicElement/>
// <imageExpression class="net.sf.jasperreports.engine.JRRenderable"><![CDATA[$V{Chart}]]></imageExpression>
// <hyperlinkReferenceExpression><![CDATA["http://www.jfree.org/jfreechart"]]></hyperlinkReferenceExpression>
// </image>

} catch (Exception e) {
e.printStackTrace();
}
return reportPrintObj;
}

 

The JasperPrint object returned from above is displayed on the jsp using a html exporter using the following settings

 

Code:
[code]
JRHtmlExporter htmlExporter = new JRHtmlExporter();
htmlExporter.setParameter(JRExporterParameter.JASPER_PRINT, reportPrintObject);
htmlExporter.setParameter(JRExporterParameter.OUTPUT_WRITER, response.getWriter());
htmlExporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, "../image?image="«»);
htmlExporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);
htmlExporter.setParameter(JRHtmlExporterParameter.HTML_HEADER, ""«»);
htmlExporter.setParameter(JRHtmlExporterParameter.HTML_FOOTER, ""«»);

htmlExporter.exportReport();

 

 

Output:

 

The output I get on the jsp shows me the static image but does not show the image generated by the scriptlet (com.mypkg.JFreeChartScriptlet).

 

(Also, com.mypkg.JFreeChartScriptlet is the class that is included in demo samples of jasperreports 1.3.1)

 

Questions

 

Why is the dynamic image not being displayed?

 

 

Thanks

Mekatoka

Post edited by: mekatoka, at: 2007/04/05 22:36

Link to comment
Share on other sites

Good news at last :)

 

I am posting the sequence so that it will help others if they run into similar problem

 

I removed the static image, and dynamic image showed but it was not displaying. The ImageServlet was configured fine but it kept complaining that Jasperprint documents were not available in the session as below

 

Code:

javax.servlet.ServletException: No JasperPrint documents found on the HTTP session.
at net.sf.jasperreports.j2ee.servlets.ImageServlet.service(ImageServlet.java:98)

 

So I added code to set the JasperPrint object into the session in the Jsp and the image displays.

 

Points to Checkpoint

 

(1) Make sure ImageServlet is properly configured in web.xml

(2) Make sure JasperPrint object is available in the session.

 

Finally, thanks Lucianc for helping me with the problem.

 

Thanks

Mekatoka

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...