How to fill report with bean data or JSON data

0

Hi,

I am developing an Angular frontend and JAVA springboot REST backend. The backend should create a PDF file and send it to the user. To create the PDF file I want to user JasperReports.

I am using

    OpenJDK 13
    IntelliJ
    Jasper Reports 6.11.0
    Maven

I have created a small abstract application which represents all relevant functions of my final REST backend project. The project creates an object of the class ReportBean with the following structure (here some example values in JSON format)

{
   "employee": {
      "name": "John Doe",
      "age": 25
   },
   "cars": [{
         "manufacturer": "Ford",
         "model": "Mustang"
      }, {
         "manufacturer": "Dodge",
         "model": "Viper"
      }, {
         "manufacturer": "Mercedes",
         "model": "SLK"
      }
   ]
}

The layout (one main report with two subreports) should be like the following:


I found a JAVA tutorial to create a PDF report. All function calls from the tutorial are used in the Main class (s. atttachment). Before adding some custom parameters or data from a JAVA object / bean, I set the following parameter on the MAIN of each report: "When No Data Type" = "All Sections No Detail".

Without setting this parameter I got an empty report.

Here are my problems:

First Problem: How to insert the current Date to the report? (top right in the main report)

Second problem: How to use parameters in the reports? I have added a custom parameter named "object" with the value "Hello World" in my JAVA project and assigned it to a HashMap for the JasperFillManager. I created a custom paremter in my report, too, so the JasperCompilerManger doesn't throw an error.

Third problem (and this is the main problem): How cann I use my JAVA object to fill my main- and subreport? In the internet I found some examples and tutorials which didn't work. :-( When I try to create a Data Adapter, I can only select a Java Bean collection. But I don't have a collection.


When I follow the examples and tutorials that are using a Java Bean collection, I don't see any bean data when creating a Data Bean connection in the Jasper Studio.

So, I hope someone has some useful hints for me or someone is so kind as modifying my project.


Regards,

Rainer

Attachments: 
rainer.stuelp's picture
Joined: Jan 28 2020 - 10:04am
Last seen: 7 months 3 weeks ago

3 Answers:

1

First problem: set WhenNoDataType is AllSectionsNoDetail, the report will not blank anymore.

HashMap<String, Object> parameters = new HashMap<>();
// Load your template
JasperReport jasperReport = this.loadTemplate();
jasperReport.setWhenNoDataType(WhenNoDataTypeEnum.ALL_SECTIONS_NO_DETAIL);
// Create an empty datasource.
final JRBeanCollectionDataSource dataSource =
    new JRBeanCollectionDataSource(Collections.singletonList(""));
 
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, dataSource);

About inserting the current date, just use new Date() in your report template

Second problem:

Just put your object into Parameters and define your parameter in your template, you can use parameter perfectly.

In java

parameters.put("testingParameter", "This is a string.");

In your template:

Define

<parameter name="testingParameter" class="java.lang.String"/>

And use it:

 
 
				<!--[CDATA[$P{testingParameter}]]-->
 

Third problem:

When defining parameter in your template, point the type of that parameter

<parameter name="javaObject" class="com.example.YourClass"/>

Then you can use methods in that class such as getters and setters

I am Leo's picture
185
Joined: Jan 3 2020 - 3:13am
Last seen: 5 months 1 week ago
0

Hi,

thank you very, very much for your answer. Now I got the parameters working. Passing parameters from the main report to the subreports works, too.

But now,  I have one more problem:

Here is my source code:

CarBean.java:

package org.example.SamplePDF.bean;
 
public class CarBean {
    private String manufacturer;
    private String model;
 
    public String getManufacturer() {
        return manufacturer;
    }
 
    public void setManufacturer(String manufacturer) {
        this.manufacturer = manufacturer;
    }
 
    public String getModel() {
        return model;
    }
 
    public void setModel(String model) {
        this.model = model;
    }
}

ReportBean.java

package org.example.SamplePDF.bean;
 
import java.util.ArrayList;
 
public class ReportBean {
    private EmployeeBean employee;
    private ArrayList<CarBean> cars;
 
    public EmployeeBean getEmployee() {
        return employee;
    }
 
    public void setEmployee(EmployeeBean employee) {
        this.employee = employee;
    }
 
    public ArrayList<CarBean> getCars() {
        return cars;
    }
 
    public void setCars(ArrayList<CarBean> cars) {
        this.cars = cars;
    }
 
}

Question 1:

In one of the subpages I want to iterate through the ArrayList<CarBean>. I know, that I have to use the detail band. But how do I have to assign my datasource to the report?

Question 2:

If I have two subreports and two arrays in my class (not an array of an array, but one array for cars and a second one for planes e.g.), how do I have to set multiple data sources?

If you can help me one more time, it would be great.

Regards,

Rainer

rainer.stuelp's picture
Joined: Jan 28 2020 - 10:04am
Last seen: 7 months 3 weeks ago
0

Finally I got the detail band working.

In JAVA it looks like this:

ReportBean myData = generateReportData();
 
Map<String, Object> parameters = new HashMap<>();
parameters.put("myData", myData);
 
JRBeanCollectionDataSource datasource = new JRBeanCollectionDataSource(myData.getCars());
JasperPrint jasperPrint = JasperFillManager.fillReport(path, parameters, datasource);

In JasperStudio I created two fields in the main report. The name of the fields is identical to the variable names in the bean.

public class CarBean {
    private String manufacturer;
    private String model;
 
    public String getManufacturer() {return manufacturer;}
    public void setManufacturer(String manufacturer) {this.manufacturer = manufacturer;}
    public String getModel() {return model;}
    public void setModel(String model) {this.model = model;}
}

main.jrcml

<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="Main" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="0a383bf6-cd61-4478-8f63-472de51e2fc7">
   <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
   <parameter name="myData" class="org.example.SamplePDF.bean.ReportBean"/>
   <queryString>
        <![CDATA[]]>
   </queryString>
   <field name="model" class="java.lang.String">
   <field name="manufacturer" class="java.lang.String"/>

In the main report I set the property the Data Source Expression of the subreport to

new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{myData}.getCars())

After that I created the same field elements in the subreport. The value of the Text Field controls are set to

$F{manufacturer}

and

$F{model}

After that the report is filled as I want it.

I hope this little tutorial will help someone else.

Regards,

Rainer

rainer.stuelp's picture
Joined: Jan 28 2020 - 10:04am
Last seen: 7 months 3 weeks ago
Feedback
randomness