Unterberichte erstellen

Unterberichte sind eine der netten Eigenschaften der JasperReports. Diese Funktion ermöglicht das Einfügen eines Berichts in einen anderen Bericht, dh ein Bericht kann ein Unterbericht eines anderen sein. Unterberichte helfen uns dabei, Berichtsentwürfe einfach zu halten, da wir viele einfache Berichte erstellen und in einen Masterbericht einkapseln können. Unterberichte werden wie normale Berichte zusammengestellt und gefüllt. Jede Berichtsvorlage kann als Unterbericht verwendet werden, wenn sie in eine andere Berichtsvorlage aufgenommen wird, ohne dass sich darin (der Berichtsvorlage) etwas ändert.

Unterberichte sind wie normale Berichtsvorlagen. Es handelt sich tatsächlich um net.sf.jasperreports.engine.JasperReport- Objekte, die nach dem Kompilieren eines net.sf.jasperreports.engine.design.JasperDesign-Objekts erhalten werden .

<Unterbericht> Element

Ein <subreport> -Element wird verwendet, wenn Unterberichte in Masterberichte eingefügt werden. Hier ist die Liste der Unterelemente im JRXML-Element <subreport>.

  • <reportElement>

  • <parametersMapExpression> - Hiermit wird eine Karte mit Berichtsparametern an den Unterbericht übergeben. Die Zuordnung wird normalerweise aus einem Parameter im Masterbericht oder mithilfe des integrierten Parameters REPORTS_PARAMETERS_MAP abgerufen, um die Parameter des übergeordneten Berichts an den Unterbericht zu übergeben. Dieser Ausdruck sollte immer ein java.util.Map- Objekt zurückgeben, in dem die Schlüssel die Parameternamen sind.

  • <subreportParameter> - Dieses Element wird verwendet, um Parameter an den Unterbericht zu übergeben. Es verfügt über ein Attribut Namen , die obligatorisch ist.

  • <connectionExpression> - Hiermit wird eine java.sql.Connection an den Unterbericht übergeben. Es wird nur verwendet, wenn die Unterberichtsvorlage während der Berichtsfüllphase eine Datenbankverbindung benötigt.

  • <dataSourceExpression> - Hiermit wird eine Datenquelle an den Unterbericht übergeben. Diese Datenquelle wird normalerweise aus einem Parameter im Masterbericht oder mithilfe des integrierten Parameters REPORT_DATA_SOURCE abgerufen, um die Datenquelle des übergeordneten Berichts an den Unterbericht zu übergeben.

  • Die Elemente ( connectionExpression und dataSourceExpression ) können nicht gleichzeitig in einer <subreport> -Elementdeklaration vorhanden sein. Dies liegt daran, dass wir nicht sowohl eine Datenquelle als auch eine Verbindung zum Unterbericht bereitstellen können. Wir müssen uns für einen von ihnen entscheiden und dabei bleiben.

  • <returnValue> - Hiermit wird der Wert einer der Variablen des Unterberichts einer der Variablen des Masterberichts zugewiesen. Dieses Unterelement hat folgende Attribute:

    • subreportVariable - Dieses Attribut gibt den Namen der Unterberichtsvariablen an, deren Wert zurückgegeben werden soll.

    • toVariable - Dieses Attribut gibt den Namen der übergeordneten Berichtsvariablen an, deren Wert mit dem Wert aus dem Unterbericht kopiert / inkrementiert werden soll.

    • Berechnung - Dieses Attribut kann Werte annehmen: Nichts, Anzahl, DistinctCount, Summe, Durchschnitt, Niedrigster, Höchster, Standardabweichung, Varianz. Der Standardwert für das Attribut Berechnung ist „Nothing“.

    • incrementerFactoryClass - Dieses Attribut gibt die Factory-Klasse zum Erstellen der Inkrementer-Instanz an.

  • <subreportExpression> - Gibt an, wo sich die kompilierte Berichtsvorlage für den Unterbericht befindet. Dieses Element hat eineclassAttribut. Das Klassenattribut kann einen der folgenden Werte annehmen: java.lang.String, java.io.File, java.net.URL, java.io.InputStream, net.sf.jasperreports.engine.JasperReport. Der Standardwert ist java.lang.String .

  • isUsingCache - Dies ist ein Attribut des <subreport> -Elements. Dies ist ein Boolescher Wert. Wenn der Wert auf " true" gesetzt ist, versucht die Berichts-Engine, zuvor geladene Unterbericht-Vorlagenobjekte anhand ihrer angegebenen Quelle zu erkennen. Diese Caching-Funktion ist nur für Unterberichtselemente verfügbar, deren Ausdrücke java.lang.String-Objekte als Unterberichtvorlagenquelle zurückgeben, die Dateinamen, URLs oder Klassenpfadressourcen darstellen.

