JasperReport サブレポートの作成

最もシンプルなケースでは、JasperReports のサブレポート機能を使用して、同じテーブル、同じデータベース内の別のテーブル、または別のデータ・ソース全体から、レポートのそれぞれの行項目の関連データを出力できます。これより複雑なケースは、このトピックの範囲を超えてしまいます。 その場合に関する情報は、JasperReports の資料を参照してください。

複雑なケースでは、サブレポートにデータを提供するレポート・ハンドラーが必要になることがあります。詳しくは、『EGL レポート・ハンドラーの作成』を参照してください。一部のシンプルなケースでは、以下の 2 つの簡単なステップでサブレポートを追加することができます。
  1. メイン・レポートの設計ファイルにサブレポート・コードを追加する。
  2. サブレポート用の設計ファイルを作成する (サブレポートの数に応じて、複数作成する場合もある)。
サブレポートを作成して、それをレポートに追加する方法の基本的な例を、以下に示します。テーブル CUSTOMER からすべてのカスタマーを印刷するレポートがある場合、テーブル ORDERS からドローされる、各カスタマーのすべての送り状を示すサブレポートを追加することができます。
  1. これは、メイン・レポート設計ファイルからのコードのセクションです。このコードは元々、テーブル CUSTOMER の各カスタマーごとに 1 行を印刷するために書き込まれました。 以下の例で太字で表示されているコードを追加します。
    	<queryString><![CDATA[SELECT * FROM ADMINISTRATOR.CUSTOMER]]></queryString>
    	<field name="CUST_NO" class="java.lang.Integer">
    	</field>
    	<field name="CUST_NAME" class="java.lang.String">
    	</field>
    	<detail>
    		<band height="100">
    			<subreport>
    				<reportElement positionType="Float" mode="Opaque" x="0" y="31" 
                           width="709" height="12" isRemoveLineWhenBlank="true"/>
    				<subreportParameter name="CURRENT_CUST">
    					<subreportParameterExpression>
                <![CDATA[$F{CUST_NO}]]>
              </subreportParameterExpression>
    				</subreportParameter>
    				<connectionExpression>
    					<![CDATA[$P{REPORT_CONNECTION}]]>
    				</connectionExpression>
    				<subreportExpression class="java.lang.String">
              <![CDATA[new String("C:¥¥workspace¥¥report_project¥¥bin
                            ¥¥report_package¥¥my_subreport.jasper")]]>
            </subreportExpression>
    			</subreport>
    			<textField>
    				<reportElement positionType="Float" x="57" y="11" 
                           width="304" height="20"/>
    				<textElement/>
    				<textFieldExpression class="java.lang.String">
              <![CDATA[$F{CUST_NO} + " " +  $F{CUST_NAME}]]>
            </textFieldExpression>
    			</textField>
    		</band>
    	</detail>
    <subreport> タグは、サブレポートを実行するために必要な情報を JasperReports に提供します。
    • 位置決め情報 (メイン・レポートにあるものと同じパラメーター)
    • サブレポートに渡すパラメーター (このケースでは、現在のカスタマーの番号を指し、サブレポートの SQL SELECT 文で必要となります)
    • 接続情報 (このレポートのレポート・ドライバーによって、DataSource.databaseConnection のデータ・ソースを指定するため)
    • サブレポート用にコンパイルされたレポート設計ファイルのロケーション (このケースでは、my_subreport.jasper)
  2. サブレポート設計ファイルは、本質的には他の .jasper 設計ファイルと大差ありません。以下の基本コードを、このファイルに組み込みます。
    <parameter name="CURRENT_CUST" class="java.lang.Integer"/>
    	<queryString><![CDATA[SELECT * FROM ADMINISTRATOR.ORDERS 
                          WHERE CUST_NO = $P{CURRENT_CUST}]]></queryString>
    	<field name="CUST_NO" class="java.lang.Integer">
    	</field>
    	<field name="INVOICE_NO" class="java.lang.Integer">
    	</field>
    	<field name="ORDER_TOTAL" class="java.lang.Float">
    	</field>
    	<detail>
    		<band height="100">
    			<textField>
    				<reportElement positionType="Float" x="50" y="10" width="300" height="20"/>
    				<textElement/>
    				<textFieldExpression class="java.lang.String">
            <![CDATA["Invoice # " + $F{INVOICE_NO} + " total: " +  
                                    $F{ORDER_TOTAL}]]>
          </textFieldExpression>
    			</textField>
    		</band>
    	</detail>
    パラメーター CURRENT_CUST をサブレポートに渡した 場合でも、<parameter> タグの class= 属性を使用して、レポートにパラメーターのタイプを知らせる必要があります。 次に、照会ストリングがきます (JasperReports では、ファイル内タグの順序を非常に重要視します)。 ここで、CURRENT_CUST の値を $P{CURRENT_CUST} として参照します。このフィールド名で ORDERS テーブルの列名を参照します。 <textFieldExpression> タグ内でこれを参照することができます。

サブレポートを追加するには、これらの変更のみを行うだけで済みます。EGL レポート・ドライバー・プログラム内のコードは、変更する必要はありません。ただし、別のデータのソースまたは複雑な計算を組み込む場合は、レポート・ハンドラーを作成する必要があります (『EGL レポート・ハンドラーの作成』を参照してください)。

ネストされたサブレポートを作成することができます。例えば、3 番目のテーブルから各送り状の行項目を呼び出す可能性があります。 これによって、<subreport> タグ内の情報をサブレポート my_subreport.jasper に追加し、 ネストされたサブレポートの別の設計ファイルを作成することになります (my_invoice_subreport.jasper と呼ばれることがあります)。 サブレポートをネストできる深さに制限はありません。


フィードバック