如何将DynamicJasper报表动态添加到Jasper Report作为子报表

问题描述 投票:0回答:1
我正在使用 JRXML 格式的 Jasper 报告,假设它是 mainReport.jrxml。这个主报表包含各种字段,例如文本字段、子报表区域等。我通过以下方式添加了另一个子报表:

<subreportExpression><![CDATA["subReport.jasper"]]></subreportExpression>
在 mainReport.jasper 中,我的目标是包含具有不可预测的列数的表。如果列数已知,我可以简单地利用 JasperSoft 的内置表格。但是,由于列数未知,我选择使用 Dynamic Jasper 库。按照“这个建议”,我成功创建了一个动态 Jasper 报告。现在,我的目标是将这个 Dynamic Jasper 报告集成到我的 mainReport 中。我尝试将此动态 Jasper 报告作为参数传递给 mainReport,但遇到了错误。谁能提供有关如何将动态 Jasper 报告合并到 mainReport 中的指导吗?

这是我的 mainReport 的 JRXML

<?xml version="1.0" encoding="UTF-8"?> <!-- Created with Jaspersoft Studio version 6.12.2.final using JasperReports Library version 6.12.2-75c5e90a222ab406e416cbf590a5397028a52de3 --> <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="ncPareto" pageWidth="595" pageHeight="792" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="3a2d19d1-8c22-4eb3-a2d0-8ddff71bdb55"> <property name="com.jaspersoft.studio.data.defaultdataadapter" value="One Empty Record"/> <property name="ireport.zoom" value="1.0"/> <property name="ireport.x" value="0"/> <property name="ireport.y" value="0"/> <import value="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> <style name="BoldFont" isBold="true"/> <parameter name="anotherSubreportDataSource" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/> <parameter name="companyLogo" class="java.awt.image.BufferedImage"/> <parameter name="dynamiJasperReport" class="java.lang.Object"/> <parameter name="dynamiJasperReportData" class="java.util.Collection"/> <queryString> <![CDATA[]]> </queryString> <group name="ReportContents" isReprintHeaderOnEachPage="true"> <groupHeader> <band height="24"> <subreport overflowType="Stretch"> <reportElement positionType="Float" x="0" y="0" width="555" height="20" uuid="c8d669fb-85eb-42d5-8b00-b02e2bcd8e26"> <property name="com.jaspersoft.studio.unit.width" value="px"/> <property name="com.jaspersoft.studio.unit.height" value="px"/> </reportElement> <dataSourceExpression><![CDATA[$P{anotherSubreportDataSource}]]></dataSourceExpression> <subreportExpression><![CDATA["anotherSubreport.jasper"]]></subreportExpression> </subreport> </band> </groupHeader> </group> <title> <band height="275" splitType="Stretch"> <property name="com.jaspersoft.studio.unit.height" value="px"/> <textField pattern="MMMMM dd, yyyy HH:mm"> <reportElement x="0" y="80" width="130" height="18" uuid="08f30fa9-efb3-4215-bfc9-e7a82c503f5c"/> <textElement> <font size="12"/> </textElement> <textFieldExpression><![CDATA[new java.util.Date()]]></textFieldExpression> </textField> <image> <reportElement x="0" y="0" width="551" height="81" uuid="565dabb7-52e2-4462-9653-c70ae0fef6b9"/> <imageExpression><![CDATA[$P{companyLogo}]]></imageExpression> </image> <subreport> <reportElement positionType="Float" x="0" y="255" width="555" height="20" isRemoveLineWhenBlank="true" uuid="243c105e-4ccc-4e8b-952b-5cef05cbf648"> <property name="com.jaspersoft.studio.unit.width" value="px"/> <property name="com.jaspersoft.studio.unit.height" value="px"/> <property name="com.jaspersoft.studio.unit.y" value="px"/> </reportElement> <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{dynamiJasperReportData})]]></dataSourceExpression> <subreportExpression><![CDATA[$P{dynamiJasperReport}]]></subreportExpression> </subreport> </band> </title> </jasperReport>