Beispiel

Nehmen Sie ein einfaches Beispiel, um die Erstellung von Unterberichten mit JRDataSource zu demonstrieren. Schreiben wir zunächst zwei neue Berichtsvorlagen, eine als Unterbericht und eine als Masterbericht. Der Inhalt der Vorlage für den Unterbericht (address_report_template.jrxml) ist wie folgt. Speichern Sie es im Verzeichnis C: \ tools \ jasperreports-5.0.1 \ test.

<?xml version = "1.0" encoding = "UTF-8"?>
<jasperReport
   xmlns = "http://jasperreports.sourceforge.net/jasperreports"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://jasperreports.sourceforge.net/jasperreports
   http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
   name = "address_report_template" pageWidth = "175" pageHeight = "842" 
   columnWidth = "175" leftMargin = "0" rightMargin = "0" 
   topMargin = "0" bottomMargin = "0">

   <field name = "city" class = "java.lang.String"/>
   <field name = "street" class = "java.lang.String"/>
   
   <background>
      <band splitType = "Stretch"/>
   </background>
   
   <title>
      <band height = "20" splitType = "Stretch">
         
         <staticText>
            <reportElement x = "0" y = "0" width = "100" height = "20"/>
            
            <textElement>
               <font size = "14" isBold = "true"/>
            </textElement>
				
            <text><![CDATA[Addresses]]></text>
         </staticText>
      
      </band>
   </title>
   
   <pageHeader>
      <band height = "12" splitType = "Stretch"/>
   </pageHeader>
   
   <columnHeader>
      <band height = "12" splitType = "Stretch"/>
   </columnHeader>
   
   <detail>
      <band height = "27" splitType = "Stretch">
         
         <textField>
            <reportElement x = "0" y = "0" width = "120" height = "20"/>
            
            <textElement>
               <font size = "12" isBold = "true"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{city}+" Address:"]]>
            </textFieldExpression>
         </textField>
         
         <textField isStretchWithOverflow = "true">
            <reportElement x = "120" y = "0" width = "435" height = "20"/>
            
            <textElement>
               <font size = "12"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{street}]]>
            </textFieldExpression>
         </textField>
      
      </band>
   </detail>
   
   <columnFooter>
      <band height = "8" splitType = "Stretch"/>
   </columnFooter>
  
   <pageFooter>
      <band height = "11" splitType = "Stretch"/>
   </pageFooter>
   
   <summary>
      <band height = "9" splitType = "Stretch"/>
   </summary>

</jasperReport>

Da wir eine Datenquelle verwenden, müssen wir eine entsprechende POJO-Datei schreiben SubReportBean.java Wie nachfolgend dargestellt. Speichern Sie es im Verzeichnis C: \ tools \ jasperreports-5.0.1 \ test \ src \ com \ tutorialspoint -

package com.tutorialspoint;

public class SubReportBean {
   private String city;
   private String street;

   public String getCity() {
      return city;
   }

   public void setCity(String city) {
      this.city = city;
   }

   public String getStreet() {
      return street;
   }

   public void setStreet(String street) {
      this.street = street;
   }
}

Hier haben wir zwei Felder 'Stadt' und 'Straße' deklariert und entsprechende Getter- und Setter-Methoden definiert.

