JasperReports list + each record on new page

2low.samurai picture 2low.samurai · Oct 17, 2013 · Viewed 9.7k times · Source

I have the following report in JasperReports jrxml, Detail section.
It is a list I get from Java containing 2 objects, both are being outputed on the first page, so each time test variable is called.

<detail>
    <band height="200" splitType="Stretch">
        <componentElement>
            <reportElement key="table" style="table" x="0" y="49" width="500" height="140"/>

            <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">
                <datasetRun subDataset="Data Set">
                    <datasetParameter name="REPORT_DATA_SOURCE">
                        <datasetParameterExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></datasetParameterExpression>
                    </datasetParameter>
                </datasetRun>
                <jr:listContents height="50" >
                    <textField  isBlankWhenNull="true">
                        <reportElement x="0" y="0" width="200" height="20" isRemoveLineWhenBlank="true"/>
                        <textElement textAlignment="Left" verticalAlignment="Middle" >
                            <font size="10" fontName="DejaVu Serif" isBold='true'/>
                        </textElement>
                        <textFieldExpression><![CDATA[$F{test}]]></textFieldExpression>
                    </textField>
                </jr:listContents>
            </jr:list>
        </componentElement>
    </band>
</detail>

So i have a list of 2 objects, beans. Everything works but this test variable gets shown twice on each page (both objects gets called on first page) instead of one object per page. I would like to put a break after first test is printed, so the next test in the list is printed on the next page.

Can anyone point me in the right direction?

Answer

2low.samurai picture 2low.samurai · Oct 18, 2013

I have the answer and i will post it here if someone else has the same problem.

Jasper report is quite buggy. First, when you are printing out collection of the elements (objects), you send collection to the jasper engine, which for some unknown reason doesnt recognize the first element in the collection. You solve this by adding one dummy object on the index 0 of your collection.

After searching i ve found out that jasper API has the function getPages(). This returns number of pages that there will be printed out, in a list. Each index of list is one page. You can call this function from this jasperPrint when u fill report.

JasperReport jasperReport = null;
JasperPrint jasperPrint = null;

where ist is the input stream of your jrxml, parameters is a hashmap, and last is your list of your jRBeancollData source.

beanColDataSource = new JRBeanCollectionDataSource("YOURLIST");
jasperReport = JasperCompileManager.compileReport(ist);
jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, beanColDataSource);

List<JRPrintPage> pages = japserPrint.getPages();

After you have this jasperPrint, you can call this function i wrote.

 /**
         * This removes blank page if the page size is bigger then the number of
         * "pages" in array if for some reason we get last page as empty in pdf - we
         * also put arraySize - 1 since we ve put one dummy(empty) in the array
         * collection on index 0 since for some buggy unknown reason jasper always
         * outputs collections from index 1 forward instead of 0.
         * 
         * @author Uros
         * @param pages
         *            , arraySize
         */
        private void removeBlankPage(List<JRPrintPage> pages, int arraySize)
        {
            int numOfPages = pages.size();

            if (numOfPages > arraySize - 1)
            {
                pages.remove(numOfPages - 1);
            }
        }

The function in this case removes only the last page, you can modify it so it removes any other empty page if there is one, and arraySize is smaller by one since you ve put in 1 dummy. Since you print each object on each page, if there are more pages then objects, it is obvious there is one empty page so you remove it. You need to make sure that data wont stretch over to the next page ofcourse, but i print pages that will always look the same.

Hope it helps..