简体   繁体   English

如何将主报表数据源传递给子报表(JasperReports)?

[英]How to pass master report data source to subreport (JasperReports)?

I am trying to generate a JasperReport PDF with subreports but I can't access the JRBeanCollectionDataSource (coming from a List) passed as parameter to the main report. 我正在尝试生成带有子报表的JasperReport PDF,但是我无法访问作为参数传递给主报表的JRBeanCollectionDataSource(来自列表)。 Or rather, I just get a blank subreport. 或者说,我只是得到一个空白子报表。 I expect to be looping of some sort since I am passing a JRBeanCollectionDataSource. 自从传递JRBeanCollectionDataSource以来,我希望会出现某种形式的循环。

This is my current code: 这是我当前的代码:

Java code: Java代码:

@PostMapping(path = "/generate-contract", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity < byte[] > report(
    @RequestBody Contract contract) {

    Map<String, Object> params = new HashMap<>();

    // add params to the MASTER REPORT
    params.put("farmName", contract.getFarmName());
    params.put("farmLogo", contract.getFarmLogo());

    // create a JRBeanCollectionDataSource of the List<Signatory> list
    JRBeanCollectionDataSource signatoriesListSubreportDataSource = new JRBeanCollectionDataSource(contract.getSignatoriesList());

    // add it as parameters to be read by the master report
    params.put("signatoriesListSubreportDataSource", signatoriesListSubreportDataSource);

    byte[] bytes = reportService.generatePDFReport("my-master-report", params);

    return ResponseEntity
        .ok()
        .header("Content-Type", "application/pdf; charset=UTF-8")
        .header("Content-Disposition", "inline; filename=\"" + contract.getFarmName() + ".pdf\"")
        .body(bytes);
}

I am calling a .generatePDF() method where it actually compiles the master report and the subreport as well. 我正在调用.generatePDF()方法,该方法实际上也可以编译主报表和子报表。 I don't know if this is accurate though 我不知道这是否正确

@Override
    public byte[] generatePDFReport(String inputFileName, Map<String, Object> params) {
        return generatePDFReport(inputFileName, params, new JREmptyDataSource());
    } // this is where it first goes through

@Override
public byte[] generatePDFReport(String inputFileName,
    Map <String, Object> params,
    JRDataSource dataSource) { // then proceeds to this method, creating a blank dataSource

    byte[] bytes = null;
    JasperReport jasperReport = null;
    try (ByteArrayOutputStream byteArray = new ByteArrayOutputStream()) {
        // Check if a compiled report exists
        if (storageService.jasperFileExists(inputFileName)) {
            jasperReport = (JasperReport) JRLoader
                .loadObject(storageService.loadJasperFile(inputFileName));
        }

        String mySignatoriesSubReportFileName = "my-subreport-file-name-here";

        // Compile report from source and save
        String jrxml = storageService.loadJrxmlFile(inputFileName);
        String mySubReport = storageService.loadJrxmlFile(mySignatoriesSubReportFileName);

        // add logs of master report + subreport here
        log.info("{} loaded. Compiling report", jrxml);
        log.info("{} loaded. Compiling report", paiwiSignatoriesSubReport);

        params.put("SUBREPORT_DIR", FileSystemUtil.rootLocation.toString() + "\\");

        // compile the master report together with the subreports
        jasperReport = JasperCompileManager.compileReport(jrxml); // master report
        JasperReport compiledMySubReport = JasperCompileManager.compileReport(mySubReport); // sub-report

        // Save compiled report. Compiled report is loaded next time
        JRSaver.saveObject(jasperReport,
            storageService.loadJasperFile(inputFileName));

        JRSaver.saveObject(compiledMySubReport,
            storageService.loadJasperFile(mySignatoriesSubReportFileName));

        JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params,
            dataSource);
        bytes = JasperExportManager.exportReportToPdf(jasperPrint);
    } catch (JRException | IOException e) {
        e.printStackTrace();
        log.error("Encountered error when loading jasper file", e);
    }

    return bytes;
}

This is what my master-report.jrxml looks like: 这是我的master-report.jrxml的样子:

<?xml version="1.0" encoding="UTF-8"?>
<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="Autogen-contract" pageWidth="612" pageHeight="1008" columnWidth="540" leftMargin="36" rightMargin="36" topMargin="36" bottomMargin="36" whenResourceMissingType="Error" uuid="4d5cd764-f78c-4d28-b2cc-4dadc9e584a1">

    <!-- Location of the compiled subreport. -->
    <parameter name="SUBREPORT_DIR" class="java.lang.String"/>

    <!-- For data source of sub-reports -->
    <parameter name="mySignatoriesListSubReportDataSource" isForPrompting="true" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource"/>

    <!-- This one works as of the master report -->
    <parameter name="farmName" class="java.lang.String"/>

    <!-- More details of the master report here.. -->

    <textField>
        <reportElement key="" x="135" y="120" width="270" height="20" isRemoveLineWhenBlank="true" uuid="2974af73-36ae-4781-a7b1-1b0a4a498c5c"/>
        <textElement textAlignment="Center" verticalAlignment="Middle">
            <font fontName="Times New Roman" size="12" isBold="true"/>
        </textElement>
        <textFieldExpression><![CDATA[java.lang.String.format("%s", $P{farmName})]]></textFieldExpression>
    </textField>

    <subreport>
        <reportElement x="1" y="520" width="537" height="20" uuid="fcf375d6-3935-42c9-bc81-1448e6f03ebf"/>
        <dataSourceExpression><![CDATA[$P{mySignatoriesListSubReportDataSource}]]></dataSourceExpression>
        <subreportExpression class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR} + "my-subreport.jasper"]]></subreportExpression>
    </subreport>

    <!-- More details of the master report here.. -->