Jetzt aktualisieren wir unsere bestehenden DataBeanDatei. Wir werden ein neues Feld subReportBeanList hinzufügen , das eine java.util.List ist. Dieses Feld enthält die Liste der SubReportBean-Objekte. Der Inhalt der Datei DataBean ist wie folgt. Speichern Sie es im Verzeichnis C: \ tools \ jasperreports-5.0.1 \ test \ src \ com \ tutorialspoint.

package com.tutorialspoint;

import java.util.List;

public class DataBean {
   private String name;
   private String country;
   private List<SubReportBean> subReportBeanList;

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public String getCountry() {
      return country;
   }

   public void setCountry(String country) {
      this.country = country;
   }

   public List<SubReportBean> getSubReportBeanList() {
      return subReportBeanList;
   }

   public void setSubReportBeanList(List<SubReportBean> subReportBeanList) {
      this.subReportBeanList = subReportBeanList;
   }
}

Lassen Sie uns nun die Datei C: \ tools \ jasperreports-5.0.1 \ test \ src \ com \ tutorialspoint \ aktualisierenDataBeanList.java. Der Inhalt dieser Datei ist wie folgt:

package com.tutorialspoint;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {

      // Create sub report data
      SubReportBean subBean1 = new SubReportBean();
      subBean1.setCity("Mumbai");
      subBean1.setStreet("M.G.Road");
      SubReportBean subBean2 = new SubReportBean();
      subBean2.setCity("New York");
      subBean2.setStreet("Park Street");
      SubReportBean subBean3 = new SubReportBean();
      subBean3.setCity("San Fransisco");
      subBean3.setStreet("King Street");

      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      // Create master report data
      dataBeanList.add(produce("Manisha", "India",
         Arrays.asList(subBean1)));
      dataBeanList.add(produce("Dennis Ritchie", "USA",
         Arrays.asList(subBean2)));
      dataBeanList.add(produce("V.Anand", "India",
         Arrays.asList(subBean1)));
      dataBeanList.add(produce("Shrinath", "California",
         Arrays.asList(subBean3)));

      return dataBeanList;
   }

   /*
    * This method returns a DataBean object,
    * with name, country and sub report
    * bean data set in it.
    */
   private DataBean produce(String name, String country,
      List<SubReportBean> subBean) {
      DataBean dataBean = new DataBean();

      dataBean.setName(name);
      dataBean.setCountry(country);
      dataBean.setSubReportBeanList(subBean);

      return dataBean;
   }
}

In der Methode generate () in der obigen Datei legen wir die Liste von SubReportBean fest.

Schreiben wir nun eine neue Master-Berichtsvorlage (jasper_report_template.jrxml). Speichern Sie diese Datei im VerzeichnisC:\tools\jasperreports-5.0.1\test. Der Inhalt dieser Datei ist wie folgt:

