Home:ALL Converter>Using an ArrayList as primary datasource in JasperReports - Only first element prints

Using an ArrayList as primary datasource in JasperReports - Only first element prints

Ask Time:2012-09-21T16:15:28         Author:eljaydub

Json Formatter

I'm having a problem using an ArrayList as my primary datasource in JasperReports.

My program is a simple Java program and I have a very simple report. I have two data object in my ArrayList and I wrap these with JRBeanCollectionDataSource and pass it to JRPrint via JasperFillManager. My report gets generated but only the first array item has been generated.

I am essentially following this tutorial and then adding another item to the ArrayList. But only one prints out.

Code snippet:

ArrayList<ProtoReport> listOfReports = new ArrayList<ProtoReport>();

ProtoReport protoReport1 = new ProtoReport();
ProtoReport protoReport2 = new ProtoReport();

//Simple Fields and text
protoReport1.setTitle("Example Fact Sheet");
protoReport2.setTitle("2nd Fact Sheet");

//add all reports to the list
listOfReports.add(protoReport1);
listOfReports.add(protoReport2);

//and wrap the ArrayList in a JRBeanCollectionDataSource
JRBeanCollectionDataSource beanBurritoWrap = new JRBeanCollectionDataSource(listOfReports);

//build the jasper report
JasperReport jasperReport;
JasperPrint jasperPrint;
HashMap<String, Object> hashMap = new HashMap<>();
boolean reportCreated;

try {
    jasperReport = JasperCompileManager.compileReport(jrxmlLocation);
    jasperPrint = JasperFillManager.fillReport(jasperReport, hashMap, beanBurritoWrap);
    JasperExportManager.exportReportToPdfFile(jasperPrint, outputFileName);
    reportCreated = true;
} catch (JRException e) {
    e.printStackTrace();
    reportCreated = false;
}

//Report on build status
System.out.println("Jasper Report built: " + reportCreated);

The ProtoReport class is basically just a container for report field, table and chart data
For example:

package org.reportprotojava.protosheet;

import java.util.ArrayList;

public class ProtoReport {

private String outputFileName;
private String title;
private String logoLocation;
private String paragraphText;
private ArrayList<String> tableData;
private String picLocation;
private int[][] graphData;  //TODO decide how to store chart data
private ChartData chartData;
private String path;

//default constructor
public ProtoReport() {

    // Initialize object fields
    outputFileName = "PrototypeReport";
    title = "Prototype Report";
    paragraphText = "Default text";

    tableData = new ArrayList<String>();
    chartData = new ChartData();

    //set path to working directory
    path = System.getProperty("user.dir");

    //default to assumed report location 
    //(ie same folder as .jrxml and .jasper files)
    logoLocation = path + "\\reports";
    picLocation = path + "\\reports";
}

Plus a parametrized constructor and then getters and setters etc

There are no problems compiling and the first report exports to pdf no problem. The only warning I get is:

log4j:WARN No appenders could be found for logger (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
log4j:WARN Please initialize the log4j system properly.

But I don't think that has anything to do with this issue (please correct me if that's not true).

Here is my .jrxml file (ignore the chart stuff, I'm working on that right now but it's shaping up to become material for another question ;-) )

<?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="ReportPrototype.jrxml" pageWidth="595" pageHeight="842" columnWidth="495" leftMargin="57" rightMargin="43" topMargin="43" bottomMargin="43" uuid="10825c57-f953-4166-bf03-8ecabe8a8f47">
<property name="ireport.zoom" value="1.0"/>
<property name="ireport.x" value="0"/>
<property name="ireport.y" value="128"/>
<subDataset name="ChartData" uuid="ebdb66fc-82b2-489c-8187-731eed51dd7a">
    <field name="xAxis" class="java.util.List"/>
    <field name="yAxis" class="java.util.List"/>
</subDataset>
<queryString language="SQL">
    <![CDATA[]]>
</queryString>
<field name="title" class="java.lang.String"/>
<field name="logoLocation" class="java.lang.String"/>
<field name="picLocation" class="java.lang.String"/>
<field name="chartData" class="java.lang.Object"/>
<field name="xAxis" class="java.util.List"/>
<field name="yAxis" class="java.util.List"/>
<title>
    <band height="115" splitType="Stretch">
        <textField isStretchWithOverflow="true" pattern="">
            <reportElement uuid="519c6bb5-72f9-4c25-8e91-47865ae0c9df" mode="Opaque" x="0" y="70" width="495" height="45" forecolor="#000099"/>
            <textElement>
                <font size="26"/>
            </textElement>
            <textFieldExpression><![CDATA[$F{title}]]></textFieldExpression>
        </textField>
        <image>
            <reportElement uuid="f989f871-32ea-4f13-ae3f-3f487cde76dd" x="295" y="0" width="200" height="42"/>
            <imageExpression><![CDATA[$F{logoLocation}]]></imageExpression>
        </image>
    </band>
