diminuta
diminuta

Reputation: 1583

JasperReports: list of objects with list of objects

I have the following DTOs:

public class ReportDTO {
    String author;
    String date;
    String title;
    List<SectionDTO> sections;
}

public class SectionDTO {
    String title;
    List<QuestionDTO> questions;
}

public class QuestionDTO {
    String title;
    String text;
}

The report is built like this:

InputStream isr = new ByteArrayInputStream(template);
InputStream is = new ByteArrayInputStream(ByteStreams.toByteArray(isr));
JasperReport report = JasperCompileManager.compileReport(is);
JasperFillManager fillManager = JasperFillManager.getInstance(DefaultJasperReportsContext.getInstance());
JRBeanCollectionDataSource datasource = new JRBeanCollectionDataSource(Collections.singleton(reportDTO));
JasperPrint print = fillManager.fill(report, jasperParameter, datasource);

And here are some relevant pieces of the JRXML file:

<field name="author" class="java.lang.String">
    <fieldDescription><![CDATA[author]]></fieldDescription>
</field>
<field name="date" class="java.lang.String">
    <fieldDescription><![CDATA[date]]></fieldDescription>
</field>
<field name="title" class="java.lang.String">
    <fieldDescription><![CDATA[title]]></fieldDescription>
</field>
<subDataset name="SectionDataSet" uuid="dae55e44-a3d6-46f1-9a27-7e751f371cbe">
    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
    <queryString>
        <![CDATA[]]></queryString>
    <field name="title" class="java.lang.String"/>
    <field name="questions" class="java.util.List"/>
</subDataset>
<subDataset name="QuestionsDataSet" uuid="f7758e2e-2508-4810-9a60-3fb053712089">
    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
    <queryString>
        <![CDATA[]]></queryString>
    <field name="title" class="java.lang.String"/>
    <field name="text" class="java.lang.String"/>
</subDataset>
<textField>
    <reportElement x="160" y="1" width="170" height="20" isRemoveLineWhenBlank="true" uuid="d0f8cbd8-20b8-409b-b6f1-bc224ceb2160"/>
    <textElement>
        <paragraph lineSpacing="Single"/>
    </textElement>
    <textFieldExpression><![CDATA[$F{author}]]></textFieldExpression>
</textField>
<textField>
    <reportElement x="0" y="22" width="140" height="19" uuid="907998dd-0d88-4645-bb54-89cc6af5c0e7"/>
    <textElement>
        <font isBold="true"/>
    </textElement>
    <textFieldExpression><![CDATA[$F{date}]]></textFieldExpression>
</textField>
<textField>
    <reportElement x="140" y="21" width="190" height="20" isRemoveLineWhenBlank="true" uuid="e0c20452-766f-4cc4-b30c-137af7badca5"/>
    <textElement>
        <paragraph lineSpacing="Single"/>
    </textElement>
    <textFieldExpression><![CDATA[$F{title}]]></textFieldExpression>
</textField>
<componentElement>
    <reportElement x="20" y="30" width="515" height="77" isRemoveLineWhenBlank="true" uuid="60c57e6e-924b-4576-8158-0670fe6847d2">
        <property name="net.sf.jasperreports.export.headertoolbar.table.name" value=""/>
    </reportElement>
    <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="SectionDataSet" uuid="86e27911-12c2-436d-be4c-78996ab031d4">
            <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{sections})]]></dataSourceExpression>
        </datasetRun>
        <jr:listContents height="77" width="515">
            <textField isBlankWhenNull="true">
                <reportElement x="1" y="0" width="514" height="20" uuid="bb1f7aeb-f199-4745-aab2-ffc877730573"/>
                <textElement>
                    <font size="12" isBold="true"/>
                    <paragraph lineSpacingSize="0.5"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{title}]]></textFieldExpression>
            </textField>
        </jr:listContents>
    </jr:list>
</componentElement>
<componentElement>
    <reportElement x="30" y="58" width="499" height="42" isRemoveLineWhenBlank="true" uuid="9a1f6d30-868d-4660-bdf7-3c58457e68aa">
        <property name="net.sf.jasperreports.export.headertoolbar.table.name" value=""/>
    </reportElement>
    <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="QuestionsDataSet" uuid="b40e2703-b00b-420a-944b-67b95a83445d">
            <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{questions})]]></dataSourceExpression>
        </datasetRun>
        <jr:listContents height="42" width="499">
            <textField>
                <reportElement x="7" y="6" width="143" height="30" uuid="112822d7-7a6f-4c37-8fe8-387df4d0414d"/>
                <textElement>
                    <font size="12" isBold="true"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{title}:]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="150" y="6" width="349" height="30" uuid="3793156d-7daf-4632-a77d-70f303b97418"/>
                <textFieldExpression><![CDATA[$F{text}]]></textFieldExpression>
            </textField>
        </jr:listContents>
    </jr:list>
</componentElement>

It's not working:

net.sf.jasperreports.engine.design.JRValidationException: Report design not valid : 
     1. Field not found : questions