<?xml version = "1.0" encoding = "UTF-8"?>
<jasperReport xmlns = "http://jasperreports.sourceforge.net/jasperreports"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://jasperreports.sourceforge.net/jasperreports
   http://jasperreports.sourceforge.net/xsd/jasperreport.xsd"
   name = "jasper_report_template" language = "groovy" pageWidth = "595"
   pageHeight = "842" columnWidth ="555" leftMargin = "20" rightMargin = "20"
   topMargin = "20" bottomMargin = "20">

   <parameter name = "SUBREPORT_DIR" class = "java.lang.String" isForPrompting = "false">
      <defaultValueExpression>
         <![CDATA["C:\\tools\\jasperreports-5.0.1\\test\\"]]>
      </defaultValueExpression>
   </parameter>
   
   <field name = "country" class = "java.lang.String"/>
   <field name = "name" class = "java.lang.String"/>
   <field name = "subReportBeanList" class = "java.util.List"/>
   
   <background>
      <band splitType = "Stretch"/>
   </background>
   
   <title>
      <band height = "35" splitType = "Stretch">
         
         <staticText>
            <reportElement x = "0" y = "0" width = "204" height = "34"/>
            
            <textElement>
               <font size = "26" isBold = "true"/>
            </textElement>
				
            <text><![CDATA[Contact Report]]></text>
         </staticText>
      
      </band>
   </title>
   
   <pageHeader>
      <band height = "17" splitType = "Stretch"/>
   </pageHeader>
   
   <columnHeader>
      <band height = "21" splitType = "Stretch"/>
   </columnHeader>
   
   <detail>
      <band height = "112" splitType = "Stretch">
            
         <staticText>
            <reportElement x = "0" y = "0" width = "100" height = "20"/>
            
            <textElement>
               <font size = "12" isBold = "true"/>
            </textElement>
				
            <text><![CDATA[Name:]]></text>
         </staticText>
         
         <staticText>
            <reportElement x = "0" y = "20" width = "100" height = "20"/>
            
            <textElement>
               <font size = "12" isBold = "true"/>
            </textElement>
				
            <text><![CDATA[Country:]]></text>
         </staticText>
         
         <textField>
            <reportElement x = "104" y = "0" width = "277" height = "20"/>
            
            <textElement>
               <font size = "12"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>
         
         <textField>
            <reportElement x = "104" y = "20" width = "277" height = "20"/>
            
            <textElement>
               <font size = "12"/>
            </textElement>
            
            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>
         
         <subreport>
            <reportElement positionType = "Float" x = "335" y = "25" width = "175"
               height = "20" isRemoveLineWhenBlank = "true" backcolor = "#99ccff"/>

            <dataSourceExpression>
               new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
                  ($F{subReportBeanList})
            </dataSourceExpression>
            
            <subreportExpression class = "java.lang.String">
               <![CDATA[$P{SUBREPORT_DIR} + "address_report_template.jasper"]]>
            </subreportExpression>
         </subreport>
         
         <line>
            <reportElement x = "0" y = "50" width = "550" height = "1"/>
         </line>
      
      </band>
   </detail>
   
   <columnFooter>
      <band height = "19" splitType = "Stretch"/>
   </columnFooter>
   
   <pageFooter>
      <band height = "18" splitType = "Stretch"/>
   </pageFooter>
   
   <summary>
      <band height = "14" splitType = "Stretch"/>
   </summary>

</jasperReport>

In der obigen Vorlage haben wir einen neuen Parameter "SUBREPORT_DIR" definiert, der den Pfad des Unterberichts definiert. Wir haben ein Feld subReportBeanList vom Typ java.util.List definiert, das der Eigenschaft in der Datei DataBean entspricht. Das Element <subreport> hat das Unterelement <dataSourceExpression>. Wir haben die Liste subReportBeanList in eine Instanz von JRBeanCollectionDataSource eingefügt. Im Unterelement <subreportExpression /> haben wir den Namen des Unterberichts (AddressReport.jasper) angegeben.

Jetzt schreiben wir eine neue Klasse CreateReportum unsere Berichtsvorlage zu kompilieren und auszuführen. Der Inhalt der DateiC:\tools\jasperreports-5.0.1\test\src\com\tutorialspoint\CreateReport.java sind wie unten angegeben -

package com.tutorialspoint;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class CreateReport {

   public static void main(String[] args) {
      String masterReportFileName = "C://tools/jasperreports-5.0.1/test"
         + "/jasper_report_template.jrxml";
      String subReportFileName = "C://tools/jasperreports-5.0.1/test"
         + "/AddressReport.jrxml";
      String destFileName = "C://tools/jasperreports-5.0.1/test"
         + "/jasper_report_template.JRprint";
			
      DataBeanList DataBeanList = new DataBeanList();
      ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();
      JRBeanCollectionDataSource beanColDataSource = new 
         JRBeanCollectionDataSource(dataList);

      try {
         /* Compile the master and sub report */
         JasperReport jasperMasterReport = JasperCompileManager
            .compileReport(masterReportFileName);
         JasperReport jasperSubReport = JasperCompileManager
            .compileReport(subReportFileName);

         Map<String, Object> parameters = new HashMap<String, Object>();
         parameters.put("subreportParameter", jasperSubReport);
         JasperFillManager.fillReportToFile(jasperMasterReport, 
            destFileName, parameters, beanColDataSource);

      } catch (JRException e) {

         e.printStackTrace();
      }
      System.out.println("Done filling!!! ...");
   }
}

