Modularization of Jasper reports: Pass data source

2020-08-09 04:10发布

In this thread how-to-pass-main-report-data-source-to-subreport-jasperreports it is stated that there may be problems with subreports on reusing an existing master reports data source. It says the subreport may close the datasource prematurely (before other iterations calling the subreports may be processed).

It seems that this may be my problem because the report is always generated (without an error) ...

  • ok: using the connection from the master report (thus each time executing the query again: once for the master and additionally for each subreport call :-( )
  • wrong: using the datasource from the master report
    • likely a follow up problem: an empty page is attached then

I set up the Data Source Expression, Parameters and Parameter Map Expression as follows:

<group name="COUNTRY" isStartNewPage="true" isReprintHeaderOnEachPage="true">
    <groupExpression><![CDATA[$F{COUNTRY}]]></groupExpression>
    <groupHeader>
        <band height="84">
            <subreport>
                <reportElement uuid="92d7fc8c-9735-4dd1-ab0d-604d734bd659" stretchType="RelativeToBandHeight" x="-2" y="5" width="555" height="75"/>
                <parametersMapExpression><![CDATA[$P{REPORT_PARAMETERS_MAP}]]></parametersMapExpression>
                <subreportParameter name="COUNTRY">
                    <subreportParameterExpression><![CDATA[$F{COUNTRY}]]></subreportParameterExpression>
                </subreportParameter>
                <dataSourceExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></dataSourceExpression>
                <subreportExpression><![CDATA[net.sf.jasperreports.engine.JasperCompileManager.compileReport( $P{BASE_DIR} + "/reports/CITIES.jrxml"]]></subreportExpression>
            </subreport>
        </band>
    </groupHeader>
</group>

I am using the latest (2013-11-06) Jaspersoft Studio Plugin 5.5.0.final (in Eclipse Kepler 4.3.1.M20130911/1000).

I want to use only one query executed once (against the database - since it is quite expensive) for the master report and a subreport that may be called arbitrary times for each group row/band. (So far this requirement and methodology seems quite plausible for many similar use cases to me. I explicitely do not want to avoid subreport functionality here because they offer the modularity and reusability I would like to utilize.)

The query has this nature (where less than 100 rows are returned in total; a lot more complex and expensive ;-) ):

query = "select country, city from cities"

The proper resulting report has this nature:

country: Germany, cities:
  Berlin
  Munich
  ...
country: Austria, cities:
  Insbruck
  Vienna
  Graz
  ...
...

The wrong result looks like this:

country: Germany, cities:
  Berlin
(additional empty page)

desired master report pseudo functionality:

ds = getDatasource()
ds.setQuery( query )
rs = ds.executeQuery()  // result set of master report

for country in getDistinctCountries( rs ) {
  println( "country: " + country + ", cities:" )
  subreport.process( country )
}

desired subreport pseudo functionality (taking over the datasource from the master report avoiding further database roundtrips):

subDs = getDatasource()
subDs.setQuery( query + " where country = " + reportParams[0] )
subRs = subDs.executeQuery()  // result set of subreport

for city in rs
  println( "  " + city )

I hope somebody could explain if I am missing something or if it is necessary (and how to do it) to clone (JRResultSetDataSource does not support it) such a datasource (or something similar).

0条回答
登录 后发表回答