导出合并多个jasper报表时如何重新计算页码?

Pet*_*erg 6 java jasper-reports

在收到聊天中的两个问题并评论有关如何处理“组合”碧玉报告中的页码的答案后,我决定通过此问答

在 java 中组合报告时使用

JasperPrint jasperPrint1 = JasperFillManager.fillReport(report1, paramMap);
JasperPrint jasperPrint2 = JasperFillManager.fillReport(report2, paramMap);
List<JasperPrint> jasperPrintList = Arrays.asList(jasperPrint1, jasperPrint2); 

JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList));
Run Code Online (Sandbox Code Playgroud)

页码和总页码

JasperPrint jasperPrint1 = JasperFillManager.fillReport(report1, paramMap);
JasperPrint jasperPrint2 = JasperFillManager.fillReport(report2, paramMap);
List<JasperPrint> jasperPrintList = Arrays.asList(jasperPrint1, jasperPrint2); 

JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList));
Run Code Online (Sandbox Code Playgroud)

对于我包含在列表中的每个报告,总是重新启动,有没有办法可以重新计算这些报告?

考虑到我的最终合并报告,我希望在每个页面上显示当前页面(以及正确的总页数)。

Pet*_*erg 3

jasper-report 方式是不在 java 中组合报告,而是使用主报告并将不同的报告作为子报告包含在该主报告中,并将页码移至主报告。

不过,如果我们喜欢像问题一样用java来组合,我们也可以用java来编辑和修正页码。

这个想法是在报告中设置“标记”,然后对报告进行后处理JasperPrint,用实际页码替换标记。

例子

jrxml(毫不羞耻地使用 freemaker 风格)

<textField>
    <reportElement x="435" y="30" width="80" height="20" uuid="14bad2ac-3a56-4cf4-b4dd-310b8fcd2120"/>
    <textElement textAlignment="Right"/>
    <textFieldExpression><![CDATA["${CURRENT_PAGE_NUMBER}"]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
    <reportElement x="515" y="30" width="40" height="20" uuid="06567ba6-6243-43e9-9813-f6593528524c"/>
    <textFieldExpression><![CDATA["${TOTAL_PAGE_NUMBER}"]]></textFieldExpression>
</textField>
Run Code Online (Sandbox Code Playgroud)

爪哇

定义我的标记

private static final String CURRENT_PAGE_NUMBER = "${CURRENT_PAGE_NUMBER}";
private static final String TOTAL_PAGE_NUMBER = "${TOTAL_PAGE_NUMBER}";
Run Code Online (Sandbox Code Playgroud)

在我的报告之后fillReport将所有标记替换为真实数字

//First loop on all reports to get totale page number
int totPageNumber=0;
for (JasperPrint jp : jasperPrintList) {
    totPageNumber += jp.getPages().size();
}

//Second loop all reports to replace our markers with current and total number
int currentPage = 1;
for (JasperPrint jp : jasperPrintList) {
    List<JRPrintPage> pages = jp.getPages();
    //Loop all pages of report
    for (JRPrintPage jpp : pages) {
        List<JRPrintElement> elements = jpp.getElements();
        //Loop all elements on page
        for (JRPrintElement jpe : elements) {
            //Check if text element
            if (jpe instanceof JRPrintText){
                JRPrintText jpt = (JRPrintText) jpe;
                //Check if current page marker
                if (CURRENT_PAGE_NUMBER.equals(jpt.getValue())){
                    jpt.setText("Page " + currentPage + " of"); //Replace marker
                    continue;
                }
                //Check if totale page marker
                if (TOTAL_PAGE_NUMBER.equals(jpt.getValue())){
                    jpt.setText(" " + totPageNumber); //Replace marker
                }
            }
        }
        currentPage++;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:如果它是我的一个项目中的代码,我不会嵌套这么多的 for 和 if 语句,而是将代码提取到不同的方法中,但为了帖子的清晰起见,我决定将其全部作为一个代码块发布

现在已准备好导出

JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList));
....
Run Code Online (Sandbox Code Playgroud)