JasperReport-Unterberichte erstellen

Im einfachsten Fall können Sie mithilfe der Funktion für Unterberichte von JasperReports zugeordnete Daten für die einzelnen Positionen in einem Bericht drucken - aus derselben Tabelle, aus einer anderen Tabelle innerhalb derselben Datenbank oder aus einer völlig anderen Datenquelle. Komplexere Fälle sprengen den Rahmen dieses Themas. Informationen dazu finden Sie in der Dokumentation zu JasperReports.

In komplexen Fällen benötigen Sie möglicherweise einen Berichtshandler, der Daten für den Unterbericht bereitstellt. Lesen Sie dazu EGL-Berichtshandler erstellen. In einigen einfachen Fällen können Sie einen Unterbericht mit zwei einfachen Schritten hinzufügen:
  1. Fügen Sie der Designdatei für den Hauptbericht Code für den Unterbericht hinzu.
  2. Erstellen Sie eine oder mehrere Designdateien für den Unterbericht bzw. die Unterberichte.
Im Folgenden finden Sie ein elementares Beispiel, wie Sie einen Unterbericht erstellen und ihn dem Bericht hinzufügen können. Wird vorausgesetzt, dass ein Bericht alle Kunden aus der Tabelle CUSTOMER druckt, können Sie einen Unterbericht hinzufügen, der für jeden Kunden alle Rechnungen anzeigt, die aus der Tabelle ORDERS gezogen werden.
  1. Dies ist ein Abschnitt mit Code aus der Hauptdatei für das Berichtsdesign. Dieser Code wurde ursprünglich geschrieben, um für jeden Kunden in der Tabelle CUSTOMER eine einzige Zeile zu drucken: Fügen Sie den im folgenden Beispiel gezeigten, fett gedruckten Code hinzu:
    	<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>
    Der Tag <subreport> gibt für JasperReports die zum Ausführen des Unterberichts erforderlichen Informationen an:
    • Daten zur Positionierung (derselbe Parameter, den Sie auch im Hauptbericht finden)
    • Parameter, die Sie an den Unterbericht übergeben wollen (in diesem Fall die Nummer des aktuellen Kunden, die Sie in der SQL-Anweisung SELECT im Unterbericht benötigen)
    • Verbindungsinformationen, da der Berichtstreiber für diesen Bericht eine Datenquelle des Typs 'DataSource.databaseConnection' angibt
    • Die Position einer kompilierten Berichtsdesigndatei für den Unterbericht (in diesem Fall 'my_subreport.jasper')
  2. Die Designdatei des Unterberichts unterscheidet sich in ihrer Art nicht von den übrigen '.jasper'-Designdateien. Schließen Sie den folgenden wesentlichen Code in diese Datei ein:
    <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>
    Auch wenn Sie den Parameter CURRENT_CUST an den Unterbericht übergeben haben, müssen Sie für den Bericht angeben, welchen Typ der Parameter aufweist. Verwenden Sie dazu das class=-Attribut des Tags <parameter>. Als Nächstes folgt die Abfragezeichenfolge (bei JasperReports muss die Reihenfolge der Tags innerhalb der Datei genau eingehalten werden). Hier referenzieren Sie den Wert von CURRENT_CUST als $P{CURRENT_CUST}. Die Feldnamen beziehen sich auf Spaltennamen in der Tabelle ORDERS, die Sie anschließend im Tag <textFieldExpression> referenzieren können.

Dies sind die einzigen Änderungen, die Sie zum Hinzufügen eines Unterberichts ausführen müssen. Sie müssen im EGL-Berichtstreiberprogramm keinen Code ändern. Möchten Sie jedoch andere Datenquellen oder komplexe Kalkulationen einschließen, müssen Sie einen Berichtshandler erstellen (siehe EGL-Berichtshandler erstellen).

Sie können verschachtelte Unterberichte erstellen. Sie können beispielsweise Positionen zu jeder Rechnung aus einer dritten Tabelle aufrufen. Dafür müssten die Informationen innerhalb des Tags <subreport> zur Unterberichtsdatei 'my_subreport.jasper' hinzugefügt und eine separate Designdatei für den verschachtelten Unterbericht erstellt werden (Sie können ihn als 'my_invoice_subreport.jasper' bezeichnen). Es gibt für die Tiefe, in der Sie Unterberichte verschachteln können, keine Begrenzung.


Feedback