前后端分离微服务管理系统项目实战SaaS-HRM项目(十)——用户档案PDF报表

十、用户档案PDF报表

1、数据填充

前面介绍了如何使用JasperReport来生成简单的文本报表,正式企业开发中动态数据展示也是报表中最重要的一环,接下来我们共同研究的就是填充动态数据到PDF报表中。

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

通过这段填充数据的源代码得知,JasperReport对报表模板中的数据填充有很多种方式,最典型的有以下两种:

  • Parameters(参数)填充
  • DataSource(数据源)填充
<1>、参数Map填充数据

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

(1)、模板制作

1、创建新模板,删除不需要的Band
在这里插入图片描述
2、创建Parameter
在outline面板中找到Parameters,右键 -> Create Parameter,新建一个Parameter(生成一个Paramerter1)
在这里插入图片描述
右键 Paramete1 -> Show Properties. 设置Name为title、Class为java.lang.String.这里要注意名字要认真取不能重 复,因为传入的参数的key就是这个参数名,以此来进行一一对应
在这里插入图片描述
3、模板参数设置
将设置好的参数直接拖入表格中对应的位置,并设置好大小与对齐方式
在这里插入图片描述

(2)、PDF输出
@RestController
public class JasperController02 {

    /**
     * 基于parameters以map形式填充数据
     */
    @GetMapping("/testJasper2")
    public void createPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {
        //1.引入jasper文件
        Resource resource = new ClassPathResource("templates/testParam.jasper");
        FileInputStream fis = new FileInputStream(resource.getFile());

        //2.创建JasperPrint,向jasper文件中填充数据
        ServletOutputStream os = response.getOutputStream();
        try {

            Map parameters = new ArrayMap<>();
            //设置参数,参数的key = 模板中使用的parameters参数的name
            parameters.put("username", "zpw");
            parameters.put("mobile", "5211314");
            parameters.put("company", "alibaba");
            parameters.put("dept", "jiagoushi");

            JasperPrint print = JasperFillManager.fillReport(fis, parameters,new JREmptyDataSource());
            //3.将JasperPrint以PDF的形式输出
            JasperExportManager.exportReportToPdfStream(print,os);

        } catch (JRException e) {
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }
}
<2>、数据源填充数据
(1)、JDBC数据源
1、配置数据库连接

使用JDBC数据源填充数据:使用Jaspersoft Studio 先要配置一个数据库连接
填写数据源的类型,选择“Database JDBC Connection”
在这里插入图片描述
配置数据库信息
在这里插入图片描述
这一步,需要: (1)给创建的这个数据连接起个名字; (2)根据数据库选择驱动类型; Jaspersoft Studio 已经内置了很多常用数据库的驱动,使用的时候直接选就可以了。当然,如果这还满足不了你的话,你还可以添加你指定的JDBC驱动jar包。

2、模板制作

1、制作空白模板
2、将数据库用户字段配置到模板中
为了方便的进行模板制作,可以将需要数据库表中的字段添加到Studio中。在outline中右键模板,选择dataset and query
在这里插入图片描述
用户可以在 SQL 查询语句输入窗口中,输入需要查询数据的查询语句,点击右上角的“Read Fields”按钮,界面下 方的字段列表中,就会显示此查询语句中所涵盖的所有字段的列表。在后面的报表设计中,我们就可以直接使用这 些字段了。
在这里插入图片描述
在“Fields”列表中,只保留报表中使用的字段,其他用不到的字段最好用“Delete”删掉,防止由于数据表变化,导致 报表模板中的字段设置与数据表对应不上,导致报表报错。输入完毕后,点击“OK”按钮,系统即会把查询语句保存 在报表模板中。
在这里插入图片描述
3、填充Filed
将id, mobile,username等拖入到 Detail Band中设计模板如下:
在这里插入图片描述

3、PDF输出
@RestController
public class JasperController03 {

    /**
     * 基于JDBC数据源形式填充数据
     */
    @GetMapping("/testJasper3")
    public void createPdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //1.引入jasper文件
        Resource resource = new ClassPathResource("templates/testConn.jasper");
        FileInputStream fis = new FileInputStream(resource.getFile());

        //2.创建JasperPrint,向jasper文件中填充数据
        ServletOutputStream os = response.getOutputStream();
        try {
            Map parameters = new ArrayMap<>();
            //查询企业id为1的所有用户
            parameters.put("cid", "1");
            //获取数据库连接
            Connection connection = getConnection();
            JasperPrint print = JasperFillManager.fillReport(fis,  parameters, connection);
            //3.将JasperPrint以PDF的形式输出
            JasperExportManager.exportReportToPdfStream(print,os);

        } catch (JRException e) {
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }

    public Connection getConnection() throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/ihrm", "root", "12345678");
        return connection;
    }
}
(2)、JavaBean数据源
1、创建Filed

