天天看点

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

一. PDF报表打印概述

1 概述

在企业级应用开发中,报表生成、报表打印下载是其重要的一个环节。在之前的课程中我们已经学习了报表中比较重要的一种:Excel报表。其实除了Excel报表之外,PDF报表也有广泛的应用场景,必须用户详细资料,用户简历等。

2 常见PDF报表的制作方式

目前世面上比较流行的制作PDF报表的工具如下:

  1. iText PDF:iText是著名的开放项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。
  2. Openoffice:openoffice是开源软件且能在windows和linux平台下运行,可以灵活的将word或者Excel转化为PDF文档。
  3. Jasper Report:是一个强大、灵活的报表生成工具,能够展示丰富的页面内容,并将之转换成PDF.

3 JasperReport框架的介绍

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

JasperReport是一个强大、灵活的报表生成工具,能够展示丰富的页面内容,并将之转换成PDF,HTML,或者XML格式。该库完全由Java写成,可以用于在各种Java应用程序,包括J2EE,Web应用程序中生成动态内容。只需要将JasperReport引入工程中即可完成PDF报表的编译、显示、输出等工作。

  • 在开源的JAVA报表工具中,JASPER Report发展是比较好的,比一些商业的报表引擎做得还好,如支持了十字交叉报表、统计报表、图形报表,支持多种报表格式的输出,如PDF、RTF、XML、CSV、XHTML、TEXT、DOCX以及OpenOffice。
  • 数据源支持更多,常用 JDBC SQL查询、XML文件、CSV文件 、HQL(Hibernate查询),HBase,JAVA集合等。还允许你义自己的数据源,通过JASPER文件及数据源,JASPER就能生成最终用户想要的文档格式。

二. JasperReport的开发步骤

1 JasperReport生命周期

通常我们提到PDF报表的时候,浮现在脑海中的是最终的PDF文档文件。在JasperReports中,这只是报表生命周期的最后阶段。通过JasperReports生成PDF报表一共要经过三个阶段,我们称之为 JasperReport的生命周期,这三个阶段为:设计(Design)阶段、执行(Execution)阶段以及输出(Export)阶段,如下图所示:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio
  1. 设计阶段(Design):所谓的报表设计就是创建一些模板,模板包含了报表的布局与设计,包括执行计算的复杂公式、可选的从数据源获取数据的查询语句、以及其它的一些信息。模板设计完成之后,我们将模板保存为JRXML文件(JR代表JasperReports),其实就是一个XML文件。
  2. 执行阶段(Execution):使用以JRXML文件编译为可执行的二进制文件(即.Jasper文件)结合数据进行执行,填充报表数据。
  3. 输出阶段(Export):数据填充结束,可以指定输出为多种形式的报表。

2 JasperReport原理简述

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio
  1. JRXML:报表填充模板,本质是一个XML。

    JasperReport已经封装了一个dtd,只要按照规定的格式写这个xml文件,那么jasperReport就可以将其解析最终生成报表,但是jasperReport所解析的不是我们常见的.xml文件,而是.jrxml文件,其实跟xml是一样的,只是后缀不一样。

  2. Jasper:由JRXML模板编译生成的二进制文件,用于代码填充数据。

    解析完成后JasperReport就开始编译.jrxml文件,将其编译成.jasper文件,因为JasperReport只可以对.jasper文件进行填充数据和转换,这步操作就跟我们java中将java文件编译成class文件是一样的。

  3. Jrprint:当用数据填充完Jasper后生成的文件,用于输出报表。

    这一步才是JasperReport的核心所在,它会根据你在xml里面写好的查询语句来查询指定是数据库,也可以控制在后台编写查询语句,参数,数据库。在报表填充完后,会再生成一个.jrprint格式的文件(读取jasper文件进行填充,然后生成一个jrprint文件)。

  4. Exporter:决定要输出的报表为何种格式,报表输出的管理类。
  5. Jasperreport可以输出多种格式的报表文件,常见的有Html,PDF,xls等。

3 开发流程概述

  • 制作报表模板
  • 模板编译
  • 构造数据
  • 填充模板数据

三. 模板工具Jaspersoft Studio

1 概述

Jaspersoft Studio是JasperReports库和JasperReports服务器的基于Eclipse的报告设计器; 它可以作为Eclipse插件或作为独立的应用程序使用。Jaspersoft Studio允许您创建包含图表,图像,子报表,交叉表等的复杂布局。您可以通过JDBC,TableModels,JavaBeans,XML,Hibernate,大数据(如Hive),CSV,XML / A以及自定义来源等各种来源访问数据,然后将报告发布为PDF,RTF, XML,XLS,CSV,HTML,XHTML,文本,DOCX或OpenOffice。

