Jasper Json nested lists - jasper-reports

I'm new in Jasper reports, so I'll write my whole task, if it's allowed..
I'm trying to parse json data to print in it PDF. Data is coming from oracle DB, written in CLOB column, so I have list of json-clob records.
I have nested lists json (and clob) data, so I can't build 3 stair nested report with my jasper experience. I have json structure like this:
{
title: 'Main Title',
blocks: [{
title: 'Inner Title',
items: [{
key: '1',
value: 'some text'
}, {
key: '2',
value: 'some other text'
}]
}, {
text: 'here may be other fields (text, not title)'
}]
}
For this json data, I want to get this result in PDF (just simple output):
Main Title
Inner Title
1 some text
2 some other text
here may be other fields (text, not title)
Firstly, I use CLOB converting in json source ( script:
< dataSourceExpression >
< ![CDATA[new net.sf.jasperreports.engine.data.JsonQLDataSource(new ByteArrayInputStream($F{JSON_CLOB_RECORD}.getBytes("UTF-8")))]] >
< /dataSourceExpression >
source: nested jasper subreports with json datasource ).
After that, I use jr:list and textfield to print main titles. And I'm done, don't know how to continue.
I searched nested lists (jr:list) but nothing, can't fit to my task.
P.S. I have subDataset for parsing data from CLOB to json with fields title (java.lang.String) and blocks (I tried here java.util.Collection and ArrayList but errors occurred, than I wrote java.lang.Object. Is it necessary to write blocks field in this subDataset?). I also added subDataset for blocks list, is it needed? And if yes, so I have to add items subDataset too, right? Also, I tried to add subReport after main title textfield, for blocks list and added dataSourceExpression but can't continue.
Need some help.

