Ken Flake
Ken Flake

Reputation: 595

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:

Current

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?

Upvotes: 1

Views: 479

Answers (2)

Petter Friberg
Petter Friberg

Reputation: 21710

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

result

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.

Upvotes: 1

Noblesse
Noblesse

Reputation: 298

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.

Upvotes: 2

Related Questions