Hier sehen wir, dass wir sowohl die Master- als auch die Unterberichtsvorlagen kompilieren und die Master-Berichtsdatei (.jasper) für die Berichtsfüllung übergeben.

Berichterstellung

Jetzt sind alle unsere Dateien fertig. Kompilieren Sie sie und führen Sie sie mit unserem regulären ANT-Erstellungsprozess aus. Der Inhalt der Datei build.xml (gespeichert im Verzeichnis C: \ tools \ jasperreports-5.0.1 \ test) ist wie folgt.

Die Importdatei - baseBuild.xml wird aus dem Kapitel Umgebungs-Setup übernommen und sollte im selben Verzeichnis wie die build.xml abgelegt werden.

<?xml version = "1.0" encoding = "UTF-8"?>
<project name = "JasperReportTest" default = "viewFillReport" basedir = ".">
   <import file = "baseBuild.xml" />
   
   <target name = "viewFillReport" depends = "compile,compilereportdesing,run"
      description = "Launches the report viewer to preview the 
      report stored in the .JRprint file.">
      
      <java classname = "net.sf.jasperreports.view.JasperViewer" fork = "true">
         <arg value = "-F${file.name}.JRprint" />
         <classpath refid = "classpath" />
      </java>
   </target>
   
   <target name = "compilereportdesing" description = "Compiles the JXML file and
      produces the .jasper file.">
      
      <taskdef name = "jrc" classname = "net.sf.jasperreports.ant.JRAntCompileTask">
         <classpath refid = "classpath" />
      </taskdef>
      
      <jrc destdir = ".">
         <src>
            <fileset dir = ".">
               <include name = "*.jrxml" />
            </fileset>
         </src>
         <classpath refid = "classpath" />
      </jrc>
		
   </target>

</project>

Öffnen Sie als Nächstes das Befehlszeilenfenster und wechseln Sie in das Verzeichnis, in dem build.xml abgelegt ist. Führen Sie abschließend den Befehl ausant -Dmain-class=com.tutorialspoint.CreateReport (viewFullReport ist das Standardziel) wie folgt:

Buildfile: C:\tools\jasperreports-5.0.1\test\build.xml

clean-sample:
   [delete] Deleting directory C:\tools\jasperreports-5.0.1\test\classes

compile:
   [mkdir] Created dir: C:\tools\jasperreports-5.0.1\test\classes
   [javac] C:\tools\jasperreports-5.0.1\test\baseBuild.xml:28: 
      warning: 'includeantruntime' was not set, defaulting to
   [javac] Compiling 7 source files to C:\tools\jasperreports-5.0.1\test\classes

compilereportdesing:
   [jrc] Compiling 1 report design files.
   [jrc] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [jrc] log4j:WARN Please initialize the log4j system properly.
   [jrc] log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig 
      for more info.
   [jrc] File : C:\tools\jasperreports-5.0.1\test\
      jasper_report_template.jrxml ... OK.

run:
   [echo] Runnin class : com.tutorialspoint.CreateReport
   [java] Compiling Report Design ...
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.engine.xml.JRXmlDigesterFactory).
   [java] log4j:WARN Please initialize the log4j system properly.
   [java] Done filling!!! ...

viewFillReport:
   [java] log4j:WARN No appenders could be found for logger
   (net.sf.jasperreports.extensions.ExtensionsEnvironment).
   [java] log4j:WARN Please initialize the log4j system properly.

BUILD SUCCESSFUL
Total time: 72 minutes 13 seconds

Als Ergebnis der obigen Kompilierung wird ein JasperViewer-Fenster geöffnet, wie im folgenden Bildschirm gezeigt -

Hier sehen wir, dass die Attribute Name, Land und Adresse angezeigt werden.