1、创建Filed
在这里插入图片描述
2、构造模板
在这里插入图片描述

2、PDF输出

1、编写实体类

package cn.itcast.domain;

public class User {

    private String id;
    private String username;
    private String company;
    private String dept;
    private String mobile;

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

    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 getCompany() {
        return company;
    }

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

    public String getDept() {
        return dept;
    }

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

    public String getMobile() {
        return mobile;
    }

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

2、使用javaBean数据源

package cn.itcast.controller;

import cn.itcast.domain.User;
import net.sf.jasperreports.engine.JRException;
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.olap4j.impl.ArrayMap;
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.List;
import java.util.Map;

@RestController
public class JasperController04 {

    /**
     * 基于javaBean数据源形式填充数据
     */
    @GetMapping("/testJasper4")
    public void createPdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //1.引入jasper文件
        Resource resource = new ClassPathResource("templates/testBean.jasper");
        FileInputStream fis = new FileInputStream(resource.getFile());

        //2.创建JasperPrint,向jasper文件中填充数据
        ServletOutputStream os = response.getOutputStream();
        try {
            Map parameters = new ArrayMap<>();
            List<User> userList = getUserList();
            JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(userList);
            JasperPrint print = JasperFillManager.fillReport(fis,  parameters, dataSource);
            //3.将JasperPrint以PDF的形式输出
            JasperExportManager.exportReportToPdfStream(print,os);

        } catch (JRException e) {
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }

    public List<User> getUserList(){
        List<User> list = new ArrayList<>();
        for (int i = 1; i <= 10; i ++){
            User user = new User(i + "", "用户名" + i, "Alibaba", "架构师", "1234567800" + i);
            list.add(user);
        }
        return list;
    }
}

2、分组报表

<1>、概述

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

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

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

<2>、设置分组属性

1、新建模板

2、新进报表群组
选中报表名称点击右键,选择菜单中的“Create Group”。
在这里插入图片描述
需要设置分组的名称、分组字段。也可以设置按照指定的函数、方法处理后进行分组
在这里插入图片描述
按照字段“companyName”进行分组。设置完毕,点击“Next”。系统显示细节设置界面。此处可以设置是否加 入“group header”和“group footer”区。建议保持默认选中,加入这两个区域,这样可以控制在每组报表的结尾, 打印相应的信息,例如统计信息等。
在这里插入图片描述

3、放置报表数据
将companyName拖入 Group Header中 ,会跳出 TextField Wizard框,选中 NoCalculation Function
在这里插入图片描述
双击 $F{deptId} 会弹出Expression editor框
在这里插入图片描述

<3>、添加分组Band

将需要作为表头打印的内容拖入 CompanyGroup Header1 栏,将字段拖入 detail 栏,将每个分组结尾需要打印 的内容放入 Companygroup footer 栏,将页脚需要打印的内容放入 Page Footer栏,如下图。
在这里插入图片描述

<4>、PDF输出
@RestController
public class JasperController05 {

    /**
     * 分组报表
     */
    @GetMapping("/testJasper5")
    public void createPdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //1.引入jasper文件
        Resource resource = new ClassPathResource("templates/testGroup.jasper");
        FileInputStream fis = new FileInputStream(resource.getFile());

        //2.创建JasperPrint,向jasper文件中填充数据
        ServletOutputStream os = response.getOutputStream();
        try {
            Map parameters = new ArrayMap<>();
            List<User> userList = getUserList();
            JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(userList);
            JasperPrint print = JasperFillManager.fillReport(fis,  parameters, dataSource);
            //3.将JasperPrint以PDF的形式输出
            JasperExportManager.exportReportToPdfStream(print,os);

        } catch (JRException e) {
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }

    public List<User> getUserList(){
        List<User> list = new ArrayList<>();
        for (int i = 1; i <= 5; i ++){
            User user = new User(i + "", "Alibaba" + i, "Alibaba", "架构师", "1234567800" + i);
            list.add(user);
        }
        for (int i = 1; i <= 5; i ++){
            User user = new User(i + "", "Tencent" + i, "Tencent", "产品经理", "1234567800" + i);
            list.add(user);
        }
        return list;
    }
}

3、Chart图表

<1>、创建模板

1、创建模板、删除不需要的band、保留title和summary。
2、创建fileds
3、创建chart图标
第一步:palette面板找到chart图表,拖拽到band中
第二步:选择需要的图表类型
第三步:设置图表参数
在这里插入图片描述

  • Key: 圆饼图的内容是什么,也就是下面的 First,Second…的内容
  • Value:这个圆饼图的比例依据,根据 Value 属性来显示每个 Key 占的比例
  • Label:显示标签
<2>、PDF输出
(1)、实体类
package cn.itcast.domain;


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

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

    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)、PDF输出
