Search code examples
javajasper-reportssubreportbytearrayinputstream

When main report query have multiple results sets and subreport input as parameter could not generate PDF?


My JasperReports's report has subreport. Using the ByteArrayInputStream parameter into the main report and main report query result have more than one row Could not generate pdf. But the main report query result set has an only one result set PDF to generate without any error

My Java code for passing subreport:

Map<String, Object> parameters = new HashMap<String, Object>(); 
parameters.put("subreportParameter", subreportinputstream)

Declaration of parameter at jrxml:

<parameter name="subreportParameter" class="java.io.ByteArrayInputStream"/>

This is how I'm calling subreport:

 <subreport>
   <reportElement positionType="Float" x="275" y="55" width="240" height="70" uuid="0010fc8e-593e-45ee-af10-952fd8b54ad5" />
   <subreportParameter name="reportid">
      <subreportParameterExpression><![CDATA[$P{reportid}]]></subreportParameterExpression>
   </subreportParameter>
   <subreportParameter name="currencycode">
      <subreportParameterExpression><![CDATA[$P{currencycode}]]></subreportParameterExpression>
   </subreportParameter>
   <subreportParameter name="taxcode">
      <subreportParameterExpression><![CDATA[$P{taxcode}]]></subreportParameterExpression>
   </subreportParameter>
   <connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
   <subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[$P{subreportParameter}]]></subreportExpression>
</subreport>

Solution

  • When the subreport renders the second time, it tries to load the report from the $P{subreportParameter} input stream, but that stream has already been read the first time the subreport rendered so reading from it again will not produce any data.

    The simplest way to fix this is to set the isUsingCache flag for the subreport:

    <subreport isUsingCache="true">
        ...
    

    Alternatively, you can load the JasperReport object yourself from the stream by doing JRLoader.loadObject(subreportinputstream) and pass the JasperReport object as report parameter instead of the stream.