📜  创建子报表

📅  最后修改于: 2020-11-16 08:09:00             🧑  作者: Mango


子报表是JasperReports的出色功能之一。此功能允许将一个报表合并到另一个报表中,也就是说,一个报表可以是另一个报表的子报表。子报表可帮助我们使报表设计保持简单,因为我们可以创建许多简单报表并将其封装到主报表中。子报表的编译和填充与常规报表一样。任何报告模板在合并到另一个报告模板中时都可以用作子报告,而内部(报告模板中)没有任何更改。

子报表就像普通报表模板一样。它们实际上是net.sf.jasperreports.engine.JasperReport对象,这些对象是在编译net.sf.jasperreports.engine.design.JasperDesign对象之后获得的。

元素

将子报表引入主报表时,使用元素。这是 JRXML元素中的子元素的列表。

  • -这用于将包含报告参数的映射传递到子报告。映射通常是从主报表中的参数获得的,或者是通过使用内置的REPORTS_PARAMETERS_MAP参数将父报表的参数传递到子报表而获得的。该表达式应始终返回一个java.util.Map对象,其中的键是参数名称。

  • -此元素用于将参数传递到子报表。它具有一个属性名称,这是必需的。

  • -这用于将java.sql.Connection传递到子报表。仅在子填充模板在报告填充阶段需要数据库连接时使用。

  • -这用于将数据源传递到子报表。通常从主报表中的参数或通过使用内置的REPORT_DATA_SOURCE参数将父报表的数据源传递到子报表来获取此数据源。

  • 元素( connectionExpression和dataSourceExpression )不能在元素声明中同时出现。这是因为我们不能同时提供数据源和到子报表的连接。我们必须决定其中之一并坚持下去。

  • -这用于将子报表的变量之一的值分配给主报表的变量之一。该子元素的属性如下-

    • subreportVariable-此属性指定要返回其值的subreport变量的名称。

    • toVariable-此属性指定父报表变量的名称,其值将与子报表中的值一起复制/增加。

    • 计算-此属性可以采用以下值:Nothing,Count,DistinctCount,Sum,Average,Lowest,Highest,StandardDeviation,Variance。属性计算的默认值为“ Nothing”。

    • 递增器工厂类-此属性指定用于创建增量器实例的工厂类。

  • -这指示在哪里可以找到子报表的已编译报告模板。该元素具有属性。 class属性可以采用以下任何值:java.lang.String,java.io.File,java.net.URL,java.io.InputStream,net.sf.jasperreports.engine.JasperReport。默认值为java.lang.String

  • isUsingCache-这是元素的属性。这是一个布尔值,当设置为true时,报告引擎将尝试使用其指定的源来识别先前加载的子报告模板对象。此缓存功能仅可用于子表达式元素,这些子表达式元素具有返回java.lang.String对象作为子报告模板源的表达式,这些子表达式表示文件名,URL或类路径资源。

让我们举一个简单的例子来演示使用JRDataSource创建子报表。让我们首先编写两个新的报告模板,一个是子报告,另一个是主报告。子报表(address_report_template.jrxml)模板的内容如下所示。将其保存到C:\ tools \ jasperreports-5.0.1 \ test目录。




   
   
   
   
      
   
   
   
      <band height="20" splittype="Stretch">
         
         <statictext>
            <reportelement x="0" y="0" width="100" height="20"></reportelement>
            
            <textelement>
               <font size="14" isbold="true"></font>
            </textelement>
                
            <text></text>
         </statictext>
      
      </band>
   
   
   
      
   
   
   
      
   
   
   
      
         
         
            
            
            
               
            
            
            
               
            
         
         
         
            
            
            
               
            
            
            
               
            
         
      
      
   
   
   
      
   
  
   
      
   
   
   
      
   


在使用数据源时,我们需要编写相应的POJO文件SubReportBean.java ,如下所示。将其保存到目录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;
   }
}

在这里,我们声明了两个字段“ city”“ street”,并分别定义了getter和setter方法。

现在,让我们更新现有的DataBean文件。我们将添加一个新字段subReportBeanList ,它是一个java.util.List。该字段将保存SubReportBean对象的列表。文件DataBean的内容如下。将其保存到目录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 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 getSubReportBeanList() {
      return subReportBeanList;
   }

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

现在,我们来更新文件C:\ tools \ jasperreports-5.0.1 \ test \ src \ com \ tutorialspoint \ DataBeanList.java 。该文件的内容如下:

package com.tutorialspoint;

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

public class DataBeanList {
   public ArrayList 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 dataBeanList = new ArrayList();

      // 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 subBean) {
      DataBean dataBean = new DataBean();

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

      return dataBean;
   }
}

在上述文件的Produce()方法中,我们正在设置SubReportBean的列表。

现在,让我们编写一个新的主报告模板(jasper_report_template.jrxml)。将此文件保存到目录C:\ tools \ jasperreports-5.0.1 \ test 。该文件的内容如下-




   
      
         
      
   
   
   
   
   
   
   
      
   
   
   
      <band height="35" splittype="Stretch">
         
         <statictext>
            <reportelement x="0" y="0" width="204" height="34"></reportelement>
            
            <textelement>
               <font size="26" isbold="true"></font>
            </textelement>
                
            <text></text>
         </statictext>
      
      </band>
   
   
   
      
   
   
   
      
   
   
   
      
            
         
            
            
            
               
            
                
            
         
         
         
            
            
            
               
            
                
            
         
         
         
            
            
            
               
            
            
            
               
            
         
         
         
            
            
            
               
            
            
            
               
            
         
         
         
            

            
               new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource
                  ($F{subReportBeanList})
            
            
            
               
            
         
         
         
            
         
      
      
   
   
   
      
   
   
   
      
   
   
   
      
   


在上面的模板中,我们定义了一个新参数“ SUBREPORT_DIR”,该参数定义了子报表的路径。我们定义了一个java.util.List类型的字段subReportBeanList 它对应于文件DataBean中的属性。元素具有子元素。我们已将列表subReportBeanList放在JRBeanCollectionDataSource的实例中。在子元素中,我们指定了子报告名称(AddressReport.jasper)。

现在,让我们编写一个新类CreateReport来编译和执行我们的报告模板。文件C:\ tools \ jasperreports-5.0.1 \ test \ src \ com \ tutorialspoint \ CreateReport.java的内容如下-

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 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 parameters = new HashMap();
         parameters.put("subreportParameter", jasperSubReport);
         JasperFillManager.fillReportToFile(jasperMasterReport, 
            destFileName, parameters, beanColDataSource);

      } catch (JRException e) {

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

在这里,我们看到我们正在编译主报告模板和子报告模板,并传递了主报告(.jasper)文件来填充报告。

报告生成

现在,我们所有的文件都准备就绪,让我们使用常规的ANT构建过程进行编译和执行。文件build.xml的内容(保存在目录C:\ tools \ jasperreports-5.0.1 \ test下)如下所示。

导入文件-baseBuild.xml是从“环境设置”一章中提取的,应与build.xml放在同一目录中。



   
   
   
      
      
         
         
      
   
   
   
      
      
         
      
      
      
         
            
               
            
         
         
      
        
   


接下来,让我们打开命令行窗口并转到build.xml所在的目录。最后,如下执行命令ant -Dmain-class = com.tutorialspoint.CreateReport (viewFullReport是默认目标)-

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

经过上述编译,JasperViewer窗口打开,如下图所示:

Jasper SubReport示例

在这里,我们可以看到显示了名称,国家和地址属性。