openxava / documentation / Report generation - Lesson 4: Working with images

×News: OpenXava with AI - Refine the UI (Part 2) - December 1 · Read more

Video

In this video we will see how to send images from OpenXava as parameter and data source to our report.

Any problem with this lesson? Ask in the forum

Code

You can download the project for this lesson. You can also copy the code used in the video here:

In PrintProductAction.java file:
public class PrintProductAction extends JasperReportBaseAction {

	private Product product;
	
	@Override
	protected JRDataSource getDataSource() throws Exception {
		return new JRBeanCollectionDataSource(FilePersistorFactory.getInstance().findLibrary(getProduct().getPhotos()));
	}

	@Override
	protected String getJRXML() throws Exception {
		return "ProductDetail.jrxml"; 
	}

	@Override
	protected Map getParameters() throws Exception {
		Messages errors = MapFacade.validate("Product", getView().getValues());
		if (errors.contains()) throw new ValidationException(errors);
		
		Map parameters = new HashMap();	
		parameters.put("id", (getProduct().getNumber()));
		parameters.put("description", getProduct().getDescription());
		parameters.put("author", getProduct().getAuthor().getName());
		parameters.put("isbn", getProduct().getIsbn());
		parameters.put("category", getProduct().getCategory().getDescription());
		parameters.put("price", getProduct().getPrice());
		
Collection<AttachedFile> attachedFiles = FilePersistorFactory.getInstance().findLibrary(getProduct().getPhotos()); byte[] file = attachedFiles.iterator().next().getData(); parameters.put("photoFromParameter", file);
return parameters; } private Product getProduct() throws Exception { if (product == null) { int number = getView().getValueInt("number"); product = XPersistence.getManager().find(Product.class, Integer.valueOf(number)); } return product; } }


Transcription

Hello, I'm Mónica. In this lesson, you'll learn how to design a report that includes images and send them from your OpenXava application. We'll see how to send a single image to appear in the header data using a parameter, and also how to send a collection of images using a DataSource.

We'll include images in the report we created in lesson 2, and for that, we'll need to modify the action.
First, we'll include an image as a parameter. We'll declare a collection of AttachedFile, which we obtain using findLibrary, sending the library or gallery ID as a parameter; this ID is found in getPhotos. If we look at the Product class, we can see that photos is a String, used to store the library key. We declare a collection of AttachedFile because photos has the @Files annotation, indicating that more than one file, or in this case, image, can be attached.
We'll send the first image from the collection. To do this, we declare a file of type byte and assign it the getData from the first element in the collection. Finally, we send it as a parameter.
If we have a @File annotation instead of declaring a collection of AttachedFile, it would just be one file. Instead of using findLibrary, we use only find to search for the attached file, sending getPhoto as a parameter. We also get the image with getData.
We'll comment out everything we just did because we won't use @File. Now we'll send the collection of images as a DataSource using the same method we saw in the previous lesson. We had a collection of AttachedFile, so we send that directly. Done. Now it's time to modify the report.

In the ProductDetail report, drag an Image element to the report. We see that there are various ways to insert an image: from the workspace, from our system, using a URL, and so on. We leave the option as "No image". Now we create a parameter to receive the image. It will have the same name we just used, and its data type will be Object. If we don't see it in the dropdown list, we need to search for it manually.
Once the parameter is created, we go to the source view of the report and search for the image element to add the expression. We can also do this directly from the properties panel. Here is the image element. We're sending a byte array and receiving it as an object. This is fine. But now we need to interpret that byte array, so we use ByteArrayInputStream, set the parameter, and specify that the received object is a byte array.
Done. In the case of the DataSource, in the previous class, we saw that we need to directly access the property of each element. In this case, data is one of them. We create a field named data of type Object. We add the sections we removed earlier. Drag data to the detail section. Then in the source view, we manually modify the element from a textField to an image; we need to change the label from textField to image and textFieldExpression to imageExpression.
Now we add the expression, similar to before, but using the field data. Save and arrange the report elements. Done, copy the report and test it. Remember to restart the application. It seems to be working fine.

I added two more images to see how it would look. By default, the detail lines are added one below the other. We'll change this. By clicking outside the report, we can edit its properties. In Edit Page Format, we change it to 3 columns and set the print order to horizontal. We made the changes, but they didn't seem to take effect. We go to advanced and manually enter the values: 3 in column count and horizontal in print order. There it is.
Then select the static text and in the properties panel, uncheck Print repeated Values so that the text is not printed every time the element is repeated. Check Print in First Whole Band so it prints the first time. Copy and test the report again. These would be the results.
In this lesson, you've seen two techniques for sending images: parameters and DataSource. You've also learned how to obtain images from properties annotated with @Files or @File, although you can send any image obtained from any source as a byte array. Additionally, we saw how to design the report to distribute the images to our liking.

We invite you to try out what you've seen in the lesson. If you have any questions or problems, you can ask us in the forum; you can also download the code from this lesson from the repository link, both links are in the video description. Goodbye!