@RestController
public class JasperController06 {

    /**
     * 分组报表
     */
    @GetMapping("/testJasper6")
    public void createPdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //1.引入jasper文件
        Resource resource = new ClassPathResource("templates/testCharts.jasper");
        FileInputStream fis = new FileInputStream(resource.getFile());

        //2.创建JasperPrint,向jasper文件中填充数据
        ServletOutputStream os = response.getOutputStream();
        try {
            Map parameters = new ArrayMap<>();
            List<UserCount> userList = getUserCount();
            JRBeanCollectionDataSource dataSource = new JRBeanCollectionDataSource(userList);
            JasperPrint print = JasperFillManager.fillReport(fis,  parameters, dataSource);
            //3.将JasperPrint以PDF的形式输出
            JasperExportManager.exportReportToPdfStream(print,os);

        } catch (JRException e) {
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }

    public List<UserCount> getUserCount(){
        List<UserCount> list = new ArrayList<>();
        UserCount user1 = new UserCount("Alibaba", 2000L);
        UserCount user2 = new UserCount("Tencent", 2000L);
        UserCount user3 = new UserCount("Baidu", 2000L);
        list.add(user1);
        list.add(user2);
        list.add(user3);
        return list;
    }
}

4、父子报表

<1>、概述

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

<2>、制作父报表

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

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

点击组件面板上的“Subreport”按钮,拖动到报表工作区上。
在这里插入图片描述
系统会自动弹出子报表选择窗口。可以选择创建一个新报表,还是使用一个已有的报表作为子报表。
在这里插入图片描述
选择“Create a new report”,可以立即制作新的子报表;如果选择“Select an existing report”,则可以调用已经有 的报表作为子报表;如果选择“Just create the subreport element”,系统会生成一个子报表区,可以在之后挂接需要的子报表。

<4>、参数传递

在这里插入图片描述

<5>、PDF输出
@RestController
public class JasperController07 {

    /**
     * 父子报表
     */
    @GetMapping("/testJasper7")
    public void createPdf(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //1.引入jasper文件
        Resource resource = new ClassPathResource("templates/main01.jasper");
        FileInputStream fis = new FileInputStream(resource.getFile());

        //2.创建JasperPrint,向jasper文件中填充数据
        ServletOutputStream os = response.getOutputStream();
        try {
            Map parameters = new ArrayMap<>();
            Resource subResout = new ClassPathResource("templates/testCharts.jasper");
            parameters.put("subpath",subResout.getFile().getPath());    //子报表路径
            parameters.put("sublist", getUserCount());                  //子报表需要的数据
            JasperPrint print = JasperFillManager.fillReport(fis,  parameters, new JREmptyDataSource());
            //3.将JasperPrint以PDF的形式输出
            JasperExportManager.exportReportToPdfStream(print,os);
        } catch (JRException e) {
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }

    public List<UserCount> getUserCount(){
        List<UserCount> list = new ArrayList<>();
        UserCount user1 = new UserCount("Alibaba", 2000L);
        UserCount user2 = new UserCount("Tencent", 2000L);
        UserCount user3 = new UserCount("Baidu", 2000L);
        list.add(user1);
        list.add(user2);
        list.add(user3);
        return list;
    }
}

5、用户档案下载

<1>、搭建环境

引入相关依赖

		<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>

解决乱码的问题和前面使用的方法一样。

<2>、用户档案下载实现

在员工微服务中的EmployeeController中添加方法

	/**
     * 打印员工报表
     */
    @RequestMapping(value = "/{id}/pdf", method = RequestMethod.GET)
    public void pdf(@PathVariable String id) throws IOException {
        //1、引入jasper文件
        Resource resource = new ClassPathResource("templates/profile.jasper");
        FileInputStream fis = new FileInputStream(resource.getFile());
        //2、构造数据
        //a、用户详情数据
        UserCompanyPersonal personal = userCompanyPersonalService.findById(id);
        //b、用户岗位信息数据
        UserCompanyJobs jobs = userCompanyJobsService.findById(id);
        //c、用户头像
        String staffPhoto = "http://pkbivgfrm.bkt.clouddn.com/" + id;
        //3、填充PDF模板数据,并输出PDF
        Map params = new HashMap();
        params.put("staffPhoto", staffPhoto);
        Map<String, Object> map = BeanMapUtils.beanToMap(personal);
        Map<String, Object> map1 = BeanMapUtils.beanToMap(jobs);
        params.putAll(map);
        params.putAll(map1);
        ServletOutputStream os = response.getOutputStream();
        try {
            JasperPrint print = JasperFillManager.fillReport(fis, params, new JREmptyDataSource());
            JasperExportManager.exportReportToPdfStream(print, os);
        }catch (JRException e){
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值