</title>
<pageHeader>
    <band height="45" splitType="Stretch">
        <staticText>
            <reportElement uuid="34054fe4-f5c8-4154-b11e-558ad49c9bed" x="195" y="14" width="100" height="20"/>
            <textElement/>
            <text><![CDATA[Static text]]></text>
        </staticText>
    </band>
</pageHeader>
<columnHeader>
    <band height="105" splitType="Stretch">
        <image>
            <reportElement uuid="3759a707-32a4-49ef-a9c6-b0ad7136f738" x="242" y="0" width="253" height="105"/>
            <imageExpression><![CDATA[$F{picLocation}]]></imageExpression>
        </image>
    </band>
</columnHeader>
<detail>
    <band height="184" splitType="Stretch">
        <xyLineChart>
            <chart>
                <reportElement uuid="3b739a73-6612-42b0-bdf9-46f5d9a9899d" x="0" y="0" width="495" height="184"/>
                <chartTitle/>
                <chartSubtitle/>
                <chartLegend/>
            </chart>
            <xyDataset>
                <dataset>
                    <datasetRun subDataset="ChartData" uuid="d84314f7-4580-4b2b-a190-b0bbe4ea63df">
                        <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.JRBeanCollectionDataSource($F{chartData})]]></dataSourceExpression>
                    </datasetRun>
                </dataset>
            </xyDataset>
            <linePlot>
                <plot/>
            </linePlot>
        </xyLineChart>
    </band>
</detail>
<columnFooter>
    <band height="45" splitType="Stretch"/>
</columnFooter>
<pageFooter>
    <band height="45" splitType="Stretch"/>
</pageFooter>
<lastPageFooter>
    <band height="45" splitType="Stretch"/>
</lastPageFooter>
<summary>
    <band height="45" splitType="Stretch"/>
</summary>

Does anyone have an idea of what I'm doing wrong?

EDIT

Ok I've made some changes based on AlexK's advice by moving all of my fields, charts and tables into the Detail 1 band but now when I go to compile I get the following error:

net.sf.jasperreports.engine.JRException: Byte data not found at : C:\Users\eljaydub\workspace\ReportProtoJava\reports
at net.sf.jasperreports.repo.RepositoryUtil.getBytesFromLocation(RepositoryUtil.java:324)
at net.sf.jasperreports.engine.RenderableUtil.getRenderable(RenderableUtil.java:121)
at net.sf.jasperreports.engine.fill.JRFillImage.evaluateImage(JRFillImage.java:505)
at net.sf.jasperreports.engine.fill.JRFillImage.evaluate(JRFillImage.java:442)
at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:257)
at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:457)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:2037)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:771)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportContent(JRVerticalFiller.java:301)
at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:148)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:909)
at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:841)
at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:88)
at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:653)
at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:969)
at org.reportprotojava.protosheet.Program.main(Program.java:130)

I've done some googling and found that most of the time this is caused by problems relating to image file locations so I've modified my code with this:

//Locations

    //Absolute
    protoReport1.setLogoLocation("C:\\Users\\eljaydub\\workspace\\ReportProtoJava\\reports\\logo.gif");
    protoReport1.setPicLocation("C:\\Users\\eljaydub\\workspace\\ReportProtoJava\\reports\\portfolio.jpg");

    //Relative
//      protoReport1.setLogoLocation(protoReport1.getPath() + "\\reports\\logo.gif");
//      protoReport1.setPicLocation(protoReport1.getPath() + "\\reports\\portfolio.jpg");

and have tried both relative and absolute paths but get the same error. Are these related or should I create a new post for this error?

Edit

Solved! AlexK's advice did indeed solve the first problem and that then revealed the second: When the report went to the next array element, protoReport2, it found that the image links for this object were those supplied by my default constructor, which only guess at the probable name and location of the images files. The exception was then thrown because the image attribute onErrorType was set to Error for both images. I simply had to change the attribute to Icon in iReports and the report generated without further problems and I got what I expected: The two array elements printed on separate pages, the second one using default constructor values. Thanks for the help!

Author:eljaydub,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/12526675/using-an-arraylist-as-primary-datasource-in-jasperreports-only-first-element-p
yy