这里的 dynamiJasperReport 是使用 Dynamic Jasper 库创建的 Dynamic Jasper 报告。 dynamiJasperReportData 保存着 dynami Jasper Report 的数据。
这是我们填写 mainReport 的方式

Map parameters = new HashMap(); parameters.put("companyLogo", image); parameters.put("dynamiJasperReport", pair.getLeft() ); parameters.put("dynamiJasperReportData", pair.getRight()); parameters.put("anotherSubreportDataSource", anotherSubreportDataSource); JasperPrint jasperPrint = JasperFillManager.fillReport(compiledReportFilePath, parameters, new JREmptyDataSource()); System.out.println("Report filling time : " + (System.currentTimeMillis() - start)); if ("PDF".equals(request.getExportType())) { reportService.exportToPdf(jasperPrint, response, "MainReport.pdf"); }

这里compileReportFilePath = "C:\Report\mainReport.jasper
这是我创建动态 Jasper 报告的方法

public Pair<JasperReport, Collection> createSubReportForHTMLTable(String htmlTable) throws Exception { if (htmlTable == null || htmlTable.isEmpty()) { return null; } try { Document doc = Jsoup.parse(htmlTable); Elements tables = doc.select("table"); if (tables == null || tables.isEmpty()) { return null; } // Get first table ignore others Element table = tables.get(0); //Get all rows Elements rows = table.select("tr"); ArrayList<String> columnName = new ArrayList<>(); Elements headerRow = rows.get(0).select("th, td"); for (Element header : headerRow) { columnName.add(header.text().replace("\"", "'") + "aa"); } DynamicReportBuilder reportBuilder = new DynamicReportBuilder(); Style rowStyle = new Style(); rowStyle.setBorderTop(Border.THIN()); rowStyle.setBorderBottom(Border.THIN()); rowStyle.setBorderLeft(Border.THIN()); rowStyle.setBorderRight(Border.THIN()); for (String column : columnName) { AbstractColumn columnBuilder = ColumnBuilder.getNew() .setColumnProperty(column, String.class.getName()) .setTitle(column) .setWidth(100) .setStyle(rowStyle) .setHeaderStyle(rowStyle) .build(); reportBuilder.addColumn(columnBuilder); } DynamicReport dynamicReport = reportBuilder.build(); List<Map<String, String>> dataList = new ArrayList<>(); for (int i = 0; i < rows.size(); i++) { Elements columns = rows.get(i).select("td"); Map<String, String> data = new HashMap<>(); for (int j = 0; j < columns.size(); j++) { data.put(columnName.get(j), columns.get(j).text().replace("\"", "'") + "aa"); } dataList.add(data); } Collection collection = new ArrayList<>(dataList); JRDataSource dataSource = new JRBeanCollectionDataSource(collection); JasperReport jasperReport = DynamicJasperHelper.generateJasperReport(dynamicReport, new ClassicLayoutManager(), new HashMap<>()); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap<>(), dataSource); JasperViewer.viewReport(jasperPrint); return new Pair<>(jasperReport, collection); } catch (Exception e) { e.printStackTrace(); } return null; }

你很接近。与每个子报表一样,您需要告诉主报表如何提供子报表的数据源。
java spring jasper-reports jaspersoft-studio dynamic-jasper
1个回答
0
投票
还请记住,dynamicJasper 使用动态报告所需的自定义 scripplet 类 (DJDefaultScriptlet) 来正确放置一些变量。

您可以查看dynamicjasper子报告示例,它可以提示您可能缺少哪些部分。

此外,DynamicJasperHelper.generateJasperReport(...) 方法可以为您提供有关如何连接报表和子报表的提示。

除了上述内容之外,您还可以将 DJ 与“模板”一起使用,根据您的用例,您可能会设法将“非动态”信息放入某些模板带中。

或者,您可以使用“串联报告技术”,其中第一个报告是您的主报告,然后串联 DJ 报告,以某种方式模仿子报告输出。

© www.soinside.com 2019 - 2024. All rights reserved.