Jaspersoft Studio 是一个可视化的报表设计工具,使用该软件可以方便地对报表进行可视化的设计,设计结果为格式.jrxml 的 XML 文件,并且可以把.jrxml 文件编译成.jasper 格式文件方便 JasperReport 报表引擎解析、显示。

2 安装配置

到JasperReport官网下载 https://community.jaspersoft.com/community-download

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

下载 Library Jar包(传统导入jar包工程需下载)和模板设计器Jaspersoft studio。并安装Jaspersoft studio,安装的过程比较简单,一直下一步直至安装成功即可。

3 面板介绍

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio
  • Report editing area (主编辑区域)中,您直观地通过拖动,定位,对齐和通过 Designer palette(设计器调色板)对报表元素调整大小。JasperSoft Studio 有一个多标签编辑器,Design,Source 和 Preview:
    1. Design tab:当你打开一个报告文件,它允许您以图形方式创建报表选中
    2. Source tab: 包含用于报表的 JRXML 源代码。
    3. Preview tab: 允许在选择数据源和输出格式后,运行报表预览。
  • Repository Explorer view:包含 JasperServer 生成的连接和可用的数据适配器列表
  • Project Explorer view:包含 JasperReports 的工程项目清单
  • Outline view:在大纲视图中显示了一个树的形式的方式报告的完整结构。
  • Properties view:通常是任何基于 Eclipse 的产品/插件的基础之一。它通常被填充与实际所选元素的属性的信息。这就是这样,当你从主设计区域(即:一个文本字段)选择一个报表元素或从大纲,视图显示了它的信息。其中一些属性可以是只读的,但大部分都是可编辑的,对其进行修改,通常会通知更改绘制的元素(如:元素的宽度或高度)。
  • Problems view:显示的问题和错误,例如可以阻断报告的正确的编译。
  • Report state summary 提供了有关在报表编译/填充/执行统计用户有用的信息。错误会显示在这里。

4 基本使用

4.1 模板制作

(1)打开Jaspersoft Studio ,新建一个project。 步骤: File -> New -> Project-> JasperReports Project。

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(2)新建一个Jasper Report模板,在 Stidio的左下方Project Explorer 找到刚才新建的Project (我这里新建的是JasperProject)。步骤:项目右键 -> New -> Jasper Report

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio
PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(3)选择 Blank A4 (A4纸大小的模板),然后 Next 命名为DemoReport1.jrxml,点击Finish。

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

如图所示,报表模板被垂直的分层,每一个部分都是一个Band,每一个Band的特点不同:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio
  • Title(标题):只在整个报表的第一页的最上端显示。只在第一页显示,其他页面均不显示。
  • Page Header(页头):在整个报表中每一页都会显示。在第一页中,出现的位置在 Title Band的下面。在除了第一页的其他页面中Page Header 的内容均在页面的最上端显示。
  • Page Footer(页脚):在整个报表中每一页都会显示。显示在页面的最下端。一般用来显示页码。
  • Detail 1(详细):报表内容,每一页都会显示。
  • Column Header(列头):Detail中打印的是一张表的话,这Column Header就是表中列的列头。
  • Column Footer(列脚):Detail中打印的是一张表的话,这Column Footer就是表中列的列脚。
  • Summary(统计):表格的合计段,出现在整个报表的最后一页中,在Detail 1 Band后面。主要是用来做报表的合计显示。

4.2 编译模板

在右侧Palette里选择static text文本框,里面输入“Jasper Test”

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

我们可以右键单机模板文件 -> compile Report 对模板进行编译,生成.jasper文件。也可以用java代码生成。

右键生成:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

代码生成:

(1)新建工程引入坐标
<dependencies>
        <dependency>
            <groupId>net.sf.jasperreports</groupId>
            <artifactId>jasperreports</artifactId>
            <version>6.5.0</version>
        </dependency>
        <dependency>
            <groupId>org.olap4j</groupId>
            <artifactId>olap4j</artifactId>
            <version>1.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.lowagie</groupId>
            <artifactId>itext</artifactId>
            <version>2.1.7</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.0.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>4.0.1</version>
        </dependency>
    </dependencies>
           
(2)代码实现
package com.wsw;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.view.JasperViewer;

import java.util.HashMap;

public class JasperTest {
    public static void main(String[] args) {
        //createJasper();
        //createJrprint();
        showPdf();
    }

