JasperReport

Table of Contents

1. JasperReport 简介

JasperReports 是一个基于 Java 的开源程序库。用户使用它可以方便地生成专业的报告,支持导出 html,pdf 等多种格式。

参考:
JasperReports Ultimate Guide (pdf)
JasperReports Tutorial

1.1. JasperReports 工作流程

JasperReports 工作流程如图 1 所示。

jasperreport_lifecycle.jpg

Figure 1: JasperReport typical work flow

使用 JasperReport 生成报告的整个过程可分为下面四步:
第一步:设计报告模板。模板为 xml 格式文件,可以用文本编辑器或者 iReportDesigner 进行编辑,模板常保存为.jrxml 后缀,称为 JRXML 文件。
第二步:编译模板为二进制形式。为了提高处理速度,文本形式的模板需要编译为二进制形式,编译后的文件为.jasper,称为 Jasper 文件。
第三步:往模板中填充数据。把数据填充到模板中,得到 Jasper print 文件(后缀为.jrprint)。
第四步:导出报告。把 Jasper print 文件,根据需要导出为 html/pdf 或其他格式的最终报告文件。

各个阶段都提供有相应的 API,如图 2 所示。

jasperreport_api_overview.png

Figure 2: JasperReports API overview

1.2. Maven 工程配置

要在 Maven 工程中使用 JasperReports,在 pom.xml 中增加下面依赖即可:

    <!-- https://mvnrepository.com/artifact/net.sf.jasperreports/jasperreports -->
    <dependency>
      <groupId>net.sf.jasperreports</groupId>
      <artifactId>jasperreports</artifactId>
      <version>6.3.0</version>
    </dependency>

1.2.1. 编译.jrxml 为.jasper

设计完模板后,我们需要把模板编译为二进制形式(基于性能考虑)。这个工作可以在程序中调用 API 实现,也可以利用 maven 插件来实现。

下面介绍利用 maven 插件编译模板的过程。
首先,增加下面配置到 pom.xml。

  <build>
    <plugins>
      <plugin>
        <groupId>com.alexnederlof</groupId>
        <artifactId>jasperreports-plugin</artifactId>
        <version>2.0</version>
        <executions>
          <execution>
            <phase>process-sources</phase>
            <goals>
              <goal>jasper</goal>
            </goals>
          </execution>
        </executions>
        <configuration>
          <!-- These are the default configurations: -->
          <compiler>net.sf.jasperreports.engine.design.JRJdtCompiler</compiler>
          <sourceDirectory>src/main/jasperreports</sourceDirectory>
          <outputDirectory>${project.build.directory}/jasper</outputDirectory>
          <outputFileExt>.jasper</outputFileExt>
          <xmlValidation>true</xmlValidation>
          <verbose>false</verbose>
          <numberOfThreads>4</numberOfThreads>
          <failOnMissingSourceDirectory>true</failOnMissingSourceDirectory>
          <sourceScanner>org.codehaus.plexus.compiler.util.scan.StaleSourceScanner</sourceScanner>
        </configuration>
      </plugin>
    </plugins>
  </build>

然后,运行 mvn compile 或者 mvn package 时,会先编译模板文件。目录 src/main/jasperreports 下的.jrxml 文件都会编译为相应的二进制.jasper 文件,生成目录为 target/jasper/。

参考:https://github.com/alexnederlof/Jasper-report-maven-plugin

2. JasperReport 简单实例

下面例子摘自:https://www.tutorialspoint.com/jasper_reports/jasper_exporting_reports.htm

这个例子比较简单,报告内容为一个表格,表格中有人名以及所在国家。

第一步,设计模板文件 report.jrxml,如下所示。

<?xml version = "1.0" encoding = "UTF-8"?>
<!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN"
   "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">