I would suggest using a subreport, instead of a list or nested lists, because you gain more flexibility in this case.
In the main report you should discard the list element and the dataset and use a subreport, something like:
<subreport>
<reportElement x="0" y="0" width="550" height="50" uuid="37861aca-d444-4aec-ad03-baa310540327"/>
<subreportParameter name="JSON_INPUT_STREAM">
<subreportParameterExpression><![CDATA[new ByteArrayInputStream($F{JSON_CLOB_RECORD}.getBytes("UTF-8"))]]></subreportParameterExpression>
</subreportParameter>
<subreportExpression><![CDATA["Subreport.jasper"]]></subreportExpression>
</subreport>
Here we only need the JSON_INPUT_STREAM so that the subreport will construct a dataSource based on the query and its language.
Case 1. If you are mostly interested in the items key, then the subreport(Subreport.jrxml) could be pretty basic like so:
<?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="Subreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="a3dd10f8-b28c-4c11-b582-9b169e8aa417">
<queryString language="jsonql">
<![CDATA[..items.*]]>
</queryString>
<field name="mainTitle" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="$.title"/>
</field>
<field name="key" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="key"/>
</field>
<field name="value" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="value"/>
</field>
<field name="blockTitle" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="^^.title"/>
</field>
<background>
<band splitType="Stretch"/>
</background>
<detail>
<band height="90" splitType="Stretch">
<textField>
<reportElement isPrintRepeatedValues="false" x="0" y="30" width="100" height="30" isRemoveLineWhenBlank="true" uuid="172de051-3d2c-4458-b01e-ab06e4e1bb3b"/>
<textFieldExpression><![CDATA[$F{blockTitle}]]></textFieldExpression>
</textField>
<textField>
<reportElement isPrintRepeatedValues="false" x="0" y="0" width="100" height="30" isRemoveLineWhenBlank="true" uuid="94f57756-a5a8-402f-ad23-7cdbe2a00e59"/>
<textFieldExpression><![CDATA[$F{mainTitle}]]></textFieldExpression>
</textField>
<textField>
<reportElement x="0" y="60" width="100" height="30" uuid="7dbbdfd8-5a0e-4288-ae39-21f13cd4d921"/>
<textFieldExpression><![CDATA[$F{key} + " " + $F{value}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
Notice the isPrintRepeatedValues="false" and the isRemoveLineWhenBlank="true" properties that remove the duplicates and the lines so that you get the desired output.
I've simulated your case with a serialized JSON and got the following:
Case 2. If you are interested in all the blocks object data you would have to land on the blocks item in your query and create a list/subreport for the items key, something like:
<?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="Report" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="a3dd10f8-b28c-4c11-b582-9b169e8aa417">
<subDataset name="BlockItemsDataset" uuid="83c1b8ed-e880-4474-a809-39d95277341f">
<field name="key" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="key"/>
</field>
<field name="value" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="value"/>
</field>
</subDataset>
<queryString language="jsonql">
<![CDATA[blocks]]>
</queryString>
<field name="mainTitle" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="$.title"/>
</field>
<field name="blockTitle" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="title"/>
</field>
<background>
<band splitType="Stretch"/>
</background>
<detail>
<band height="91" splitType="Stretch">
<textField>
<reportElement isPrintRepeatedValues="false" x="0" y="0" width="100" height="30" isRemoveLineWhenBlank="true" uuid="94f57756-a5a8-402f-ad23-7cdbe2a00e59"/>
<textFieldExpression><![CDATA[$F{mainTitle}]]></textFieldExpression>
</textField>
<textField>
<reportElement isPrintRepeatedValues="false" x="0" y="30" width="100" height="30" isRemoveLineWhenBlank="true" uuid="172de051-3d2c-4458-b01e-ab06e4e1bb3b"/>
<textFieldExpression><![CDATA[$F{blockTitle}]]></textFieldExpression>
</textField>
<componentElement>
<reportElement x="0" y="61" width="200" height="30" uuid="7a94d84d-d58e-4508-b143-3704fa7f5cd3"/>
<jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" printOrder="Vertical">
<datasetRun subDataset="BlockItemsDataset" uuid="a866f955-7594-4fb9-9bb2-936282963dea">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JsonQLDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("items")]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30" width="200">
<textField>
<reportElement x="0" y="0" width="200" height="30" uuid="36a771fa-f949-4c69-a62c-1df0c610a2d3"/>
<textFieldExpression><![CDATA[$F{key} + " " + $F{value}]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
</band>
</detail>
</jasperReport>

Related

New/different page for different organization IDs in Jaspersoft report

I'm looking for any suggestions on how to print a new/different page for different organization IDs. I created a jaspersoft grouping and was thinking of adding a print when expression to the organization ID group header. Would that be the way to go? Can anyone help me with the expression that I would need for that?
"Start New Page" (isStartNewPage="true") in the Appearance tab of the Properties for the Group Header is all that is necessary to start on a new page for every new group. Group Expression for your situation would simply be something like $F{organizationID}.
Here's an example that groups on $F{city}, lists $F{CustomerID} and starts a new page for every new $F{city}:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.1.1 -->
<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="Blank_A4_" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="62ac07f5-f11e-4179-aedb-a42e850c1ea8">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="northwind"/>
<queryString language="jsonql">
<![CDATA[Northwind.Customers]]>
</queryString>
<field name="City" class="java.lang.String">
<property name="net.sf.jasperreports.jsonql.field.expression" value="City"/>
<fieldDescription><![CDATA[City]]></fieldDescription>
</field>
<field name="CustomerID" class="java.lang.String">
<property name="net.sf.jasperreports.json.field.expression" value="CustomerID"/>
<fieldDescription><![CDATA[CustomerID]]></fieldDescription>
</field>
<group name="City" isStartNewPage="true">
<groupExpression><![CDATA[$F{City}]]></groupExpression>
</group>
<columnHeader>
<band height="12" splitType="Stretch">
<staticText>
<reportElement x="0" y="0" width="100" height="12" uuid="bdf3f7ab-bf1d-451e-a2ad-831a551ce388"/>
<textElement>
<font isBold="true"/>
</textElement>
<text><![CDATA[Company Name]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="12" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="100" height="12" uuid="c7bcc5aa-8051-48ad-a0d6-fe27c68da204"/>
<textFieldExpression><![CDATA[$F{CustomerID}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>

How to reference one field to another in a subDataset?

If I have a Jasper report with two fields. For example:
<field name="counts" class="java.util.List"/>
<field name="names" class="java.util.List"/>
In the report is it possible to use the name field to "lookup" a value in the counts field if the counts field looks like this:
[{"Bob":10},{"Bill":5},{"John":2}]
So in the report I iterate over the names using a subDataSet:
<subDataset name="nameDetails" uuid="6f0e513d-9659-4dea-8c88-0fa9522d6aef">
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
</subDataset>
<componentElement>
<reportElement x="0" y="40" width="200" height="60"/>
<jr:list printOrder="Vertical">
<datasetRun subDataset="nameDetails">
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRMapCollectionDataSource($F{names})]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="60" width="200">
<textField>
<reportElement x="0" y="0" width="200" height="20"/>
<textFieldExpression><![CDATA["Name: " + $F{name}]]></textFieldExpression>
</textField>
...
This prints out the name of each person in the names field, but additionally I want to use the "name" of each person to look-up the count for the person in the counts field, but not sure if I can do this or how?
Yes you can reference fields, in your case however you need first to pass also the other field to the subdataset, hence you can only reference data that is present in the actual subdataset.
One way is to pass the field counts as a parameter.
<datasetParameter name="counts">
<datasetParameterExpression><![CDATA[$F{counts}]]></datasetParameterExpression>
</datasetParameter>
For example assuming the List have data in same position.
List<String> names = Arrays.asList(new String[] { "Bob", "Bill", "John" });
List<Integer> counts = Arrays.asList(new Integer[] { 10, 5, 2 });
You could use the built in parameter $V{REPORT_COUNT} to retrive data from the other List, $P{counts}.get(($V{REPORT_COUNT}.intValue()-1))
jrxml
<?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="firstReport" pageWidth="595" pageHeight="842" whenNoDataType="BlankPage" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="597c0716-df6b-42ec-a7c8-863eb1b7174a">
<subDataset name="nameDetails" uuid="63078d78-2076-4a72-8728-ee6ca3ded99f">
<parameter name="counts" class="java.util.List"/>
<field name="_THIS" class="java.lang.String"/>
</subDataset>
<field name="counts" class="java.util.List"/>
<field name="names" class="java.util.List"/>
<detail>
<band height="50">
<componentElement>
<reportElement x="0" y="0" width="550" height="30" uuid="180fb785-64b3-4f04-81f6-7076444d871d"/>
<jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" printOrder="Vertical">
<datasetRun subDataset="nameDetails" uuid="8d40297b-e33b-4681-9533-d6f1ab63c6f2">
<datasetParameter name="counts">
<datasetParameterExpression><![CDATA[$F{counts}]]></datasetParameterExpression>
</datasetParameter>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{names})]]></dataSourceExpression>
</datasetRun>
<jr:listContents height="30" width="550">
<textField>
<reportElement x="0" y="0" width="550" height="30" uuid="48e09c52-3b6a-40cf-b572-2abccfcd83cc"/>
<textElement verticalAlignment="Middle">
<font size="14"/>
</textElement>
<textFieldExpression><![CDATA[$F{_THIS} + ":" + $P{counts}.get(($V{REPORT_COUNT}.intValue()-1))]]></textFieldExpression>
</textField>
</jr:listContents>
</jr:list>
</componentElement>
</band>
</detail>
</jasperReport>
Result
Note: If you have control on data arriving, however I would strongly suggest you pass the data in a single object (List), since this type of referencing is error prone, in this case if the size of the Lists are different, the report generation will fail

How to print text for each iteration in the detail except for the last one?

I have a subreport that iterates names. I want to print a the text "or" on every loop, except for the last one. Right now I'm doing a suggested solution in this question, but it still prints in the last iterate.
Here is a sample of what I have right now:
There is still an extra or in the end of the subreport.
Current subreport source code I have right now:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.5.1.final using JasperReports Library version 6.5.1 -->
<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="paiwi-signatories-name-only-subreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="8f474d5a-0cca-4c5f-807e-71af8848276f">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="signatoryJSON"/>
<queryString language="json">
<![CDATA[signatoryNames]]>
</queryString>
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="address" class="java.lang.String"/>
<variable name="signatoryCurrentCount" class="java.lang.Integer" resetType="None">
<variableExpression><![CDATA[$V{nameGroup_COUNT}]]></variableExpression>
</variable>
<group name="nameGroup">
<groupExpression><![CDATA[$F{name}]]></groupExpression>
</group>
<detail>
<band height="36" splitType="Stretch">
<textField isBlankWhenNull="true">
<reportElement positionType="Float" x="-20" y="-20" width="260" height="20" uuid="220a59b9-595b-4149-badd-f4a1ecff36c5"/>
<textElement>
<font fontName="Times New Roman" size="12"/>
</textElement>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto" isBlankWhenNull="true">
<reportElement positionType="Float" x="0" y="0" width="100" height="20" isRemoveLineWhenBlank="true" uuid="afda4fcc-78fc-46f9-8c5c-2e0c4f04dfa5"/>
<textFieldExpression><![CDATA[$V{signatoryCurrentCount}.equals($V{nameGroup_COUNT}) ? "or" : ""]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
How can I avoid to print the last textField after last record?
You can try a simple thing, put the 2 variables in your report, I think you already know how many pages your report will contain, and then change the printWhenExpression statement to the value of your page, for example your report contains 20 pages, then in your variable change the print condition to PAGE_NUMBER==20 and PAGE_NUMBER < 20 for the other one.
Good luck.
If you like to leverage evalutationTime="Auto"
Variables will be evaluated at a time corresponding to their reset type
From EvaluationTimeEnum
You need 2 variables with different reset time. Adapting to your example a solution can be:
Setting your signatoryCurrentCount to the REPORT_COUNT but reseting everytime your group change (hence on every record in your example)
<variable name="signatoryCurrentCount" class="java.lang.Integer" resetType="Group" resetGroup="nameGroup">
<variableExpression><![CDATA[$V{REPORT_COUNT}]]></variableExpression>
</variable>
Then you compare this with the built in variable $V{REPORT_COUNT} that have reset type report
<textFieldExpression><![CDATA[$V{signatoryCurrentCount}<$V{REPORT_COUNT} ? "or" : ""]]></textFieldExpression>
To understand the expression with reset type "Auto", the signatoryCurrentCount will have 1,2,3 (reset's at group) and $V{REPORT_COUNT} always 3 (reset at report).
Full Example
jrxml
<?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="paiwi-signatories-name-only-subreport" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="8f474d5a-0cca-4c5f-807e-71af8848276f">
<queryString language="json">
<![CDATA[signatoryNames]]>
</queryString>
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="address" class="java.lang.String"/>
<variable name="signatoryCurrentCount" class="java.lang.Integer" resetType="Group" resetGroup="nameGroup">
<variableExpression><![CDATA[$V{REPORT_COUNT}]]></variableExpression>
</variable>
<group name="nameGroup">
<groupExpression><![CDATA[$F{name}]]></groupExpression>
</group>
<detail>
<band height="36" splitType="Stretch">
<textField isBlankWhenNull="true">
<reportElement positionType="Float" x="-20" y="-20" width="260" height="20" uuid="220a59b9-595b-4149-badd-f4a1ecff36c5"/>
<textElement>
<font fontName="Times New Roman" size="12"/>
</textElement>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
<textField evaluationTime="Auto" isBlankWhenNull="true">
<reportElement positionType="Float" x="0" y="0" width="100" height="20" isRemoveLineWhenBlank="true" uuid="afda4fcc-78fc-46f9-8c5c-2e0c4f04dfa5"/>
<textFieldExpression><![CDATA[$V{signatoryCurrentCount}<$V{REPORT_COUNT} ? "or" : ""]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
output
Do note: using evaluationTime="Auto" is resource intensive for jasper report, in most cases I would suggest that users pass in datasource the totale number of records, the report will be generated faster.

How to evaluate a jasper report variable when there is no data?

I have a report that using a parameter to determine the report title. It is displaying null when there is no data. I've tried changing the variable $V{reportName} Evaluation Time, but no luck. Can anybody help me?
Thanks.
PS: It is using mssql data adapter and the current querystring does not return any row. To return rows, change 2=1 to 1=1.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 5.6.1.final using JasperReports Library version 5.6.1 -->
<!-- 2017-05-02T07:59:20 -->
<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="Evaluate" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="a736ce53-7e76-4194-9086-96d2270a6250">
<property name="com.jaspersoft.studio.data.defaultdataadapter" value="SYDPC1744-EXPRESSR2"/>
<parameter name="ReportType" class="java.lang.String">
<defaultValueExpression><![CDATA["B"]]></defaultValueExpression>
</parameter>
<queryString language="SQL">
<![CDATA[select Col1 from (values (1),(2)) as a(Col1) where 2=1]]>
</queryString>
<field name="Col1" class="java.lang.Integer"/>
<variable name="ReportName" class="java.lang.String">
<variableExpression><![CDATA[$P{ReportType}.equals("A")? $V{reportTitleA}:$V{reportTitleB}]]></variableExpression>
</variable>
<variable name="reportTitleA" class="java.lang.String">
<variableExpression><![CDATA["Report A"]]></variableExpression>
</variable>
<variable name="reportTitleB" class="java.lang.String">
<variableExpression><![CDATA["Report Other"]]></variableExpression>
</variable>
<pageHeader>
<band height="49" splitType="Stretch">
<textField evaluationTime="Report">
<reportElement x="0" y="0" width="390" height="20" uuid="98c519b9-7350-4cd6-a71e-f2fb1c0e7b80"/>
<textFieldExpression><![CDATA[$V{ReportName}]]></textFieldExpression>
</textField>
</band>
</pageHeader>
<columnHeader>
<band height="14" splitType="Stretch"/>
</columnHeader>
<detail>
<band height="15" splitType="Stretch">
<property name="local_mesure_unitheight" value="pixel"/>
<property name="com.jaspersoft.studio.unit.height" value="px"/>
<textField>
<reportElement x="0" y="0" width="100" height="14" uuid="82ab5741-1138-4173-88f5-42ef07a6cb9f">
<property name="local_mesure_unitheight" value="pixel"/>
<property name="com.jaspersoft.studio.unit.height" value="px"/>
</reportElement>
<textFieldExpression><![CDATA[$F{Col1}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
Your problem was setting the <textFieldExpression>
and not the <initialValueExpression>.
The <textFieldExpression> is used for calculation. Only use it for calculation!
The <initialValueExpression> is used for your initial value of this variable.
When there is no data jasperreports won't go through the calculation expression as there is no way, you could calculate using no data at all.
So just use the initial value expression...
Chaning the evaluation time of the element has no benefits at all in this case, so you can just skip it.
Also keep in mind, that by using a good order for your variables you can avoid many errors.
Here is the working code (excerpt):
<variable name="reportTitleA" class="java.lang.String">
<initialValueExpression><![CDATA["Report A"]]></initialValueExpression>
</variable>
<variable name="reportTitleB" class="java.lang.String">
<initialValueExpression><![CDATA["Report Other"]]></initialValueExpression>
</variable>
<variable name="ReportName" class="java.lang.String">
<initialValueExpression><![CDATA[$P{ReportType}.equals("A")? $V{reportTitleA}:$V{reportTitleB}]]></initialValueExpression>
</variable>
<pageHeader>
<band height="49" splitType="Stretch">
<textField>
<reportElement x="0" y="0" width="390" height="20" uuid="98c519b9-7350-4cd6-a71e-f2fb1c0e7b80"/>
<textFieldExpression><![CDATA[$V{ReportName}]]></textFieldExpression>
</textField>
</band>
</pageHeader>

Jasper reports: positioning element on bottom of the page

I wonder if it's possible to position dynamically growing (table) element to the bottom of the page? My table element is on detail band, just above the page footer band.
Basically in my case the position of the topmost row of the table would be dynamically changing all the time based on the amount of rows in the table. But I'm not sure if creating this kind of presentation is even possible with Jasper where the table would be basically "growing" from bottom to top where the last row of the table would be basically fixed to the bottom of the page, just above page footer. There would be no problem if the position of the table's topmost row would be always fixed and table would "grow normally" from the fixed top position towards the bottom of the page...
I tried setting the table's position type property to Fix relative to bottom, but after that the whole table disappeared completely. This was the only thing I was able to think of so far to solve my issue.
Maybe the easiest way to achieve this is to put your table in a <groupFooter> with footerPosition="StackAtBottom"
The correct way to group depends on your datasource, but let assume you have just one table creating a dummy group.
Example of dummy group with table StackAtBottom of page
<?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="Example2" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="ca579c38-1e4f-4993-a020-efcea9d1096e">
<style name="table"><box><pen lineWidth="1.0" lineColor="#000000"/></box></style>
<style name="table_TD" mode="Opaque" backcolor="#FFFFFF"><box><pen lineWidth="0.5" lineColor="#000000"/></box></style>
<subDataset name="Table" uuid="982be61b-ae46-4404-a9a0-30ba13e8c414">
<queryString language="xPath">
<![CDATA[/report/table/entry]]>
</queryString>
<field name="name" class="java.lang.String">
<fieldDescription><![CDATA[name]]></fieldDescription>
</field>
<field name="class" class="java.lang.String">
<fieldDescription><![CDATA[class]]></fieldDescription>
</field>
</subDataset>
<queryString language="xPath">
<![CDATA[/report]]>
</queryString>
<group name="dummy" footerPosition="StackAtBottom">
<groupFooter>
<band height="29">
<componentElement>
<reportElement key="table" style="table" x="0" y="0" width="360" height="20" uuid="53ea5a0e-1218-4150-ab5a-5f947e73b284"/>
<jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd">
<datasetRun subDataset="Table" uuid="64092841-9993-4ccd-89b4-84a546c719cf">
<dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JRXmlDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("report/table/entry")]]></dataSourceExpression>
</datasetRun>
<jr:column width="90" uuid="4f5b1813-a9cc-4f83-9bdb-b0d8c4299133">
<jr:detailCell style="table_TD" height="20">
<textField>
<reportElement x="0" y="0" width="90" height="20" uuid="f1a97e19-e23d-40b6-ad95-10614f516db7"/>
<textFieldExpression><![CDATA[$F{class}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
<jr:column width="90" uuid="98cfbe63-f865-419c-ad8f-d8af2ed706ba">
<jr:detailCell style="table_TD" height="20">
<textField>
<reportElement x="0" y="0" width="90" height="20" uuid="0480f047-02ba-4ec4-b12a-ef56a3cbfee9"/>
<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
</textField>
</jr:detailCell>
</jr:column>
</jr:table>
</componentElement>
</band>
</groupFooter>
</group>
<detail>
<band height="17" splitType="Stretch"/>
</detail>
</jasperReport>
Result