    //1.将pdf模板编译为Jasper文件
    public static void createJasper(){
        try{
            String path = "C:\\Users\\21134\\Desktop\\DemoReport1.jrxml";
            JasperCompileManager.compileReportToFile(path);
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    //2.将Jasper文件和数据进行填充,获取Jrprint
    public static void createJrprint(){
        try{
            String path = "C:\\Users\\21134\\Desktop\\DemoReport1.jasper";
            //通过空参数和空数据源进行填充
            JasperFillManager.fillReportToFile(path,new HashMap(),new JREmptyDataSource());
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    //3.预览
    public static void showPdf(){
        try{
            String path = "C:\\Users\\21134\\Desktop\\DemoReport1.jrprint";
            JasperViewer.viewReport(path,false);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
           
(3)实现结果

文件生成位置:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

最终展示效果:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

4.3 整合SpringBoot工程

(1)新建SpringBoot工程引入坐标
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.5.RELEASE</version>
    <relativePath/>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>net.sf.jasperreports</groupId>
        <artifactId>jasperreports</artifactId>
        <version>6.5.0</version>
    </dependency>
    <dependency>
        <groupId>org.olap4j</groupId>
        <artifactId>olap4j</artifactId>
        <version>1.2.0</version>
    </dependency>
    <dependency>
        <groupId>com.lowagie</groupId>
        <artifactId>itext</artifactId>
        <version>2.1.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>4.0.1</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>
           
(2)引入配置文件
server:
    port: 8181
spring:
    application:
        name: jasper-demo #指定服务名
    datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/ihrm?useUnicode=true&characterEncoding=utf8
        username: root
        password: root
           
(3)创建启动类
@SpringBootApplication(scanBasePackages = "com.xxx")
public class JasperApplication {
	public static void main(String[] args) {
		SpringApplication.run(JasperApplication.class, args);
	}
}
           
(4)导入生成的.jasper文件
(5)创建测试controller
@RestController
public class JasperController {
    @GetMapping("/testJasper")
    public void createHtml(HttpServletResponse response, HttpServletRequest request)throws Exception{
        //引入jasper文件。由JRXML模板编译生成的二进制文件,用于代码填充数据
        Resource resource = new ClassPathResource("templates/test01.jasper");
        //加载jasper文件创建inputStream
        FileInputStream isRef = new FileInputStream(resource.getFile());
        ServletOutputStream sosRef = response.getOutputStream();
        try {
            //创建JasperPrint对象
            JasperPrint jasperPrint = JasperFillManager.fillReport(isRef, new HashMap<>(),new JREmptyDataSource());
            //写入pdf数据
            JasperExportManager.exportReportToPdfStream(jasperPrint,sosRef);
        } finally {
            sosRef.flush();
            sosRef.close();
        }
    }
}
           

4.4 中文处理

(1)设计阶段需要指定中文样式

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(2)通过手动指定中文字体的形式解决中文不现实

  • 添加properties文件:
net.sf.jasperreports.extension.registry.factory.simple.font.families=net.sf.jasperreports.engine.fonts.SimpleFontExtensionsRegistryFactory
net.sf.jasperreports.extension.simple.font.families.lobstertwo=stsong/fonts.xml
           
  • 指定中文配置文件fonts.xml
<?xml version="1.0" encoding="UTF-8"?>
<fontFamilies>
    <!--<fontFamily name="Lobster Two">-->
    <!--<normal>lobstertwo/LobsterTwo-Regular.otf</normal>-->
    <!--<bold>lobstertwo/LobsterTwo-Bold.otf</bold>-->
    <!--<italic>lobstertwo/LobsterTwo-Italic.otf</italic>-->
    <!--<boldItalic>lobstertwo/LobsterTwo-BoldItalic.otf</boldItalic>-->
    <!--<pdfEncoding>Identity-H</pdfEncoding>-->
    <!--<pdfEmbedded>true</pdfEmbedded>-->
    <!--<!–-->
    <!--<exportFonts>-->
    <!--<export key="net.sf.jasperreports.html">'Lobster Two', 'Times New Roman', Times, serif</export>-->
    <!--</exportFonts>-->
    <!--–>-->
    <!--</fontFamily>-->
    <fontFamily name="华文宋体">
        <normal>stsong/stsong.TTF</normal>
        <bold>stsong/stsong.TTF</bold>
        <italic>stsong/stsong.TTF</italic>
        <boldItalic>stsong/stsong.TTF</boldItalic>
        <pdfEncoding>Identity-H</pdfEncoding>
        <pdfEmbedded>true</pdfEmbedded>
        <exportFonts>
            <export key="net.sf.jasperreports.html">'华文宋体', Arial, Helvetica, sans-serif</export>
            <export key="net.sf.jasperreports.xhtml">'华文宋体', Arial, Helvetica, sans-serif</export>
        </exportFonts>
        <!--
        <locales>
            <locale>en_US</locale>
            <locale>de_DE</locale>
        </locales>
        -->
    </fontFamily>
</fontFamilies>
           
  • 引入字体库stsong.TTF

    链接:https://pan.baidu.com/s/10582hCa-JhOJfKmybTyE0w

    提取码:mlyw

windows可以从C:\Windows\Fonts下寻找想要的字库。

5 数据填充

/**
 * 填充数据构造JasperPrint
 * 			is: 文件输入流
 * 		parameters: 参数
 * 		dataSource: 数据源 
 */
public static JasperPrint fillReport(InputStream inputStream, Map<String, Object> parameters, JRDataSource dataSource) throws JRException {
    return getDefaultInstance().fill(inputStream, parameters, dataSource);
}
           

通过这段代码我们可以看出JasperReport对报表模板中的数据填充有很多种,但最主要的有以下两种:

  • Parameters(参数)填充
  • DataSource(数据源)填充

5.1 参数Map填充数据

Parameter通常是用来在打印的时候从程序里传值到报表里。也就是说parameters通常是起参数传递的作用。他们可以被用在一些特定的场合(比如应用中SQL查询的条件), 如report中任何一个需要从外部传入的变量等(如一个Image对象所包括的char或报表title的字符串)。parameters也需要在创建的时候定义它的数据类型,其数据类型是标准的java的Object。

5.1.1 模板制作

(1) 创建模板, 删除不需要的Band

新建一个jrxml文件,删除不需要的band。如下图所示:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(2) 设置模板的静态信息

如下图所示:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(3) 创建Parameters

首先,在左下角找到Parameters点击右键,选择Create Parameter

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

在右下角的Properties中设置参数信息:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

直接将设置好的参数拖拽到页面上即可,如下图所示:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

模板制作完成后可以点击,预览按钮查看模板样式:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

若是对于样式不满意,还可以去右下角对样式进行设计,修改

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(4) 编译模板生成jasper文件

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(5) 将Jasper文件放到Java工程里

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(6) 编写Java代码

注意:设置参数时,参数的key必须大于模板中parameter参数的name一致。

package com.wsw.controller;

import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;

@RestController
public class JasperController02 {
    /**
     * 基于Parameters以Map的形式填充数据
     * @param response
     * @param request
     * @throws Exception
     */
    @GetMapping("/testJasper2")
    public void createHtml(HttpServletResponse response, HttpServletRequest request)throws Exception{
        //1.引入jasper文件。由JRXML模板编译生成的二进制文件,用于代码填充数据
        Resource resource = new ClassPathResource("templates/testParam.jasper");
        //2.加载jasper文件创建inputStream
        FileInputStream isRef = new FileInputStream(resource.getFile());
        ServletOutputStream sosRef = response.getOutputStream();
        try {
            Map parameters = new HashMap();
            //设置参数 参数的key必须大于模板中parameter参数的name一致
            parameters.put("username", "张三");
            parameters.put("mobile", "14747596654");
            parameters.put("company", "阿里巴巴");
            parameters.put("dept", "开发部");

            JasperPrint jasperPrint = JasperFillManager.fillReport(isRef, parameters,new JREmptyDataSource());
            //3.将JasperPrint已PDF的形式输出
            JasperExportManager.exportReportToPdfStream(jasperPrint,sosRef);
        } finally {
            sosRef.flush();
            sosRef.close();
        }
    }

}
           

(6) 重启项目

(7) 调用接口

填写的参数都被打印出来了,如下图所示:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

5.2 数据源填充数据

5.2.1 JDBC 数据源

5.2.1.1 无参数的JDBC数据源连接

使用JDBC数据源填充数据,使用JasperSoft Studio 先要配置一个数据库连接。

填写数据源的类型,选择“DataBase JDBC Connection”

(1) 新建建一个JDBC Connection的模板,testConn.jrxml

(2) 选择左上角的Repository

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(3) 右键点击Data Adapters 选择Created Data Adapter

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(4) 选择 Database JDBC Connection

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(5) 配置数据库连接的信息

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(6) 添加数据库连接的驱动

点击Driver Classpath

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

点击Add,选择数据库驱动的jar包, 这里提供一个下载jar包的网址:http://central.maven.org/maven2/mysql/mysql-connector-java/ 。我下载的版本是:mysql-connector-java-5.1.9.jar

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

添加完jar包后,点击test按钮,连接成功如下图所示 :

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

最后,点击Finish。创建成功!

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(7) 编辑模板 – 设置Fields

去左下角的OutLine里,在模板上点击右键选择Datatest and Query

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

选择我们刚刚设置好的的数据库:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

选择我们想要显示数据的表,并在右侧编写查询sql

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

点击Read Fields,就会生成相应的字段信息

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

删除多余的字段,只留下需要展示的字段:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

点击OK,查看OutLine里的Fields,里面已经有我们设置好的字段信息了:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(8) 编辑模板 – 设置页面样式

直接将需要使用的字段拖拽到Detail里,这时会出现对应的静态文本框,因为我们是要生成一个列表,需要将这些静态框删除,然后设计表格样式,如下图所示:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

去properties中设置每一行数据的高度,高度与你设置的每一个元素的高度相同:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

保存后,点击preview查看样式:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(8) 编译模板,将生成的Jasper文件拖入项目的resourse目录下

(9) 编写java代码

package com.wsw.controller;

import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;
import java.util.Map;

@RestController
public class JasperController03 {
    /**
     * 基于JDBC数据源的形式填充数据
     * @param response
     * @param request
     * @throws Exception
     */
    @GetMapping("/testJasper3")
    public void createHtml(HttpServletResponse response, HttpServletRequest request)throws Exception{
        //1.引入jasper文件。由JRXML模板编译生成的二进制文件,用于代码填充数据
        Resource resource = new ClassPathResource("templates/testConn01.jasper");
        //2.加载jasper文件创建inputStream
        FileInputStream isRef = new FileInputStream(resource.getFile());
        ServletOutputStream sosRef = response.getOutputStream();
        try {
            Map parameters = new HashMap();

            //获取数据库连接
            Connection conn = getConnection();

            JasperPrint jasperPrint = JasperFillManager.fillReport(isRef, parameters, conn);
            //3.将JasperPrint已PDF的形式输出
            JasperExportManager.exportReportToPdfStream(jasperPrint,sosRef);
        } finally {
            sosRef.flush();
            sosRef.close();
        }
    }

    public Connection getConnection() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/ihrm", "root", "root");
        return connection;
    }

}
           

(9) 调用接口

结果如下图所示:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

5.2.1.2 有参数的JDBC数据源连接

(1) 创建Parameters

回到我们的模板,添加一个Paramerters

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

设置参数信息:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(2) 修改查询语句

回到OutLine,右键单击testConn,选择Datatest and Query

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

修改sql, 这里的参数要使用 $P{参数名} 的形式:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

点击OK后,进入preview页面。填入参数后,点击启动按钮:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

预览一下,OK:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(3) 重新编译一下jrxml文件,将生成的jasper文件放入工程里

(4) 修改Java代码

package com.wsw.controller;

import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;
import java.util.Map;

@RestController
public class JasperController03 {
    /**
     * 基于JDBC数据源的形式填充数据
     * @param response
     * @param request
     * @throws Exception
     */
    @GetMapping("/testJasper3")
    public void createHtml(HttpServletResponse response, HttpServletRequest request)throws Exception{
        //1.引入jasper文件。由JRXML模板编译生成的二进制文件,用于代码填充数据
        Resource resource = new ClassPathResource("templates/testConn.jasper");
        //2.加载jasper文件创建inputStream
        FileInputStream isRef = new FileInputStream(resource.getFile());
        ServletOutputStream sosRef = response.getOutputStream();
        try {
            Map parameters = new HashMap();

            parameters.put("cid", "1");

            //获取数据库连接
            Connection conn = getConnection();

            JasperPrint jasperPrint = JasperFillManager.fillReport(isRef, parameters, conn);
            //3.将JasperPrint已PDF的形式输出
            JasperExportManager.exportReportToPdfStream(jasperPrint,sosRef);
        } finally {
            sosRef.flush();
            sosRef.close();
        }
    }
	/**
	 * 获取数据库连接
	 * @return
	 * @throws Exception
	 */
    public Connection getConnection() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/ihrm", "root", "root");
        return connection;
    }

}
           

(5) 调用接口,如下图所示

注意:我在编写代码时遇到过jasper文件读取不到的问题,解决方法时将Jasper文件改个名字即可,怀疑时缓存问题。

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio
5.2.2 JavaBean 数据源
使用JDBC数据源的形式,将数据库的连接交给了Jasper管理。这种方式可能不够好,这时可以使用JavaBean作为数据源的方式

(1) 新建模板testBean

(2) 手动创建Fields

找到OutLine,右键Fields选择Create Field

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

设置Field的名称,因为是通过反射实现的,所以该名称要与JavaBean中的一致:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(3) 设置模板如下图所示

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(4) preview一下确定样式

由于没有传递数据,故此时都为null。

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(5) 编译模板,将jasper文件放入工程

(6) 编写Java代码

步骤:

  1. 获取到对象的list集合
  2. 通过list结合创建JavaBean的数据源对象

① 创建一个JavaBean

package com.wsw.domain;

public class User {
    private String id;
    private String username;
    private String mobile;
    private String company;
    private String dept;

    public User() {
    }

    public User(String id, String username, String mobile, String company, String dept) {
        this.id = id;
        this.username = username;
        this.mobile = mobile;
        this.company = company;
        this.dept = dept;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getMobile() {
        return mobile;
    }

    public void setMobile(String mobile) {
        this.mobile = mobile;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getDept() {
        return dept;
    }

    public void setDept(String dept) {
        this.dept = dept;
    }
}
           

② 编写接口

package com.wsw.controller;

import com.wsw.domain.User;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class JasperController04 {
    /**
     * 基于JavaBean的形式填充数据
     * @param response
     * @param request
     * @throws Exception
     */
    @GetMapping("/testJasper4")
    public void createHtml(HttpServletResponse response, HttpServletRequest request)throws Exception{
        //1.引入jasper文件。由JRXML模板编译生成的二进制文件,用于代码填充数据
        Resource resource = new ClassPathResource("templates/testBean01.jasper");
        //2.加载jasper文件创建inputStream
        FileInputStream isRef = new FileInputStream(resource.getFile());
        ServletOutputStream sosRef = response.getOutputStream();
        try {
            Map parameters = new HashMap();

            //构造JavaBean的数据源
            //1. 获取到对象的list集合
            List<User> users = getUserList();
            //2. 通过list结合创建JavaBean的数据源对象
            JRBeanCollectionDataSource jrBeanCollectionDataSource = new JRBeanCollectionDataSource(users);

            JasperPrint jasperPrint = JasperFillManager.fillReport(isRef, parameters, jrBeanCollectionDataSource);
            //3.将JasperPrint已PDF的形式输出
            JasperExportManager.exportReportToPdfStream(jasperPrint,sosRef);
        } finally {
            sosRef.flush();
            sosRef.close();
        }
    }

    /**
     * 设置模拟数据
     * @return
     */
    public List<User> getUserList() {
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            User user = new User(i + "", "wsw" + i ,"1470000000" + i, "中国石油" , "开发部");
            userList.add(user);
        }
        return userList;
    }

}
           

注意:这里有一个坑,就是在手动设置Field的时候description字段不要填写描述,否则反射机制会出现问题,可能寻找对应字段时会出现对应字段匹配错误的问题!

(7) 重启项目

(8) 调用接口

结果如下:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio
6 分组报表

6.1 概述

两种情况会使用分组报表:

  • 美观和好看的显示
  • 当数据库分为两层表时,经常需要批量打印子表的数据。打印室,常常需要按照附表的外键或关联值进行自动分组,即每一条父表记录所属的字表打印到一组报表中,每组报表都单独计数及计算页数。

在应用中,可以通过选择需要打印的父表记录,将父表的id传入,有报表进行自动分组。

6.2 分组功能的实现

(1) 新建模板

新建一个testGroup.jrxml模板

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

创建Field

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

设置页面基本样式:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(2) 设置分组

找到 Outline 的模板名称,点击右键选择 Create Group

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

选择分组的依据,这里我选择的时company 公司分组:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

点击next,会出现两个选项,就按照默认就好(这两个选项就是分组的头和尾):

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

点击Finsih,页面变成如下样式:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

由于我们以公司分组,故要将公司的company的Field拖入Group Header中显示,出现下图情况直接点击Finish。

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

成功后如下图所示:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

双击Group Header里的company字段可以修改打印的语句,格式与java代码类似,最后点击Finish:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

最后一步,对模板的样式进行处理:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(3) 点击preview,预览模板

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(4) 编译模板,将生成的jasper文件导入项目中

(5) 编写java代码

package com.wsw.controller;

import com.wsw.domain.User;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class JasperController05 {
    /**
     * 分组报表
     * @param response
     * @param request
     * @throws Exception
     */
    @GetMapping("/testJasper5")
    public void createHtml(HttpServletResponse response, HttpServletRequest request)throws Exception{
        //1.引入jasper文件。由JRXML模板编译生成的二进制文件,用于代码填充数据
        Resource resource = new ClassPathResource("templates/testGroup.jasper");
        //2.加载jasper文件创建inputStream
        FileInputStream isRef = new FileInputStream(resource.getFile());
        ServletOutputStream sosRef = response.getOutputStream();
        try {
            Map parameters = new HashMap();

            //构造JavaBean的数据源
            //1. 获取到对象的list集合
            List<User> users = getUserList();
            //2. 通过list结合创建JavaBean的数据源对象
            JRBeanCollectionDataSource jrBeanCollectionDataSource = new JRBeanCollectionDataSource(users);

            JasperPrint jasperPrint = JasperFillManager.fillReport(isRef, parameters, jrBeanCollectionDataSource);
            //3.将JasperPrint已PDF的形式输出
            JasperExportManager.exportReportToPdfStream(jasperPrint,sosRef);
        } finally {
            sosRef.flush();
            sosRef.close();
        }
    }

    /**
     * 设置模拟数据
     * @return
     */
    public List<User> getUserList() {
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            User user = new User(i + "", "wsw" + i ,"1470000000" + i, "中国石油" , "开发部");
            userList.add(user);
        }
        for (int i = 0; i < 6; i++) {
            User user = new User(i + "", "木头人" + i ,"1590000000" + i, "中国工商银行" , "开发部");
            userList.add(user);
        }
        return userList;
    }

}
           

(6) 调用接口

结果如下:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

6.3 分组统计汇总

(1)创建Variable

找到Outline 选中 Variable 右键,选择Create Variable:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

填写Variable 和参数类型,参数类型选择Integer就行:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

点击Calculation, 选择Count:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

点击Expression右侧, 填写表达式:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

填写完成后点击Finish:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

在Reset type 里选择 Group,根据分组重置Count函数的值:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(2)将Variable拖入Group Footer里

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(3)双击这条Variable, 设置显示信息

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

设置完成后,点击Finish。并修改模板样式。如下图所示:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(3)设置页码

找到Outline里的Page Footer,右键 选择Add Band:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

Band 被加回页面上:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

将 Outline 里 Variables 下的PAGE_NUMBER 直接拖入 Page Footer。这就是当前页码:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(4)Preview 查看样式

(5)重新编译并导入项目

(6)重启项目,调用接口

结果如下:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

7 Chart 图表

统计每个公司的员工数,以饼状图的形式显示

7.1 模板设置

(1) 删除Band 只保留 Title 和 Summary

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(2) 创建Fields

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(3) 创建chart图标

第一步:palette面板找到chart图标, 拖拽到band中

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第二步:选择需要的图表类型,点击next

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第三步:设置图标参数

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第四步:点击Finish

(5) 设置模板页面样式

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(6) 点击饼状图,在右下角设置饼状图属性

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

对标题进行设置:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

(7) 编译模板,导入项目

7.2 代码实现

(1) 编写存放表格数据的实体类

package com.wsw.domain;

public class UserCount {
    private String company;
    private Long count;

    public UserCount(String company, Long count) {
        this.company = company;
        this.count = count;
    }

    public UserCount() {
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public Long getCount() {
        return count;
    }

    public void setCount(Long count) {
        this.count = count;
    }
}
           

(2) 接口代码

package com.wsw.controller;

import com.wsw.domain.User;
import com.wsw.domain.UserCount;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class JasperController06 {
    /**
     * Chart报表
     * @param response
     * @param request
     * @throws Exception
     */
    @GetMapping("/testJasper6")
    public void createHtml(HttpServletResponse response, HttpServletRequest request)throws Exception{
        //1.引入jasper文件。由JRXML模板编译生成的二进制文件,用于代码填充数据
        Resource resource = new ClassPathResource("templates/testChart.jasper");
        //2.加载jasper文件创建inputStream
        FileInputStream isRef = new FileInputStream(resource.getFile());
        ServletOutputStream sosRef = response.getOutputStream();
        try {
            Map parameters = new HashMap();

            //构造JavaBean的数据源
            //1. 获取到对象的list集合
            List<UserCount> users = getUserCountList();
            //2. 通过list结合创建JavaBean的数据源对象
            JRBeanCollectionDataSource jrBeanCollectionDataSource = new JRBeanCollectionDataSource(users);

            JasperPrint jasperPrint = JasperFillManager.fillReport(isRef, parameters, jrBeanCollectionDataSource);
            //3.将JasperPrint已PDF的形式输出
            JasperExportManager.exportReportToPdfStream(jasperPrint,sosRef);
        } finally {
            sosRef.flush();
            sosRef.close();
        }
    }

    /**
     * 设置模拟数据
     * @return
     */
    public List<UserCount> getUserCountList() {
        List<UserCount> userCounts = new ArrayList<>();

        UserCount userCount01 = new UserCount("阿里巴巴", 1000L);
        UserCount userCount02 = new UserCount("百度", 900L);
        UserCount userCount03 = new UserCount("腾讯", 1200L);

        userCounts.add(userCount01);
        userCounts.add(userCount02);
        userCounts.add(userCount03);

        return userCounts;
    }

}
           

7.3 实现结果

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

8 父子报表

8.1 概述

复杂报表或数据内容比较多的时候,可以使用子报表解决。

8.2 制作夫报表

首先制作父报表,就是调用子报表的一个基本报表。主报表的作用有如下两种:

  • 父报表中需要显示数据,使用子报表弥补studio设计的不足
  • 父报表不需要显示任何数据, 只是作为子报表的载体。适用于复杂报表的设计

8.3 制作子报表

第一步:创建父报表parent.jrxml

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第二步:添加子报表

点击组件面板上的"Subreport"按钮,拖动到报表工作区上。

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

这时会出现如下弹框:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

点击 Select a report file,选择WorkSpace这一项:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

点击Browse,选择之前制作的图形报表testChart.jrxml:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

一直点击OK,最后Finish:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第三步:修改testChart,只保留图表部分

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第四步:在父报表中添加一个Parameter,存放子报表图形中所需的数据

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第五步:单击子报表,选择Subreport

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第六步:清空Connection Expression,点击Data Source Expression

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第七步:点击加号

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第八步:点击‘…‘

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第九步:选择JRBeanCollectionDataSource

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第十步:复制下来该方法

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第十一步:填写表达式

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第十二步:在父报表中添加一个参数subPath,用来保存子报表的路径

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第十三步:填写子报表的表达式

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

第十四步:编译父子报表,并导入项目

8.4 编写Java代码

package com.wsw.controller;

import com.wsw.domain.UserCount;
import net.sf.jasperreports.engine.JREmptyDataSource;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class JasperController07 {
    /**
     * 父子报表
     * @param response
     * @param request
     * @throws Exception
     */
    @GetMapping("/testJasper7")
    public void createHtml(HttpServletResponse response, HttpServletRequest request)throws Exception{
        //1.引入jasper文件。由JRXML模板编译生成的二进制文件,用于代码填充数据
        Resource resource = new ClassPathResource("templates/parent.jasper");
        //2.加载jasper文件创建inputStream
        FileInputStream isRef = new FileInputStream(resource.getFile());
        ServletOutputStream sosRef = response.getOutputStream();
        try {
            Map parameters = new HashMap();
            Resource subResource = new ClassPathResource("templates/testChart.jasper");
            //参数 子报表的路径 子报表的数据
            parameters.put("subPath", subResource.getFile().getPath());
            parameters.put("subList", getUserCountList());

            JasperPrint jasperPrint = JasperFillManager.fillReport(isRef, parameters, new JREmptyDataSource());
            //3.将JasperPrint已PDF的形式输出
            JasperExportManager.exportReportToPdfStream(jasperPrint,sosRef);
        } finally {
            sosRef.flush();
            sosRef.close();
        }
    }

    /**
     * 设置模拟数据
     * @return
     */
    public List<UserCount> getUserCountList() {
        List<UserCount> userCounts = new ArrayList<>();

        UserCount userCount01 = new UserCount("阿里巴巴", 1000L);
        UserCount userCount02 = new UserCount("百度", 900L);
        UserCount userCount03 = new UserCount("腾讯", 1200L);

        userCounts.add(userCount01);
        userCounts.add(userCount02);
        userCounts.add(userCount03);

        return userCounts;
    }

}
           

8.5 调用接口

结果如下:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

8.6 样式修改

我们可以明显的看到子报表位置太靠右,原因如下:

父报表

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

子报表

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

两个报表都有很多空格,两个相加图形就很靠右了。解决方法:调整子报表图形的位置

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio

重新编译子报表,导入项目。重启工程,结果如下:

PDF报表打印 -- Jasper Report一. PDF报表打印概述二. JasperReport的开发步骤三. 模板工具Jaspersoft Studio