Custom Class for JasperReports field - jasper-reports

I would like to create a report with a custom class as follows:
public class Class1 {
String cl1_f1;
String cl1_f2;
}
public class Class2 {
String cl2_f1;
String cl2_f2;
Class1 cl1_ob1;
}
Now I pass Class2 in the report through fields and JRBeanCollectionDataSource.
<subDataset name="myitems">
<field name="cl2_f1" class="java.lang.String"/>
<field name="cl2_f2" class="java.lang.String"/>
**<field name="cl1_ob1" class="Class2"/>**
</subDataset>
For the third parameter, I would like to mention one of its fields. For example: cl1_ob1.cl1_f1.
How can I accomplish this?

In the Jasper report design, the field will be defined as below:
<field name="cl1_ob1" class="Class1">
<fieldDescription><![CDATA[cl1_ob1]]></fieldDescription>
</field>
And the 2 variables of Class1 can be accessed by calling the getter method (if there is one) or you can use the variable directly, depending on it's access privileges. For Example, $F{cl1_ob1}.getCl1_f1() can be used as a text-field expression, as shown below:
<textField>
<reportElement x="36" y="26" width="235" height="20"/>
<textElement textAlignment="Center" verticalAlignment="Middle"/>
<textFieldExpression><![CDATA[$F{cl1_ob1}.getCl1_f1()]]></textFieldExpression>
</textField>

Related

Writing Flat file using beanio (beanio.org) . pojo's have parent class

I need to sort pojo of different data type like Student,employee,patient using age and store it into array. Then write it to flat file using beanio.
By json i am sending request which can have array of student,employee and patient .I have 3 pojo at java side like student,employee,patient to store data from json request.
i am able to merge and then sort all array of objects like student,employee,patient into single array of class which is base class of student,employee,patient like Human. Human class i have to make so i can sort all 3 child class using Comparator by property age.
class SortbyAge implements Comparator<Human>
{
// Used for sorting in ascending order of
// age
public int compare(Human a, Human b)
{
return a.getAge() - b.getAge();
}
}
By here everything is fine .
I am able to sort data depending on age and store it into Human Array.
problem is when i am writing sorted data to flat file using beanio .
**when i am writing data to Flat file i am getting exception below exception
org.beanio.BeanWriterException: Bean identification failed: no record or group mapping for bean class 'class [Lcom.amex.ibm.model.Human;' at the current position**
i have written all 4 tags into xml file like below.
<record name="student" class="com.amex.ibm.model.Student" occurs="0+" maxLength="unbounded">
<field name="name" length="3"/>
<field name="age" length="8"/>
<field name="address" length="15"/>
</record>
<record name="employee" class="com.amex.ibm.model.Employee" occurs="0+" maxLength="unbounded">
<field name="name" length="3"/>
<field name="age" length="8"/>
<field name="address" length="15"/>
</record>
<record name="patient" class="com.amex.ibm.model.Patient" occurs="0+" maxLength="unbounded">
<field name="name" length="3"/>
<field name="age" length="8"/>
<field name="address" length="15"/>
</record>
<record name="human" class="com.amex.ibm.model.Human" occurs="0+" maxLength="unbounded">
<field name="age" length="3"/>
</record>
How to define Parent class mapping in bean IO??
The problem you are seeing is that BeanIO doesn't know how to map an array of type Human You need to pass each of the individual objects to BeanIO to write it out to your file. Try this, by looping over your array and then pass each of the objects to BeanIO.
Change
b.write(listFinalArray);
to
for (int i = 0; i < listFinalArray.length; i++) {
b.write(listFinalArray[i]);
}
or less typing:
for (final Human human : listFinalArray) {
b.write(human);
}

No markup processor factory specified for "HTML" markup error on JaspeReports Server