</jasperReport>

This is what my-subreport.jrxml looks like: 这是my-subreport.jrxml的样子:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.5.1.final using JasperReports Library version 6.5.1  -->
<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="paiwi-signatories-subreport" pageWidth="612" pageHeight="792" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="55585643-052e-4eee-9632-3c9b06dbec8f">
    <subDataset name="Dataset1" uuid="01eaeaca-361c-429f-9e71-e974b4f2beda">
        <queryString>
            <![CDATA[]]>
        </queryString>
    </subDataset>

    <queryString>
        <![CDATA[]]>
    </queryString>

    <!-- I have a name and address in the Signatory object I passed as a list of Data Source.. -->
    <!-- But this doesn't work.. or atleast it doesn't iterate anything -->
    <field name = "name" class = "java.lang.String"/>
    <field name = "address" class = "java.lang.String"/>

    <detail>
        <band height="24" splitType="Stretch">
            <textField>
                <reportElement x="0" y="0" width="140" height="20" uuid="5f357ce5-9928-4657-98f7-c7eace9b9e84"/>
                <textElement verticalAlignment="Middle">
                    <font fontName="Times New Roman" size="12"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="140" y="0" width="400" height="20" uuid="0390ae27-e46b-4bb4-87d0-83d59abfc22e"/>
                <textElement verticalAlignment="Middle">
                    <font fontName="Times New Roman" size="12"/>
                </textElement>
                <textFieldExpression><![CDATA[$F{address}]]></textFieldExpression>
            </textField>
        </band>
    </detail>
</jasperReport>

I can't access the fields in the sub-report, I don't even know if the parameter farmSignatoriesListSubReportDataSource in the master-report.xml actually goes through and enters the subreport as a valid data source. 我无法访问子报表中的字段,我什至不知道master-report.xml中的参数farmSignatoriesListSubReportDataSource是否实际通过并将子报表作为有效数据源输入。

If You want to pass the report parameter to subreport then use a subreportParameter tag like below. 如果要将报告参数传递给subreport,请使用subreportParameter标记,如下所示。

<subreport>
        <reportElement x="-12" y="0" width="553" height="110" uuid="e012100d-4c24-468f-9d97-57cda4a0d64a"/>
                <subreportParameter name="cou_ID">
                    <subreportParameterExpression><![CDATA[$P{mySignatoriesListSubReportDataSource}]]></subreportParameterExpression>
                </subreportParameter>
                <connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
                <subreportExpression><![CDATA["my-subreport.jasper"]]></subreportExpression>
</subreport>

I hope it's helpful. 希望对您有所帮助。

First you add a subreport to a main report. 首先,您将子报表添加到主报表中。 Define parameter in main report which you will set farmSignatoriesListSubReportDataSource at first. 在主报告中定义参数,您将首先设置farmSignatoriesListSubReportDataSource。

Click the subreport you added open properties sub report tab and open edit parameters. 单击添加的子报表,然后打开属性子报表选项卡,然后打开编辑参数。 There you will need to add a parameter , give a name to parameter of subreport , and as parameter expression select parameter from the main report which you've already set before. 在那里,您将需要添加一个参数,为subreport的参数命名,并从先前已设置的主报表中选择parameter作为参数表达式。 Then you will have your fields at subreport. 然后,您将在子报表中输入字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将 JR Bean 数据源仅传递给子报表,将 JREmptyData 源传递给主 IReport - How to Pass JR Bean Data Source only to subreport and JREmptyData Source to master IReport 如何通过主报表的参数将结果集传递到子报表? - How to pass resultset to the subreport via master report's parameter? 如何将参数和资源包从主报表传递到子报表 - How to pass parameters and resource bundle from master report to subreport 如何将json数据从主报表传递到子报表 Jaspersoft Studio - How to pass json data from main report to subreport Jaspersoft Studio 如何使用Java代码中的子报表运行JasperReports的报表。 找不到子报表 - How to run JasperReports's report with subreport in java code. Not found subreport 如何在jasper报告中传递SUBREPORT_DIR - how to pass SUBREPORT_DIR in jasper report JasperReports API:如何传递多个参数以进行报告 - JasperReports API: How to pass multiple parameters to report 从主报告传递参数时,JasperReports 子报告不显示 - JasperReports subreport not displaying when parameters passed from main report 如何通过iReport将数据集从主报表传递到子报表? - How to pass dataset from main report to subreport by iReport? JasperReports - 如何在 Java 中使用远程 JSON 数据报告运行报告 - JasperReports - How to run a report using Remote JSON Data Report in Java
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM