-
Notifications
You must be signed in to change notification settings - Fork 374
ODTReportingJavaMainDynamicImage
Since XDocReport 0.9.1, it's possible to manage dynamic images for ODT document. If you wish manage a dynamic image, you must :
-
design you ODT document to insert dynamic image :
- insert a "template" image (any image).
- set a name (ex: logo) for the image.
- register an instance of fr.opensagres.xdocreport.document.images.IImageProvider in the model context with a name (ex: logo) which is enable to write binary of the image in the generated ODT report.
In this section we will design a ODT document with a "template" dynamic image like this:
[After report generation, the "template" dynamic image
(http://wiki.xdocreport.googlecode.com/git/screenshots/ODTProjectWithVelocityAndImage.png).).
will be replaced with a real logo image :
[to generate this report :
(http://wiki.xdocreport.googlecode.com/git/screenshots/logo.png).).
Insert a template image (ex: [:
(http://wiki.xdocreport.googlecode.com/git/screenshots/template.png))).
and set the image name with logo:
[If you don't know how to do that, please read ODTDesignReport#Manage_Dynamic_Image Manage Dynamic Image) section.
Now we can create a Java Main which will replace the "template" image with the real logo image.
At first you must indicate to XDocReport that the image linked to the image named with logo must be replaced with another image coming from the context. To do that, you must register fields metadata like this:
// Create fields metadata to manage image
FieldsMetadata metadata = new FieldsMetadata();
metadata.addFieldAsImage("logo");
report.setFieldsMetadata(metadata);
Therefore context must be populated with the binary of the image by using an instance of fr.opensagres.xdocreport.document.images.IImageProvider. For example you can do that:
IImageProvider logo = new ClassPathImageProvider(ODTProjectWithVelocityAndImage.class, "logo.png");
context.put("logo", logo);
In this example image is stored in the same package than ODTProjectWithVelocityAndImage class. It exists another implementation of IImageProvider : if you want load image from another mean (like file). Please read IImageProvider section.
Create fr.opensagres.xdocreport.samples.ODTandvelocity.ODTProjectWithVelocityAndImage class like this :
package fr.opensagres.xdocreport.samples.ODTandvelocity;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import fr.opensagres.xdocreport.core.XDocReportException;
import fr.opensagres.xdocreport.document.IXDocReport;
import fr.opensagres.xdocreport.document.images.ClassPathImageProvider;
import fr.opensagres.xdocreport.document.images.IImageProvider;
import fr.opensagres.xdocreport.document.registry.XDocReportRegistry;
import fr.opensagres.xdocreport.samples.ODTandvelocity.model.Project;
import fr.opensagres.xdocreport.template.IContext;
import fr.opensagres.xdocreport.template.TemplateEngineKind;
import fr.opensagres.xdocreport.template.formatter.FieldsMetadata;
public class ODTProjectWithVelocityAndImage {
public static void main(String[args) {
try {
// 1) Load ODT file by filling Velocity template engine and cache
// it to the registry
InputStream in = ODTProjectWithVelocityAndImage.class
.getResourceAsStream("ODTProjectWithVelocityAndImage.ODT");
IXDocReport report = XDocReportRegistry.getRegistry().loadReport(
in, TemplateEngineKind.Velocity);
// 2) Create fields metadata to manage image
FieldsMetadata metadata = new FieldsMetadata();
metadata.addFieldAsImage("logo");
report.setFieldsMetadata(metadata);
// 3) Create context Java model
IContext context = report.createContext();
Project project = new Project("XDocReport");
context.put("project", project);
IImageProvider logo = new ClassPathImageProvider(
ODTProjectWithVelocityAndImage.class, "logo.png");
context.put("logo", logo);
// 4) Generate report by merging Java model with the ODT
OutputStream out = new FileOutputStream(new File(
"ODTProjectWithVelocityAndImage_Out.ODT"));
report.process(context, out);
} catch (IOException e) {
e.printStackTrace();
} catch (XDocReportException e) {
e.printStackTrace();
}
}
}
Run ODTProjectWithVelocityAndImage Java class and ODTProjectWithVelocityAndImage_Out.ODT will be generated in your project home :
(]).
XDocReport provides several implementation of IImageProvider :
**Class** | **Description** |
fr.opensagres.xdocreport.document.images.**ClassPathImageProvider** | Implementation which load binary image from classpath of the given Class. |
fr.opensagres.xdocreport.document.images.**FileImageProvider** | Implementation which load binary image from a file. |
fr.opensagres.xdocreport.document.images.**ByteArrayImageProvider** | Implementation which load binary image from byte array or input stream. This implementation is This provider is useful when image content can change by calling ByteArrayImageProvider#setImageByteArray(byte[ByteArrayImageProvider#setImageStream(InputStream)). |
Here a sample to load image "logo.png" stored in the package of the class ODTProjectWithVelocityAndImage :
IImageProvider logo = new ClassPathImageProvider(ODTProjectWithVelocityAndImage.class, "logo.png");
context.put("logo", logo);
You can find samples with ClassPathImageProvider with Freemarker in the http://code.google.com/p/xdocreport/source/browse/samples/fr.opensagres.xdocreport.samples.odtandfreemarker/src/fr/opensagres/xdocreport/samples/odtandfreemarker/ODTProjectWithFreemarkerAndImage.java?repo=samples ODTProjectWithFreemarkerAndImage.java) and samples with ClassPathImageProvider with Velocity in the ODTProjectWithVelocityrAndImage.java.
and find JUnit TestCase in the ClassPathImageProviderTestCase.java
Here a sample to load image "logo.png" from the file D:/logo.png :
IImageProvider logo = new FileImageProvider(new File("D:/logo.png"));
context.put("logo", logo);
You can find JUnit TestCase in the FileImageProviderTestCase.java
Here a sample to load image "logo.png" from a byte array (or input stream):
byte[imageByteArray = ...
IImageProvider logo = new ByteArrayImageProvider(imageByteArray);
context.put("logo", logo);
You can change the content byte array (or input stream) like this:
byte[](]) imageByteArray = ...
IImageProvider logo = new ByteArrayImageProvider(imageByteArray);
// Change image content
byte[newImageByteArray = ...
logo.setImageByteArray(newImageByteArray);
You can find find JUnit TestCase in the http://code.google.com/p/xdocreport/source/browse/document/fr.opensagres.xdocreport.document/src/test/java/fr/opensagres/xdocreport/document/images/ByteArrayImageProviderTestCase.java ByteArrayImageProviderTestCase.java
At this step, image size inserted in the generated report take the same size than the "template" image. Since XDocReport 0.9.3, it's possible to customize the image size.
This section will be based on the ODTProjectWithFreemarkerAndImage.java sample.
This sample is based on this image logo (to see the real size) :
[## Use the "template" image size
By default, the size of the inserted image take the same size of the "template" image :
FieldsMetadata metadata = new FieldsMetadata();
metadata.addFieldAsImage("logo");
...
// Image with the "template" image size
IImageProvider logo = new ClassPathImageProvider(ODTProjectWithFreemarkerAndImage.class, logo.png");
context.put("logo", logo);
The generated report display the logo with the "template" size:
(http://wiki.xdocreport.googlecode.com/git/screenshots/logo.png))
If you wish display the logo with the original size, you must do like this :
FieldsMetadata metadata = new FieldsMetadata();
metadata.addFieldAsImage("originalSizeLogo");
...
// Image with original size
boolean useImageSize = true;
IImageProvider originalSizeLogo = new ClassPathImageProvider(ODTProjectWithFreemarkerAndImage.class, "logo.png",
useImageSize);
context.put("originalSizeLogo", originalSizeLogo);
The generated report display the logo with the original size:
[## Set a size for the image
You can set a size (width and height) in a pixel unit like this :
FieldsMetadata metadata = new FieldsMetadata();
metadata.addFieldAsImage("forcedSizeLogo");
...
// Image with width/height forced
IImageProvider forcedSizeLogo = new ClassPathImageProvider(ODTProjectWithFreemarkerAndImage.class, logo.png");
forcedSizeLogo.setSize(400f, 100f);
context.put("forcedSizeLogo", forcedSizeLogo);
The generated report display the logo with the forced size:
(http://wiki.xdocreport.googlecode.com/git/screenshots/ODTDynamicImageOriginalSize.png))
You can set a width in a pixel unit and compute the height with ratio like this :
FieldsMetadata metadata = new FieldsMetadata();
metadata.addFieldAsImage("ratioSizeLogo");
...
// Image with width forced and height computed with ratio
IImageProvider ratioSizeLogo = new ClassPathImageProvider(ODTProjectWithFreemarkerAndImage.class, "logo.png");
ratioSizeLogo.setUseImageSize(true);
ratioSizeLogo.setWidth(400f);
ratioSizeLogo.setResize(true);
context.put("ratioSizeLogo", ratioSizeLogo);
The generated report display the logo with the forced width and computed height :
[It's important to set IImageProvider#setResize(true) :
ratioSizeLogo.setResize(true);
otherwise the height will not be computed and will use the "template" image height.
Since XDocReport097 XDocReport 0.9.7), it's possible to manage optional image. Optional image means that:
- the IImageProvider field is null (ex : the image provider is not putted in the context).
- the IImageProvider field is NOT null but it returns a null stream image.
Imagine you have logo image template like this :
[When logo image is null (IImageProvider is null or image stream of IImageProvider is null), you wish:
- throws an error and break the report generation :
Caused by: fr.opensagres.xdocreport.core.XDocReportException: Image provider for field [logo](http://wiki.xdocreport.googlecode.com/git/screenshots/ODTDynamicImageImageTemplate.png)) cannot be null!
at fr.opensagres.xdocreport.document.images.AbstractImageRegistry.processNullImage(AbstractImageRegistry.java:106)
- or remove the "image" template in the generated report :
[- keep the "image" template in the generated report :
(http://wiki.xdocreport.googlecode.com/git/screenshots/ODTDynamicImageRemoveImageTemplate.png))
Those 3 behaviours can be managed by using the following enum :
package fr.opensagres.xdocreport.template.formatter;
public enum NullImageBehaviour
{
ThrowsError, RemoveImageTemplate, KeepImageTemplate
}
This enum gives you the capability to configure the behaviour of the null image for :
- every fields image:
FieldsMetadata metadata = report.createFieldsMetadata();
metadata.setBehaviour( NullImageBehaviour.ThrowsError )
- for a field image:
FieldsMetadata metadata = report.createFieldsMetadata();
metadata.addFieldAsImage( "logo", NullImageBehaviour.ThrowsError );
You can find samples :
-
with odt and Velocity in the ODTProjectWithVelocityAndImageWithoutImageProvider.java
-
with odt and Freemarker in the ODTProjectWithFreemarkerAndImageWithoutImageProvider.java
Using IImageProvider in your POJO model could be annoying because POJO have a big dependencies to XDocreport. Sometimes you prefer using your own Image POJO or use Java Type like InputStream, byte or File.
Since XDocReport 0.9.7 you can avoid using IImageProvider :
public class Project {
public IImageProvider getLogo() {
return ...;
}
}
and using any Java Class. Here an example with InputStream :
public class Project {
public InputStream getLogo() {
return ...;
}
}
You can find samples :
-
with odt and Velocity in the ODTProjectWithVelocityAndImageWithoutImageProvider.java
-
with odt and Freemarker in the ODTProjectWithFreemarkerAndImageWithoutImageProvider.java
- Overview
- Getting Started
- FAQ
- Which License Applies
- Download
- Developer's Guide
- User's Guide
- Contributor's Guide
- Acknowledgment
- Articles
- Releases