5

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

<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

4 回答 4

2

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

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

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

JasperReport jasperReport = null;
JasperPrint jasperPrint = null;

其中 ist 是您的 jrxml 的输入流,parameters 是一个哈希图,最后是您的 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);
            }
        }

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

希望能帮助到你..

于 2013-10-18T12:32:08.163 回答
0

我在 iReport 中设计我的报告,它允许我将分页符拖放到详细信息带中,但也许这可以帮助你。生成的 XML 如下所示:

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

我在细节带的底部插入了我的,所以你应该尝试<break>在你的两个对象之间插入你的。

于 2013-10-17T15:00:33.213 回答
0

是的,在打印您的第一个对象后放置中断页面调色板。这样它将在不同的页面中打印两个对象。

于 2013-10-17T15:03:23.200 回答
0

使用子报表。将您的列表作为 JRBeanCollectionDataSource 提供给 SubReport。将该子报表与子报表正下方的分页符一起放在详细信息带中。

              <break>
                   <reportElement uuid="*uuid here*" x="0" y="28" width="100" height="1"/>
              </break>
于 2015-01-16T13:29:39.793 回答