Passing the List of primitive type objects as datasource for subreport

前端 未结 3 1175
面向向阳花
面向向阳花 2020-11-30 05:18

I need to pass to my subreport a dataSource with help of master report\'s List parameter. I don\'t know what is

相关标签:
3条回答
  • 2020-11-30 05:33

    You can use this datasource expression for passing java.util.List (via parameter) to subreport:

    <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{seznamPriloh})]]></dataSourceExpression>
    

    The working sample, master report:

    <?xml version="1.0" encoding="UTF-8"?>
    <jasperReport ...>
        <parameter name="listParam" class="java.util.List"/>
        <parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
            <defaultValueExpression><![CDATA["<subreport_dir>"]]></defaultValueExpression>
        </parameter>
        <queryString>
            <![CDATA[SELECT id, street, city FROM address]]>
        </queryString>
        <field name="ID" class="java.lang.Integer"/>
        <field name="STREET" class="java.lang.String"/>
        <field name="CITY" class="java.lang.String"/>
        <detail>
            <band height="57" splitType="Stretch">
                <frame>
                    <reportElement x="0" y="0" width="539" height="57"/>
                    <box>
                        <topPen lineWidth="1.0"/>
                        <leftPen lineWidth="1.0"/>
                        <bottomPen lineWidth="1.0"/>
                        <rightPen lineWidth="1.0"/>
                    </box>
                    <subreport>
                        <reportElement x="0" y="32" width="523" height="17"/>
                        <subreportParameter name="cityParam">
                            <subreportParameterExpression><![CDATA[$F{CITY}]]></subreportParameterExpression>
                        </subreportParameter>
                        <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{listParam})]]></dataSourceExpression>
                        <subreportExpression><![CDATA[$P{SUBREPORT_DIR} + "subreport_list_as_param.jasper"]]></subreportExpression>
                    </subreport>
                    <textField>
                        <reportElement x="300" y="0" width="208" height="20"/>
                        <box leftPadding="10"/>
                        <textElement>
                            <font isBold="true"/>
                        </textElement>
                        <textFieldExpression><![CDATA["City: " + $F{CITY}]]></textFieldExpression>
                    </textField>
                    <textField>
                        <reportElement x="100" y="0" width="200" height="20"/>
                        <box leftPadding="10"/>
                        <textElement>
                            <font isBold="true"/>
                        </textElement>
                        <textFieldExpression><![CDATA["Street: " + $F{STREET}]]></textFieldExpression>
                    </textField>
                    <textField>
                        <reportElement x="0" y="0" width="100" height="20"/>
                        <box leftPadding="10"/>
                        <textElement>
                            <font isBold="true"/>
                        </textElement>
                        <textFieldExpression><![CDATA["Id: " + $F{ID}]]></textFieldExpression>
                    </textField>
                </frame>
            </band>
        </detail>
    </jasperReport>
    

    The subreport:

    <?xml version="1.0" encoding="UTF-8"?>
    <jasperReport ...>
        <parameter name="cityParam" class="java.lang.String"/>
        <field name="id" class="java.lang.Integer"/>
        <field name="station" class="java.lang.String"/>
        <field name="city" class="java.lang.String"/>
        <filterExpression><![CDATA[$F{city}.equals($P{cityParam})]]></filterExpression>
        <title>
            <band height="39">
                <textField>
                    <reportElement x="220" y="14" width="161" height="20"/>
                    <box leftPadding="10"/>
                    <textElement>
                        <font isBold="true" isItalic="true"/>
                    </textElement>
                    <textFieldExpression><![CDATA["City param: " + $P{cityParam}]]></textFieldExpression>
                </textField>
            </band>
        </title>
        <detail>
            <band height="20" splitType="Stretch">
                <textField>
                    <reportElement x="0" y="0" width="100" height="20"/>
                    <box leftPadding="10"/>
                    <textElement/>
                    <textFieldExpression><![CDATA[$F{id}]]></textFieldExpression>
                </textField>
                <textField>
                    <reportElement x="100" y="0" width="100" height="20"/>
                    <box leftPadding="10"/>
                    <textElement/>
                    <textFieldExpression><![CDATA[$F{station}]]></textFieldExpression>
                </textField>
            </band>
        </detail>
        <noData>
            <band height="50">
                <textField>
                    <reportElement x="220" y="17" width="161" height="20"/>
                    <box leftPadding="10"/>
                    <textElement>
                        <font isBold="true" isItalic="true"/>
                    </textElement>
                    <textFieldExpression><![CDATA["No data for city param: " + $P{cityParam}]]></textFieldExpression>
                </textField>
            </band>
        </noData>
    </jasperReport>
    

    The Java code for passing List:

    Map<String, Object> params = new HashMap<String, Object>();
    
    List<TestBean> beansList = new ArrayList<TestBean>();
    
    // The TestBean class constructor is: 
    //public TestBean(String city, Integer id, String station)
    TestBean bean = new TestBean("Dallas", 10, "Central park st.");
    beansList.add(bean);
    
    bean = new TestBean("Dallas", 11, "Railway st.");
    beansList.add(bean);
    
    bean = new TestBean("Dallas", 12, "Market st.");
    beansList.add(bean);
    
    bean = new TestBean("Lyon", 20, "Airport st.");
    beansList.add(bean);
    
    params.put("listParam", beansList);
    
    JasperReport jasperReport = JasperCompileManager.compileReport(reportSource);
    JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, params, getDemoHsqldbConnection());
    
    JasperExportManager.exportReportToPdfFile(jasperPrint, outputFileName);
    

    The result will be (view of generated PDF file):

    Generated result in PDF format


    You can look at the implementations of net.sf.jasperreports.engine.JRDataSource. The most appropriate for your case are: JRBeanCollectionDataSource and JRBeanArrayDataSource. As you can see they are both Bean-based.

    I think you can easily convert your List<String> to the List<StringBean>.

    Or you can implement your own JRDataSource.

    0 讨论(0)
  • 2020-11-30 05:47

    You have to specify what field you're using in your sub report. You are passing $F{} and as you are passing a List<String> as a DataSource you should put $F{_THIS}. Of course you have to add a field with that name too, only doing that you can use the expression $F{somefield}.

    0 讨论(0)
  • 2020-11-30 05:52

    Yes it works. It's totally not clearly documented but it works with jasperreport 4.5.1.

    You have to declare a field into your subreport named "_THIS", typed with your primitive type you want to display. In this case, a String.

    SubReport

    <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="testSubReport" pageWidth="555" pageHeight="802" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="0" rightMargin="0" topMargin="0" bottomMargin="0" isSummaryWithPageHeaderAndFooter="true" whenResourceMissingType="Empty">
    
        <queryString>
            <![CDATA[]]>
        </queryString>
        <field name="_THIS" class="java.lang.String"/>
        <pageHeader>
      ...
    

    Then in this subreport where you want to display the String value, just use $F{_THIS}.

    <detail>
        <band height="25">
            <textField isStretchWithOverflow="true">
                <reportElement x="37" y="5" width="503" height="15">
                </reportElement>
                <textFieldExpression><![CDATA[$F{_THIS}]]></textFieldExpression>
            </textField>
        </band>
    </detail>
    

    Main report

    The parent report provide the List as the datasourceExpression

    <subreport>
        <reportElement positionType="Float" x="0" y="4" width="554" height="1"/>
        <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{bean}.getListeOfStringsMethode())]]></dataSourceExpression>
        <subreportExpression><![CDATA[$P{subreportPrimitiveTypeList}]]></subreportExpression>
    </subreport>
    

    I took inspiration here

    0 讨论(0)
提交回复
热议问题