We’re adding XML datasources for reports in RightsPro (currently JasperReports is supported) and needed to embed the image data directly in the XML so thought I’d expand on the solution I found here.
If your creating your XML dynamically using Java you can do:
...
import org.apache.commons.codec.binary.Base64;
// Read the byte array from DB or whatever
byte[] imageByteArray = getImageByteArray();
String base64Image = Base64.encodeBase64String(imageByteArray);
...
then write the Base64 encoded data in your XML as:
...
<image><![CDATA[ ... Base64 mess here ... ]]></image>
...
The rest comes from this JasperForge forum post which explains how to decode the Base64 into a ByteArrayInputStream
that’s usable by the JasperReports image report element.
As the post says, in your JasperReport (we currently use iReport as a report editor) define a String field, let’s call it Image
, for the image:
then define a variable, let’s call it ImageBytes
, which uses that field:
with the Variable Expression:
new ByteArrayInputStream(new Base64().decodeBase64($F{Image}.getBytes("UTF-8")))
(don’t forget to add org.apache.commons.codec.binary.Base64
to the imports of the report properties)
and in the image element on your layout use the ImageBytes variable:
and you should see your image properly rendered in the final report.
However, what I found at this point is that while the images displayed fine in iReport in PDF preview most PDF readers were unable to display the images, resulting in just a black rectangle.
The solution was to change the ImageBytes
variable class to java.awt.Image
with a constructor of:
ImageIO.read(new ByteArrayInputStream(new Base64().decodeBase64($F{Image}.getBytes("UTF-8"))))
then change the expression class of the image element on the layout to java.awt.Image
as well. You’ll also have to add javax.imageio.ImageIO
to the imports of the report.
This technique can be useful when you need to grab the image data dynamically (not from actual files on the filesystem), you can’t get each image from a URL (perhaps due to security constraints), and don’t want to use a custom Java datasource.
Can you please tell us how did you import the Base64 class for the report?
I’m also trying to import a third party library class file to be used in a variable expression and even if the .jrxml has the proper import statement and the .jar file containing this third party class is copied to [JasperSoft\iReport-4.0.1\ireport\lib], i still cannot use the third party class. I get an error while trying to compile the report with iReport – [some third party class] cannot be resolved.
Thank you
Hi Linu,
It sounds like there may be a classpath problem.
I haven’t used iReport 4 yet but in 3.7 I did not have to add jar files to iReports environment. I like to keep application instances (like iReport) as generic as possible to ease upgrades and collaboration.
In the import properties for the report I do have the Apache commons’ Base64 as an entry along with ImageIO and others, and in the application properties classpath I have a reference to my project’s config files, but not the jars, so I’m guessing I happen to have the Apache commons jar somewhere else on my default classpath.
I would suggest placing your needed jar somewhere other than inside iReport and add a classpath entry in the iReport application properties pointing to that, then double check that the report’s import entries are correct.