web-dev-qa-db-ja.com

メインレポートデータソースをサブレポート(JasperReports)に渡す方法

JasperReportsを使用しており、レポートにJRDataSourceを入力しています。さて、メインREPORT_DATA_SOURCEサブレポートに。これどうやってするの?

私が知る限り、REPORT_DATA_SOURCEは消費可能なオブジェクトなので、一度しか使用できませんよね。このデータソースをコピーして渡すことはできますか?

ところで:私はレイアウトを作成するためにiReportを使用しています。

31
adis

組み込みのREPORT_DATA_SOURCEパラメーターを介してdatasourceを渡すことができます。

例:

<subreport>
    <reportElement x="261" y="25" width="200" height="100"/>
    <dataSourceExpression><![CDATA[$P{REPORT_DATA_SOURCE}]]></dataSourceExpression>
    <subreportExpression><![CDATA[$P{SUBREPORT_DIR} + "subreport.jasper"]]></subreportExpression>
</subreport>

変数、パラメーター、またはフィールドに基づいて、datasourceの新しいインスタンスを作成できます。

標本、見本:

<variable name="HeadingsCollection" class="Java.util.Collection" calculation="System">
    <initialValueExpression><![CDATA[new Java.util.ArrayList()]]></initialValueExpression>
</variable>
...
<subreport>
    <reportElement x="0" y="0" width="515" height="20"/>
    <subreportParameter name="ReportTitle">
        <subreportParameterExpression><![CDATA[$P{ReportTitle}]]></subreportParameterExpression>
    </subreportParameter>
    <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($V{HeadingsCollection})]]></dataSourceExpression>
    <subreportExpression class="Java.lang.String"><![CDATA["HeadingsReport.jasper"]]></subreportExpression>
</subreport>

別のサンプル:

<field name="cast" class="Java.util.Collection"/>
...
<subreport>
    <reportElement positionType="Float" x="15" y="25" width="245" height="20" isRemoveLineWhenBlank="true" backcolor="#99CCFF"/>
    <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{cast})]]></dataSourceExpression>
    <subreportExpression class="Java.lang.String"><![CDATA["JRMDbCastSubreport.jasper"]]></subreportExpression>
</subreport>

または、パラメータを介してdatasourceを渡すことができます:

<parameter name="SubreportDataSource" class="net.sf.jasperreports.engine.JRDataSource"/>
...
<subreport>
    <reportElement positionType="Float" x="15" y="25" width="245" height="20" isRemoveLineWhenBlank="true"/>
    <dataSourceExpression>$P{SubreportDataSource}</dataSourceExpression>
    <subreportExpression class="Java.lang.String"><![CDATA["Subreport.jasper"]]></subreportExpression>
</subreport>

注:サブレポートマスターレポートと(データソース)-を使用すると、サブレポート最初の行を失う効果が発生する可能性があります。この問題を回避する方法を理解するには、 サブレポートに最初のレコードがないのはなぜですか postを読むことができます。

37
Alex K

はい、データソースを渡す方法に注意する必要があります。 SQL接続では、$P{REPORT_CONNECTION}のような接続式を渡すことができます。次に、サブレポートには独自のSQLクエリがあります。

あなたの場合、実際のデータを渡したいです。詳細によっては、$P{REPORT_PARAMETERS_MAP}のようなパラメータマップ式を定義するだけの簡単な場合もあります。 iReportでサブレポート接続を設定した同じウィンドウの別のタブにあります。多くの場合、これはデータソースを渡すのに十分です。

しかし、物事を処理するために小さなコードが必要になる場合があります。サブレポートで再利用されるCSVデータソースを使用したこの例を検討してください。 JRParameter.REPORT_DATA_SOURCEオブジェクトを使用できないのは、インデックス行ポインターがリセットされないためです。そのため、元のオブジェクトをサブレポートに渡すと、レコードセットが早まって閉じられます。これを最小限のヘルパークラスで解決しました。

package com.jaspersoft.untested_unsupported; 

import Java.io.File; 
import Java.io.FileNotFoundException; 
import net.sf.jasperreports.engine.JRDataSource; 
import net.sf.jasperreports.engine.data.JRCsvDataSource; 

public class CsvDataSourceFactory { 
    public static JRDataSource getDataSource(String fileName, boolean firstRowHeaders) throws FileNotFoundException { 
        JRCsvDataSource csvDs = new JRCsvDataSource(new File(fileName)); 
        csvDs.setUseFirstRowAsHeader(firstRowHeaders); 
        return csvDs; 
    } 
}
1
mdahlman