<jasperReport name = "jasper_report_template">

   <queryString>
      <![CDATA[]]>
   </queryString>

   <field name = "country" class = "java.lang.String">
      <fieldDescription><![CDATA[country]]></fieldDescription>
   </field>

   <field name = "name" class = "java.lang.String">
      <fieldDescription><![CDATA[name]]></fieldDescription>
   </field>

   <columnHeader>
      <band height = "23">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "3"
               width = "535" height = "15" backcolor = "#70A9A9" />

            <box>
               <bottomPen lineWidth = "1.0" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <staticText>
            <reportElement x = "414" y = "3" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Country]]></text>
         </staticText>

         <staticText>
            <reportElement x = "0" y = "3" width = "136" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font isBold = "true" />
            </textElement>

            <text><![CDATA[Name]]></text>
         </staticText>

      </band>
   </columnHeader>

   <detail>
      <band height = "16">

         <staticText>
            <reportElement mode = "Opaque" x = "0" y = "0"
               width = "535" height = "14" backcolor = "#E5ECF9" />

            <box>
               <bottomPen lineWidth = "0.25" lineColor = "#CCCCCC" />
            </box>

            <textElement />
            <text><![CDATA[]]> </text>
         </staticText>

         <textField>
            <reportElement x = "414" y = "0" width = "121" height = "15" />

            <textElement textAlignment = "Center" verticalAlignment = "Middle">
               <font size = "9" />
            </textElement>

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{country}]]>
            </textFieldExpression>
         </textField>

         <textField>
            <reportElement x = "0" y = "0" width = "136" height = "15" />
            <textElement textAlignment = "Center" verticalAlignment = "Middle" />

            <textFieldExpression class = "java.lang.String">
               <![CDATA[$F{name}]]>
            </textFieldExpression>
         </textField>

      </band>
   </detail>

</jasperReport>

第二步,把上面文件编译为二进制的模板文件 report.jasper,过程略(通过前面介绍的 maven 插件可以自动完成)。

第三步,准备填充的数据。这个例子中,通过下面两个 java 文件实现。

public class DataBean {
    private String name;
    private String country;

    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;
    }
}
import java.util.ArrayList;

public class DataBeanList {
   public ArrayList<DataBean> getDataBeanList() {
      ArrayList<DataBean> dataBeanList = new ArrayList<DataBean>();

      dataBeanList.add(produce("Manisha", "India"));
      dataBeanList.add(produce("Dennis Ritchie", "USA"));
      dataBeanList.add(produce("V.Anand", "India"));
      dataBeanList.add(produce("Shrinath", "California"));

      return dataBeanList;
   }

   /**
    * This method returns a DataBean object,
    * with name and country set in it.
    */
   private DataBean produce(String name, String country) {
      DataBean dataBean = new DataBean();
      dataBean.setName(name);
      dataBean.setCountry(country);

      return dataBean;
   }
}

第四步,生成报告。这里生成 pdf 和 html 格式的报告。

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

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

public class App
{
    public static void main(String[] args) {
        String sourceFileName = "/Users/cig01/first-jasperreport-app/target/jasper/report.jasper";
        String printFileName = null;
        DataBeanList DataBeanList = new DataBeanList();
        ArrayList<DataBean> dataList = DataBeanList.getDataBeanList();
        JRBeanCollectionDataSource beanColDataSource =
           new JRBeanCollectionDataSource(dataList);

        Map<String, Object> parameters = new HashMap<String, Object>();
        try {
           printFileName = JasperFillManager.fillReportToFile(sourceFileName,
              parameters, beanColDataSource);
           if (printFileName != null) {
              /**
               * 1- export to PDF
               */
              JasperExportManager.exportReportToPdfFile(printFileName,
                 "/Users/cig01/first-jasperreport-app/sample_report.pdf");

              /**
               * 2- export to HTML
               */
              JasperExportManager.exportReportToHtmlFile(printFileName,
                 "/Users/cig01/first-jasperreport-app/sample_report.html");
           }
        } catch (JRException e) {
           e.printStackTrace();
        }
     }
}

运行程序,得到的 sample_report.pdf 或者 sample_report.html,看起来如图 3 所示。

jasperreport_example.gif

Figure 3: JasperReport 导出报告的简单实例

Author: cig01

Created: <2017-03-30 Thu>

Last updated: <2017-12-13 Wed>

Creator: Emacs 27.1 (Org mode 9.4)