JasperReports列表+新页面上的每条记录

时间:2013-10-17 12:26:54

标签: list jasper-reports page-break

我在 JasperReports jrxml,详细信息部分中有以下报告。
这是我从包含2个对象的 Java 获得的列表,两者都在第一页上输出,因此每次都调用测试变量。

<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>

所以我有一个包含2个对象的列表,bean。一切正常但这个测试变量在每个页面上显示两次(两个对象都在第一页上调用)而不是每页一个对象。我打算在打印完第一个测试后休息一下,所以列表中的下一个测试将打印在下一页上。

有人能指出我正确的方向吗?

4 个答案:

答案 0 :(得分:2)

我有答案,如果其他人有同样的问题,我会在这里发布。

贾斯珀报告非常错误。首先,当您打印出元素(对象)的集合时,您将集合发送到jasper引擎,由于某些未知原因,该引擎无法识别集合中的第一个元素。您可以通过在集合的索引0上添加一个虚拟对象来解决此问题。

搜索后我发现jasper API具有getPages()函数。这将返回列表中将打印出的页数。列表的每个索引是一页。当你填写报告时,你可以从这个jasperPrint调用这个函数。

JasperReport jasperReport = null;
JasperPrint jasperPrint = null;

其中ist是jrxml的输入流,参数是hashmap,last是你的jRBeancollData源列表。

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

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

有了这个jasperPrint之后,你可以调用我写的这个函数。

 /**
         * 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);
            }
        }

这种情况下的函数只删除了最后一页,你可以对它进行修改,以便删除任何其他空页(如果有的话),并且由于你输入了1个虚拟,因此arraySize小了一个。 由于您在每个页面上打印每个对象,如果有更多页面然后是对象,很明显有一个空页面,因此您将其删除。您需要确保数据不会延伸到下一页,但我打印的页面看起来总是一样。

希望有所帮助......

答案 1 :(得分:0)

我在iReport中设计我的报告,这允许我将分页符拖放到细节带中,但也许这可以帮助你。生成的XML看起来像:

          <break>
               <reportElement uuid="*uuid here*" x="0" y="28" width="100" height="1"/>
          </break>
     </band>
</detail>

我在详细信息区域的底部插入了我的,因此您应该尝试在两个对象之间插入<break>

答案 2 :(得分:0)

是打印第一个对象后放置中断页面调色板。因此它将打印两者 对象在不同的​​页面中。

答案 3 :(得分:0)

使用子报告。将列表作为JRBeanCollectionDataSource提供给SubReport。将子报表放在详细信息区域中,并在子报表的正下方放置分页符。

              <break>
                   <reportElement uuid="*uuid here*" x="0" y="28" width="100" height="1"/>
              </break>