I guess the error is that I'm not linking QuestionsDataSet with SectionDataSet, so it doesn't recognize field "questions". But I'm not sure how to do that...

I tried to follow this example, but it's missing some parts so I couldn't get it to work: https://www.qualogy.com/techblog/java-web/creating-report-with-list-containing-list-using-jasper-report

Upvotes: 0

Views: 5036

Answers (1)

diminuta
diminuta

Reputation: 1583

In the end it was all about list nesting, if the question list is nested as a content of the section list it works.

It also needs a "trick" to link the nested list with the main list with a dataset parameter:

<field name="author" class="java.lang.String">
    <fieldDescription><![CDATA[author]]></fieldDescription>
</field>
<field name="date" class="java.lang.String">
    <fieldDescription><![CDATA[date]]></fieldDescription>
</field>
<field name="title" class="java.lang.String">
    <fieldDescription><![CDATA[title]]></fieldDescription>
</field>
<subDataset name="SectionDataSet" uuid="dae55e44-a3d6-46f1-9a27-7e751f371cbe">
    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
    <queryString>
        <![CDATA[]]></queryString>
    <field name="title" class="java.lang.String"/>
    <field name="questions" class="java.util.List"/>
</subDataset>
<subDataset name="QuestionsDataSet" uuid="f7758e2e-2508-4810-9a60-3fb053712089">
    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/>
    <queryString>
        <![CDATA[]]></queryString>
    <field name="title" class="java.lang.String"/>
    <field name="text" class="java.lang.String"/>
</subDataset>
<textField>
    <reportElement x="160" y="1" width="170" height="20" isRemoveLineWhenBlank="true" uuid="d0f8cbd8-20b8-409b-b6f1-bc224ceb2160"/>
    <textElement>
        <paragraph lineSpacing="Single"/>
    </textElement>
    <textFieldExpression><![CDATA[$F{author}]]></textFieldExpression>
</textField>
<textField>
    <reportElement x="0" y="22" width="140" height="19" uuid="907998dd-0d88-4645-bb54-89cc6af5c0e7"/>
    <textElement>
        <font isBold="true"/>
    </textElement>
    <textFieldExpression><![CDATA[$F{date}]]></textFieldExpression>
</textField>
<textField>
    <reportElement x="140" y="21" width="190" height="20" isRemoveLineWhenBlank="true" uuid="e0c20452-766f-4cc4-b30c-137af7badca5"/>
    <textElement>
        <paragraph lineSpacing="Single"/>
    </textElement>
    <textFieldExpression><![CDATA[$F{title}]]></textFieldExpression>
</textField>
<componentElement>
    <reportElement x="20" y="30" width="515" height="77" isRemoveLineWhenBlank="true" uuid="60c57e6e-924b-4576-8158-0670fe6847d2">
        <property name="net.sf.jasperreports.export.headertoolbar.table.name" value=""/>
    </reportElement>
    <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="SectionDataSet" uuid="86e27911-12c2-436d-be4c-78996ab031d4">
            <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{sections})]]></dataSourceExpression>
        </datasetRun>
        <jr:listContents height="77" width="515">
            <textField isBlankWhenNull="true">
                <reportElement x="1" y="0" width="514" height="20" uuid="bb1f7aeb-f199-4745-aab2-ffc877730573"/>
                <textElement>
                    <font size="12" isBold="true"/>
                    <paragraph lineSpacingSize="0.5"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{title}]]></textFieldExpression>
            </textField>
            <componentElement>
                <reportElement x="30" y="58" width="499" height="42" isRemoveLineWhenBlank="true" uuid="9a1f6d30-868d-4660-bdf7-3c58457e68aa">
                    <property name="net.sf.jasperreports.export.headertoolbar.table.name" value=""/>
                </reportElement>
                <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="PreguntasDataSet" uuid="2e470209-9104-40ec-a0cd-688880c37958">
                                    <datasetParameter name="REPORT_DATA_SOURCE">
                                        <datasetParameterExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{questionsDataSource})]]></datasetParameterExpression>
                                    </datasetParameter>
                                    <dataSourceExpression><![CDATA[$P{REPORT_CONNECTION}]]></dataSourceExpression>
                                </datasetRun>
                    <jr:listContents height="42" width="499">
                        <textField>
                            <reportElement x="7" y="6" width="143" height="30" uuid="112822d7-7a6f-4c37-8fe8-387df4d0414d"/>
                            <textElement>
                                <font size="12" isBold="true"/>
                            </textElement>
                            <textFieldExpression><![CDATA[$F{title}:]]></textFieldExpression>
                        </textField>
                        <textField>
                            <reportElement x="150" y="6" width="349" height="30" uuid="3793156d-7daf-4632-a77d-70f303b97418"/>
                            <textFieldExpression><![CDATA[$F{text}]]></textFieldExpression>
                        </textField>
                    </jr:listContents>
                </jr:list>
            </componentElement>
        </jr:listContents>
    </jr:list>
</componentElement>

Upvotes: 2

Related Questions