首页 文章

如何在JasperReports中构建包含大型摘要的报表

提问于
浏览
4

我正在尝试使用我正在为桌面应用程序设计的报告来完成一些要求 . 我会尽可能清楚地解释自己,因为它对我来说是可能的 . 情况如下:

我有一个报告,在 <detail> 带中有一个简单的表,然后是一些非常大的部分静态文本和2或3个表达式,它们应该对应于 <summary> 波段 . 在第一时刻,我试图将所有信息都放在 <summary> 中,但后来我发现了JasperReports频段的656px高度限制 .

我解决该问题的第二个尝试是将静态摘要信息放在子报表中 . 这样我就可以使用 <title><summary> 波段将字段放在两个波段中,并且能够在子报告部分(有2或3页)中显示页码(来自第一个报告) . 我找到了选项 page footer and header in summary (JasperStudio中的一个复选框,它是 <jasperReport> 元素中的 isSummaryWithPageHeaderAndFooter="true" 属性)但是我的报告在预览时给了我一个编译错误;不要't know if it'是JasperStudio中的一个错误:我尝试了2个最新版本,错误是一样的 .

最后,我尝试添加第二个带有不同查询的 <detail> 波段,该查询只返回一个值 . 现在的问题是我无法将第二个细节带"below"放在第一个:在预览中我交替看到每个乐队的一行,而不是我需要的 . 经过大量搜索,我发现这是不可能的 .

导致问题的摘要要求

摘要具有以下要求

  • 有几个静态文本字段和一些其他带有计算字段和参数的表达式(格式化日期和类似的东西) .

  • 这些页面必须分页(页脚中[total]的页面[当前])

  • 主报表和摘要的数据源和查询相同

第一个要求使得汇总带需要一个大于656px的高度,这是该频段允许的最大值 . 所以我尝试了上面简要描述的解决方案 . 我现在将描述子报告方法的问题 .

子报表与isSummaryWithPageHeaderAndFooter =“true”

当我尝试使用这种方法从Jaspersoft Studio预览报表时,首先我得到以下状态(在IDE请求参数之前):

First report state

当我输入参数时,我得到以下状态

Second report state

之后,时间和页面不断增长,直到程序崩溃 . 在不同的安装中也会出现相同的行为:我在Windows 7和Mac OS中都尝试了6.3.1和6.4.0版本 . 但是,使用编译报告选项从IDE编译报告是成功的

compile report option

(我的意思是它会生成 .jasper 文件)但是当我将报告导出为PDF(或用 JasperViewer 显示)时,它不会在摘要带中使用页脚进行渲染

Note: 从简单的Java应用程序编译报告并没有给我任何错误 .

欢迎任何帮助 . 提前致谢

2 回答

  • 0

    您可以添加一个不会产生任何破裂的虚拟组,并将第二个细节的内容放在组页脚区域内 .

  • 0

    经过大量的研究,尝试了许多选项并提出了另一个问题,我终于找到了一种解决方案来完成报告的所有要求 . 正如我所说,这是一种解决方法,但对任何可能与JasperReports斗争的人来说都是有用的 .

    1. - 报告

    首先,我制作了2份独立报告,每份报告都有自己的查询和章节 . 每个报告都有一个名为 PAGE_COUNT_OFFSET 的参数,类型为 Integer . 在页面页脚中,我需要进行分页,我执行了以下操作:

    主要报告

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

    Note: 我要感谢Petter Fribergthis answer,这对我帮助很大 .

    2. - 报告填写

    为了使这个过程成功,在每次执行中编译报告都不是必需的,只需要编译的 .jasper 文件就可以填充数据 . 我用Java例程做了这个programmaticaly . 我将使用 main 方法显示和示例,在实践中,您将把这个逻辑写入方法体或类似的东西 .

    Note: 我假设 .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中获得我的报告并正确分页 . 希望能帮到任何人 . 最好的祝福 .

相关问题