I am working on a JasperReports report that works totally fine when I compile it on the Jaspersoft Studio but when I deploy it on the JR Server 6.3.0 it gives me an error that no markup processor specified for the the HTML markup:
No markup processor factory specified for "HTML" markup
I used the html markup to add few font effects to some text parts in the report. I am attaching a screenshot of the error.
How I can fix this error?
The Java code that looking for a processor is a case sensitive.
package net.sf.jasperreports.engine.fill;
// ...
public abstract class JRFillTextElement extends JRFillElement implements JRTextElement {
// ...
private static final Map<String, MarkupProcessor> markupProcessors = new HashMap<String, MarkupProcessor>();
// ...
protected MarkupProcessor getMarkupProcessor(String markup) {
MarkupProcessor markupProcessor = markupProcessors.get(markup); // it is just a Map. The key is case sensetive
In default.jasperreports.properties file the processor for html markup is registered with lower case. Look at the end of name (factory.html):
net.sf.jasperreports.markup.processor.factory.html=net.sf.jasperreports.engine.util.JEditorPaneMarkupProcessor.HtmlFactory
You should use the name at lower case, like this:
<textField>
<reportElement x="0" y="0" width="100" height="10"/>
<textElement markup="html">

Data will not shown at Jaspersoft Studio 6.2.2 data set dialog

I have faced suddenly the following issues with Jaspersoft Studio data set dialog:
First: After running the first query select KN_Perzentile from "Kennzahl" where KN_ID = 215 and KN_RefWert1 = 8.3 and clicking the refresh preview data the Studio shows that 2 fields are read (which should be one in fact as I tested the query against DB), but the data will not shown at all!
Second: Running any other query there encounters an error, saying that the field KN_Perzentile is not found! This field is not asked in the second query at all!
Both queries are tested against Database and correct. I have these problems only on one project.
The variable vVisual should read the value from the data base.And the java class which is in build path should read his variable and use it for creating the chart. But the data will not be added to the chart. I guess that is because jasper does not read the KN_Perzentile.
This is the chart with Visual Basic = 0 after genarating:
Here is the jrxml:
<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="JFreeReport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="1edc4d15-06d0-46cf-8d57-179fd0bed566">
<scriptlet name="BoxPlotScript" class="testProjektIman.toc.JFreeChartScriptlet"/>
<queryString>
<![CDATA[select KN_Perzentile from "Kennzahl" where KN_ID = 215 and KN_RefWert1 = 8.3
]]>
</queryString>
<field name="KN_Perzentile" class="java.lang.Double"/>
<variable name="Pie" class="net.sf.jasperreports.engine.JRRenderable" calculation="System">
<variableExpression><![CDATA[$V{Pie}]]></variableExpression>
<initialValueExpression><![CDATA[$V{Pie}]]></initialValueExpression>
</variable>
<variable name="vVisual" class="java.lang.Double" calculation="First">
<variableExpression><![CDATA[$F{KN_Perzentile}]]></variableExpression>
<initialValueExpression><![CDATA[$F{KN_Perzentile}]]> </initialValueExpression>
</variable>
<detail>
<band height="290" splitType="Stretch">
<image scaleImage="Clip" hAlign="Center">
<reportElement x="60" y="50" width="440" height="215" uuid="60c9de91-e7ad-4ffb-81fd-109a381532b6"/>
<imageExpression><![CDATA[$V{Pie}]]></imageExpression>
</image>
</band>
</detail>
</jasperReport>
Java Class:
public class JFreeChartScriptlet extends JRDefaultScriptlet
{
#Override
public void afterReportInit() throws JRScriptletException {
Double testVb = 0.0;
DefaultPieDataset dataset = new DefaultPieDataset();
testVb = (Double) this.getVariableValue("vVisual");
dataset.setValue("Java", new Double(43.2));
dataset.setValue("Visual Basic", testVb);
dataset.setValue("C/C++", new Double(17.5));
dataset.setValue("PHP", new Double(32.5));
dataset.setValue("Perl", new Double(1.0));
JFreeChart chart =
ChartFactory.createPieChart3D(
"Pie Chart 3D Demo 1",
dataset,
true,
true,
false);
PiePlot3D plot = (PiePlot3D) chart.getPlot();
plot.setStartAngle(290);
plot.setDirection(Rotation.CLOCKWISE);
plot.setForegroundAlpha(0.5f);
plot.setNoDataMessage("No data to display");
this.setVariableValue("Pie", new JCommonDrawableRenderer(chart));
}
}
First
I don't see any use of any field out of the result. $V{Pie} just refers to itself and is being used in the reports Detail band, $V{vVisual} is being calculated but not being used anywhere.
Because of this structure, no fields are being shown.
Second
There is a field defined called KN_Perzentile. If you change your query and your query does not return this field (with the correct data type) anymore you get the error you are seeing.
EDIT
According to the documentation for scriptlets, there are two rules to comply with:
The important part when ensuring a variable in your report template is filled by a Scriptlet (or subreport) is to ensure the Variable has a calculation type of 'System' in the report design:
<variable name="AllCities" class="java.lang.String" calculation="System"/>
Also notice that there is no Variable Expression. Make sure you remember these two points when creating Variables in your own report with values supplied by Scriptlets.
Following this, the variableExpression of the system variable should be removed.

How to populate chart data with JavaBeans collection dataSet?

I have already created a working jrxml report presenting a table populated by a dataset of a collection (List) of Java beans.
Now I would like to use that same dataset to create Chart (basic bar chart for starters). Each bean contains 4 values that I would like to show on bar chart: month, normal hours, travel hours, and overtime hours. I was hoping that each bean would generate a group of 3-bars for each month so in the end the chart would contain 12x3 bars growing from bottom to up and the name of the month would act as a label under the 3-bar groups, each group positioned next to another starting from left to right.
Unfortunately creating this chart seems much harder than I thought. At least it seems to be totally different compared to creating the table. I'm not sure if the Jasper Studio's Chart wizard is even working. At least it doesn't allow me to add any series in the chart data series dialog: if I press Add absolutely nothing happens - no dialog opens, no error message, nothing, nothing to hint me what is wrong.
Main problem is that I don't see a way to connect the dataset data to the Chart.
After trying embedding chart to my main report, I tried to add it also to a new subreport created only for to act as chart container. I passed the main report dataset as a datasource to subreport and tried to use it as main data set in subreport's chart. Still no luck with the dataset/chart connection, f.e. Still nothing happens if I press the Add-button.
Below you can see the simple beans I'm using. First one, the WorkingHoursReport is the bean I'm passing to report as JRBeanCollectionDataSource. I believe the most interesting field of that bean is the list of WorkingHours-beans. There will be always 12 items on that list: one for each month. That is the list I'm currently passing to my table element using datasource expression: new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{workingHours}).
WorkingHoursReport.java:
public class WorkingHoursReport extends CommonReport {
private int year;
private List<WorkingHours> workingHours;
}
WorkingHours.java:
public class WorkingHours {
private int month = 0;
private double hoursNormal = 0;
private double hoursTravel = 0;
private double hoursOvertime = 0;
private double hoursTotal = 0;
private double hoursTotalCumulative = 0;
}
While trying to create my first chart ever, I was naturally trying to populate the data to chart using the very same command for defining the datasource as I was already using successfully with my table:
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{workingHours}).
Unfortunately it seemed that at least the jasper studio chart creation wizard did not get any connection to the data (no dialog was opening where, according to the docs, I should have been able to select data fields to chart ).
This is how I would solve your problem considering that you are using java beans, need to sum up data and then have both series (hours) and categories (months). Don't connect it to your table datasource but create a specific datasource for it.
Create a specific chart bean
public class ChartData {
private String serie;
private String category;
private double value;
public ChartData(String serie, String category, double value) {
super();
this.serie = serie;
this.category = category;
this.value = value;
}
.... getter and setters
}
Fill the chart bean's with data
Loop your dataset (List) and fill the ChartData list, you will probably need a map to find same month and add to the hours. I will not show you this but create them statically to show an example
List<ChartData> cList = new ArrayList<ChartData>();
cList.add(new ChartData("hoursNormal","month1", 12.3)); //The use of resources or static text is beyond this example
cList.add(new ChartData("hoursTravel","month1", 3.2));
cList.add(new ChartData("hoursOvertime","month1", 1.3));
cList.add(new ChartData("hoursNormal","month2", 16.4));
cList.add(new ChartData("hoursTravel","month2", 5.2));
cList.add(new ChartData("hoursOvertime","month2", 4.1));
Pass the List as a datasource through the parameter map
Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("CHART_DATASET", new JRBeanCollectionDataSource(cList));
Display the chart
Now we can display the chart in the title or summary band using a subDataset passed on the parameter $P{CHART_DATASET}
<?xml version="1.0" encoding="UTF-8"?>
<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="working_hours" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="1a12c021-57e2-4482-a273-56cbd3f78a17">
<subDataset name="chartDataSet" uuid="119b7f0e-01ef-4e2b-b628-d76f51e83768">
<field name="serie" class="java.lang.String"/>
<field name="category" class="java.lang.String"/>
<field name="value" class="java.lang.Double"/>
</subDataset>
<parameter name="CHART_DATASET" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource" isForPrompting="false"/>
<summary>
<band height="142" splitType="Stretch">
<barChart>
<chart>
<reportElement x="80" y="0" width="337" height="142" uuid="c8f4dc5d-47e7-489b-b27e-09976d90994a"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend/>
</chart>
<categoryDataset>
<dataset>
<datasetRun subDataset="chartDataSet" uuid="abec2dce-b670-4e84-b71f-469d954dbcb5">
<dataSourceExpression><![CDATA[$P{CHART_DATASET}]]></dataSourceExpression>
</datasetRun>
</dataset>
<categorySeries>
<seriesExpression><![CDATA[$F{serie}]]></seriesExpression>
<categoryExpression><![CDATA[$F{category}]]></categoryExpression>
<valueExpression><![CDATA[$F{value}]]></valueExpression>
</categorySeries>
</categoryDataset>
<barPlot>
<plot/>
<itemLabel/>
<categoryAxisFormat>
<axisFormat/>
</categoryAxisFormat>
<valueAxisFormat>
<axisFormat/>
</valueAxisFormat>
</barPlot>
</barChart>
</band>
</summary>
</jasperReport>
Settings in JasperSoft Studio
Enjoy the result

Creating Subreport with list of list

I have a list of goals, each of which have another ArrayList in it. I want to have the details in the child ArrayList to be displayed using a subreport. I would like to have a subreport for each of the objects in the child ArrayList.
The issue I am facing is that, I can't seem to find a way to specify the ArrayListas data source for the subreport. When trying to create datasource, I can't select fields of the dataset on which the list is built, only the fields of the main report can be selected.
Is it possible to do this in jasper report? I am stuck with this for quite some time now.
With information given this would be the answer.
Main bean (your goals?), containing List of other bean (SubBean).
public class Bean {
private String var1;
private List<SubBean> subBeans;
public String getVar1() {
return var1;
}
public void setVar1(String var1) {
this.var1 = var1;
}
public List<SubBean> getSubBeans() {
return subBeans;
}
public void setSubBeans(List<SubBean> subBean) {
this.subBeans = subBean;
}
}
Sub bean
public class SubBean {
private String var2;
public SubBean(String var2){
this.var2 = var2;
}
public String getVar2() {
return var2;
}
public void setVar2(String var2) {
this.var2 = var2;
}
}
How to pass the SubBean List to a subreport.
You need the field subBeans in you main report.
<field name="subBeans" class="java.util.List"/>
I suggest that you pass the location of the .jasper file as a parameter (Note jasper report needs absolute path) es. in main report
<parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false"/>
and in java pass it (in example sub folder "jasper" in working directory is the location of the subreport.jasper)
paramMap.put("SUBREPORT_DIR", new File("jasper").getAbsolutePath() + File.separator);
Now just call your subreport (needs to be complied into .jasper) from main report like this.
<subreport>
<reportElement x="105" y="4" width="400" height="100"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{subBeans})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR} + "subreport.jasper"]]></subreportExpression>
</subreport>
Hence:
I'm creating a new JRDataSource for the sub report passing the List of SubBean in the current Bean
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{subBeans})
indicating the absolute location of the compiled subreport.jasper
$P{SUBREPORT_DIR} + "subreport.jasper"
so now in your subreport you can use the field: var2 of the SubBean, just define it like this in the subreport.jrxml
<field name="var2" class="java.lang.String"/>