如何在导出中组合多个jasper报告时重新计算页码?
我已经决定在收到聊天中的两个问题并且评论关于如何处理组合jasper报告中页码的答案
I have decided to pass this Q/A after receiving both questions in chat and comment on answer on how to handle page number in "combined" jasper reports
在使用java组合报表时
When combining reports in java using
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));
页码和总页数
<textField>
<reportElement x="435" y="30" width="80" height="20" uuid="14bad2ac-3a56-4cf4-b4dd-310b8fcd2120"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA["Page "+$V{PAGE_NUMBER}+" of"]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="515" y="30" width="40" height="20" uuid="06567ba6-6243-43e9-9813-f6593528524c"/>
<textFieldExpression><![CDATA[" " + $V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
总是重新启动我列入的每个报告,有没有办法可以重新计算这些?
Is always restarted for each report that I'm including in list, is there a way that I can recalculate these?
考虑到我的最终合并报告,我想在每个页面上显示当前页面(以及正确的总页数)。
I want to have on each page the current page (and correct total number of pages) considering my final combined report.
jasper-report的方式是不在java中组合报告,而是使用
a主报告并包含不同的报告在此主要
报告中报告子报告,将页码移至主报告。
The jasper-report way would be to not combine reports in java but to use a main report and include the different reports as subreports in this main report, moving the page number to the main report.
但是,如果我们愿意结合java中的问题,我们也可以使用java来编辑和更正页码。
However, if we like to combine in java as in questions, we can also use java to edit and correct the page numbers.
这个想法是在报告中设置标记然后进行后处理 JasperPrint
,用实际页码替换标记。
This idea is to set "markers" in report and then post-process the JasperPrint
, replacing the markers with the actual page number.
jrxml (使用自由制作者风格没有羞耻感)
jrxml (without shame using freemaker style)
<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>
java
定义我的标记
private static final String CURRENT_PAGE_NUMBER = "${CURRENT_PAGE_NUMBER}";
private static final String TOTAL_PAGE_NUMBER = "${TOTAL_PAGE_NUMBER}";
我的报告的 fillReport
替换全部我的标记与真实数字
after the fillReport
of my reports replace all my markers with the true numbers
//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++;
}
}
注意:如果是我的一个项目中的代码,我不会嵌套这个数量的for和if语句,而是将代码提取到不同的方法,但为了清楚起见,我决定将它全部发布为一个代码块
Note: If it was code in one of my projects I would not nest this quantity of for and if statements, but extract code to different method's, but for clarity of post I have decided to post it all as one code block
现在已准备好出口
JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrintList));
....