サブレポートにテーブルがある状況がありました。サブレポートには、タイトルバンドとサマリーバンドのみがあり、サマリーにはテーブルがあります。テーブルにもサブレポートデータソースを使用したかったのですが、受け入れられた回答のどちらのアプローチも機能しませんでした。したがって、バージョン6.6.0でうまく機能している代替アプローチとして、次のようにします。

メインレポートで:

        <subreport>
            <reportElement x="0" y="0" width="468" height="0" uuid="c057b890-3889-43dd-8634-bbf2e857cc0d"/>
            <subreportParameter name="partsList">
                <subreportParameterExpression><![CDATA[$F{drawingRevision}.getPartsList()]]></subreportParameterExpression>
            </subreportParameter>
            <subreportExpression><![CDATA["static/engineering/drawings/subreports/DrawingPartsList.jasper"]]></subreportExpression>
        </subreport>

ここで重要なのは、Listがパラメーターとして渡され、[〜#〜] not [〜#〜]が次のようなデータソースとして渡されることです。

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

サブレポートには次が含まれます。

...
<parameter name="partsList" class="Java.util.List" isForPrompting="false"/>
...
<summary>
    <band height="60" splitType="Stretch">
        <componentElement>
            <reportElement key="table" style="table" x="0" y="0" width="468" height="60" uuid="09499b35-b122-4fe4-a2b3-d91d6a19b2ab"/>
            <jr:table xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" whenNoDataType="AllSectionsNoDetail">
                <datasetRun subDataset="PartList" uuid="87fcbcc9-f0f0-4397-87f2-237201fc1857">
                    <dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{partsList})]]></dataSourceExpression>
                </datasetRun>
...

サブレポートには、プロパティwhenNoDataType="AllSectionsNoDetail"などを含める必要があります。そうしないと、データがないためサブレポートが空白になります。

0
Tim

「REPORT_DATA_SOURCE」は消費可能なオブジェクトです。必要な時間だけ使用できます。

データソースをxml File dataSourceとしてテストしましたが、ALEXが言ったようには表示されません。

「これにより、サブレポートの最初の行が失われることはありません。」

私は選択するためにXPathを使用するかもしれないと思うので、毎回レコードが失われることはありません。

JDBCデータベースをデータソースとして使用している場合、pealseはsqlをパラメーターとしてサブレポートに渡します。

ResultSetをパラメーターとして使用する場合、サブバンドを詳細バンドで定義するときに1つのレコードが失われる可能性があります。

0
zg_spring

それはすでに答えられた古い質問ですが、最初のレコードの損失を回避するか、すべてのレコードをサブレポートに渡すことで、不必要なBeanをサブレポートに渡すことができます。このソリューションには、サブレポートをメインレポートとして使用でき、実際のレコードをサブレポートデータソースとして「単純に」渡すという利点があります(レポート言語としてgroovyを使用)。

<subreport>
    <reportElement x="261" y="25" width="200" height="100"/>
    <dataSourceExpression><![CDATA[new JRBeanCollectionDataSource(
       $P{REPORT_DATA_SOURCE}.data.toList().subList($V{REPORT_COUNT}-1,$V{REPORT_COUNT})]]></dataSourceExpression>
    <subreportExpression><![CDATA[$P{SUBREPORT_DIR} + "subreport.jasper"]]></subreportExpression>
</subreport>
0
jneira

datasourceパラメータが「dataSourceParam」であり、データソース値(リスト)が「Java入れたクラスのdataSourceList」であると仮定します。

final Map<String, Object> params = new HashMap<String, Object>();
JRDataSource dataSource = new ListOfArrayDataSource( dataSourceList, 
                          new String[] {"date", "age", "adress", "email"});
params.put("dataSourceParam",dataSourceList);**

メインレポートテンプレートでは、パラメーター宣言に入れます。

<parameter name="dataSourceParam" class="net.sf.jasperreports.engine.JRDataSource"/>

その後、サブレポートタグに入れます:

<subreport isUsingCache="true">
    <reportElement key="subreport-1" stretchType="RelativeToTallestObject" isPrintRepeatedValues="false" x="112" y="45" width="338" height="29"/>
    <subreportParameter name="otherParameter">
        <subreportParameterExpression><![CDATA[$P{sumM1}]]></subreportParameterExpression>
    </subreportParameter>
    <dataSourceExpression><![CDATA[$P{dataSourceParam}]]></dataSourceExpression>
    <subreportExpression class="net.sf.jasperreports.engine.JasperReport"><![CDATA[$P{subReportFile}]]></subreportExpression>
</subreport>
0
Shessuky