我正在尝试使用我正在为桌面应用设计的报告来完成一些要求。我会尽可能清楚地解释自己,因为它对我来说是可能的。情况如下:
我的报告在<detail>
频段中有一个简单的表格,然后是一些非常大的部分静态文本和2或3个表达式,它们应该对应<summary>
个频段。在第一时刻,我试图将所有信息都放在<summary>
中,但后来我发现了JasperReports频段的656px高度限制。
我解决该问题的第二次尝试是将静态摘要信息放在子报表中。这样我就可以使用<title>
和<summary>
个频段将字段放在两个频段中,而不必担心频段高度限制。该解决方案的问题在于我无法在子报表部分(具有2或3页)中显示页码(来自第一个报表)。我找到了页脚和摘要标题的选项(JasperStudio中的一个复选框,isSummaryWithPageHeaderAndFooter="true"
元素中的<jasperReport>
属性)但是我的报告在预览时给了我一个编译错误;不知道它是不是JasperStudio中的一个错误:我尝试了2个最新版本,错误是一样的。
最后,我尝试使用不同的查询添加第二个<detail>
波段,该查询仅返回单个值。现在的问题是我无法将第二个细节带“置于”第一个:在预览中,我看到每个波段的一行交替出现,而不是我需要的。经过大量搜索,我发现这是不可能的。
摘要具有以下要求
第一个要求使得汇总带需要大于656px的高度,这是该频段允许的最大值。所以我尝试了上面简要描述的解决方案。我现在将描述子报告方法的问题。
isSummaryWithPageHeaderAndFooter="true"
当我尝试使用此方法从Jaspersoft Studio预览报表时,首先我得到以下状态(在IDE请求参数之前):
当我输入参数时,我得到以下状态
之后,时间和页面不断增长,直到程序崩溃。在不同的安装中也会出现相同的行为:我在Windows 7和Mac OS中都尝试过版本6.3.1和6.4.0。但是,使用编译报告选项
从IDE编译报告是成功的(我的意思是它会生成.jasper
文件)但是当我将报告导出为PDF(或使用JasperViewer
显示)时,它不会使用摘要带中的页脚进行渲染
注意:从简单的Java应用程序编译报告不会给我带来任何错误。
欢迎任何帮助。提前致谢
答案 0 :(得分:0)
您可以添加一个不会产生任何破裂的虚拟组,并将第二个细节的内容放在组页脚区域内。
答案 1 :(得分:0)
经过大量研究,尝试了许多选项并提出了另一个问题后,我终于找到了一种解决方案来完成报告的所有要求。正如我所说,这是一种解决方法,但对任何可能与JasperReports斗争的人来说都是有用的。
首先,我制作了2份独立报告,每份报告都有自己的查询和部分。每个报告都有一个名为Integer
的{{1}}类型的参数。在页面页脚中,我需要进行分页,我执行了以下操作:
<pageFooter>
<band height="54" splitType="Stretch">
<textField>
<reportElement x="146" y="2" width="100" height="30" uuid="1314c392-e24a-47bd-a0aa-6b19803be36a"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA["- Page " + $V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="246" y="2" width="100" height="30" uuid="230a6e2d-3e6d-4d52-9228-aab519122537"/>
<textElement textAlignment="Left"/>
<textFieldExpression><![CDATA[" of " + ($V{PAGE_NUMBER} + $P{PAGE_COUNT_OFFSET}) + " -"]]></textFieldExpression>
</textField>
</band>
</pageFooter>
<pageFooter>
<band height="50">
<property name="com.jaspersoft.studio.unit.height" value="pixel"/>
<textField>
<reportElement x="146" y="2" width="100" height="30" uuid="b6a836b2-41f5-4a61-af64-50720544cef2"/>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA["- Page " + ($V{PAGE_NUMBER} + $P{PAGE_COUNT_OFFSET})]]></textFieldExpression>
</textField>
<textField evaluationTime="Report">
<reportElement x="246" y="2" width="100" height="30" uuid="be5469d3-10ed-4deb-964d-c1f9c9b7337a"/>
<textElement textAlignment="Left"/>
<textFieldExpression><![CDATA[" of " + ($V{PAGE_NUMBER} + $P{PAGE_COUNT_OFFSET}) + " -"]]></textFieldExpression>
</textField>
</band>
</pageFooter>
注意:我要感谢Petter Friberg this answer,这对我帮助很大。
要使此过程成功,在每次执行中编译报表都不是必需的,您只需要将已编译的.jasper
文件填充数据。我用Java例程做了这个programmaticaly。我将使用main
方法展示和示例,在实践中,您将把这个逻辑写入方法体或类似的东西。
注意:我假设.jasper
文件打包在JAR文件的根目录中。
public static void main(String[] args) {
try {
// Build parameters map with fake offset
Map<String, Object> subreportParams = new HashMap<>();
// PARAM_PAGE_COUNT_OFFSET is a convenient String constant with the parameter name for the report
subreportParams.put(PARAM_PAGE_COUNT_OFFSET, 10);
Map<String, Object> mainParams = new HashMap<>(subreportParams);
mainParams.put(...); // Some other parameters
// Fill the report the first time and get the real page count for every report
ClassLoader classLoader = getClass().getClassLoader();
// Again, MAIN_REPORT_FILE and SUBREPORT_FILE are String constants containing jasper files names
// JdbcManager.getConnection() is a utility method which gets a connection with predefined parameters
JasperPrint main = JasperFillManager.fillReport(classLoader.getResourceAsStream(MAIN_REPORT_FILE), mainParams, JdbcManager.getConnection());
JasperPrint subreport = JasperFillManager.fillReport(classLoader.getResourceAsStream(SUBREPORT_FILE), subreportParams, JdbcManager.getConnection());
// Get the page count for every report and reinsert it in the parameters map
int mainPageCount = main.getPages().size();
int subreportPageCount = subreport.getPages().size();
// The offset for the given report should be the count from the other
mainParams.put(PARAM_PAGE_COUNT_OFFSET, subreportPageCount);
subreportParams.put(PARAM_PAGE_COUNT_OFFSET, mainPageCount);
// Fill with the final parameters and generates a JpList object
main = JasperFillManager.fillReport(classLoader.getResourceAsStream(MAIN_REPORT_FILE), mainParams, JdbcManager.getConnection());
subreport = JasperFillManager.fillReport(classLoader.getResourceAsStream(SUBREPORT_FILE), subreportParams, JdbcManager.getConnection());
List<JasperPrint> finalReport = new ArrayList<>();
finalReport.add(main);
finalReport.add(subreport);
// Export the report and save it to a given path
JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(SimpleExporterInput.getInstance(finalReport));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(
new FileOutputStream("path/to/report.pdf")));
exporter.exportReport();
} catch (JRException ex) {
LOGGER.log(Level.SEVERE, "Error generating report", ex);
} catch (FileNotFoundException ex) {
LOGGER.log(Level.SEVERE, "Error saving file", ex);
}
}
这样我就可以在单个PDF中获取报告并正确分页。希望能帮助任何人。最好的问候。