用户档案PDF报表1

简介: 用户档案PDF报表

用户档案PDF报表

理解数据填充的两种方式熟练构造分组报表

熟练构造Chart图形报表实现个人档案的PDF输出


数据填充

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


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

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

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


参数Map填充数据

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


模板制作

创建新模板,删除不需要的Band


创建Parameter

在outline面板中找到Parameters,右键 -> Create Parameter,新建一个Parameter(生成一个Paramerter1)

选中新建的参数Paramete1,可以看到右侧的Properties栏,这里可以设置参数的信息,设置Name为title、Class为java.lang.String.这里要注意名字要认真取,不能重复,因为传入的参数的key就是这个参数名,以此来进行一一对应

模板参数设置


将设置好的参数直接拖入表格中对应的位置,并设置好大小与对齐方式。

PDF输出

package cn.itcast.controller;
import net.sf.jasperreports.engine.*;
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.io.IOException;
import java.util.HashMap;
import java.util.Map;
@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 HashMap<>();
            //设置参数 参数的key = 模板中使用的parameters参数的name
            parameters.put("username","张三");
            parameters.put("phone","120");
            parameters.put("department","讲师");
            parameters.put("company","字节跳动");
            JasperPrint print = JasperFillManager.fillReport(fis,parameters,new JREmptyDataSource());
            JasperExportManager.exportReportToPdfStream(print,os);
        } catch (JRException e) {
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }
}

骚戴理解:这个是通过hashMap来填充参数的,这里写的都是静态的数据,唯一要注意的就是这个hashMap里的key要和Parameters里面的属性名保持一致!使用HashMap填充适用于一对一的数据,就是标题下面只有一行数据的情况,如果是想一对多,也就是数据列表的形式,跟数据库表格数据一样的话就要用JDBC或者JavaBean的填充方式!


数据源填充数据

JDBC数据源

配置数据连接

选择Data Adapters右键选择Create Data Adapter

使用JDBC数据源填充数据:使用Jaspersoft Studio 先要配置一个数据库连接填写数据源的类型,选择“Database JDBC Connection”

配置数据库信息

这一步,需要:


(1)给创建的这个数据连接起个名字;


(2)根据数据库选择驱动类型; Jaspersoft Studio 已经内置了很多常用数据库的驱动,使用的时候直接选就可以了。当然,如果这还满足不了你的话,你还可以添加你指定的 JDBC 驱动 jar 包。


骚戴理解:这个Mysql驱动其实就是jdbc的驱动包,如下所示!

模板制作

制作空白模板

创建空白模板,并将不需要的Band删除

将数据库用户字段配置到模块中

为了方便的进行模板制作,可以将需要数据库表中的字段添加到Studio中。在outline中右键模板,选择dataset and query


用户可以在 SQL 查询语句输入窗口中,输入需要查询数据的查询语句,点击右上角的“Read Fields”按钮,界面下方的字段列表中,就会显示此查询语句中所涵盖的所有字段的列表。在后面的报表设计中,我们就可以直接使用这些字段了。

在“Fields”列表中,只保留报表中使用的字段,其他用不到的字段最好用“Delete”删掉,防止由于数据表变化,导致报表模板中的字段设置与数据表对应不上,导致报表报错。输入完毕后,点击“OK”按钮,系统即会把查询语句保存在报表模板中。

填充Filed

将id,mobile,username等拖入到 Detail Band中设计模板如下:

骚戴理解:在把Fields里面列名拽到控制台可能会出现下面这样的情况

可以看到多了一些东西,也就是我红色画出的部分,这些其实就是描述,可以不用,所以删掉即可

在预览的时候出现这样的情况,这是样式问题,选中Detail1可以看到它的高度是286px

在选中列框可以看到高度是30px

只需要把detail1的高度改成列框的高度即可

其实也可以直接拖拽detail1的框和列框的高度保持一致即可

调整后

动态传入参数来筛选数据

创建动态参数cid

这里修改sql语句加一个查询条件,使用Jasper的语法$P{}传参数

然后报错测试即可!

PDF输出

package cn.itcast.controller;
import net.sf.jasperreports.engine.*;
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.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.HashMap;
import java.util.Map;
@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 HashMap<>();
            //查询企业id为1的所有用户
            parameters.put("cid","1");
            //获取数据库连接
            Connection conn= getConnection();
            JasperPrint print = JasperFillManager.fillReport(fis,parameters,conn);
            JasperExportManager.exportReportToPdfStream(print,os);
        } catch (JRException e) {
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }
    public Connection getConnection() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/ihrm","root","111111");
        return conn;
    }
}

骚戴理解:这里只需要修改JasperPrint print = JasperFillManager.fillReport(fis,parameters,conn);即可,传入一个Connection对象替换原来的new JREmptyDataSource()


JavaBean数据源

创建Filed

创建Filed


骚戴理解:JavaBean的方式就只能手动一个个的去创建Fields,然后拖拽到控制台进行设计,不像JDBC一样可以自己生成!

构造模板

PDF输出

配置实体类

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

使用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.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.ArrayList;
import java.util.HashMap;
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 HashMap<>();
            //构建javaBean的数据源
            //1.获取到对象的list集合
            List<User> userList = getUserList();
            //2.通过list集合创建javaBean的数据源对象
            JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(userList);
            JasperPrint print = JasperFillManager.fillReport(fis,parameters,ds);
            JasperExportManager.exportReportToPdfStream(print,os);
        } catch (JRException e) {
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }
    public List<User> getUserList() {
        List<User> list = new ArrayList<>();
        for(int i=0;i<10;i++) {
            User user = new User(i+"", "用户"+i, "字节跳动","讲师", "1380000000"+i);
            list.add(user);
        }
        return list;
    }
}

骚戴理解:JavaBean实现的核心代码如下所示


JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(userList);

通过传入集合来构造一个JRBeanCollectionDataSource对象,这是JavaBean的数据源


分组报表

概述

有两种情况会使用分组报表: 美观和好看的显示。


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


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


设置分组属性

新建模板

使用用户列表模板完成分组案例

新建报表群组

选中报表名称点击右键,选择菜单中的“Create Group”。


需要设置分组的名称、分组字段。也可以设置按照指定的函数、方法处理后进行分组


按照字段“companyName”进行分组。设置完毕,点击“Next”。系统显示细节设置界面。此处可以设置是否加入“group header”和“group footer”区。建议保持默认选中,加入这两个区域,这样可以控制在每组报表的结尾, 打印相应的信息,例如统计信息等。

放置报表数据

将Fields里的companyName拖入 Group Header中 ,会跳出 TextField Wizard框,选中

No Calculation Function

双击 $F{companyName} 会弹出Expression editor框

骚戴理解:这里注意写法和Java的写法差不多,有点类似字符串拼接

"以企业进行分组:企业名称" + $F{companyName)

添加分组Band

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


统计每组记录数

首先创建fx的Variables变量

设置这个Variables变量的属性,只需要设置下面右边画出来的属性即可

其中Expression表示分组依据,这里是一个表达式$F{companyName},表示分组是按照companyName企业名称进行分组的!Calculation表示计算方式,这里用的是Count,因为是需要统计每个组的记录数,就是有多少条数据,Calculation还有其他的选项,这里列出来便于了解!


最后的Reset type其实是设置根据什么情况下来重置统计数,这里选择是按分组进行统计重置,也就是统计完一个组后就会把重置count=0,然后统计下一个分组,这些设计好后ctrl+s保存即可拖拽这个变量到控制台进行设计,这是自定义变量,Jaspersoft Studio自带一些Variables是可以直接用的,例如这里就用到了PAGE_NUMBER


Jaspersoft Studio自带的Variables都是什么意思?


REPORT_COUNT:当前报表中已经处理的记录数。

PAGE_NUMBER:当前页的页码。

COLUMN_NUMBER:在详细段中,指明正在处理的列的编号。在组报表中,它是当前分组的列数。

PAGE_COUNT:报表的总页数。

COLUMN_COUNT:在详细段中,它指出正在处理的列的总数。在组报表中,它是总列数。

REPORT_MAX_COUNT:报表中待处理的最大记录数。如果未指定,则无穷大。


PDF输出

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.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 {
    /**
     *  分组报表
     */
    @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 HashMap<>();
            //构建javaBean的数据源
            //1.获取到对象的list集合
            List<User> userList = getUserList();
            //2.通过list集合创建javaBean的数据源对象
            JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(userList);
            JasperPrint print = JasperFillManager.fillReport(fis,parameters,ds);
            JasperExportManager.exportReportToPdfStream(print,os);
        } catch (JRException e) {
            e.printStackTrace();
        }finally {
            os.flush();
        }
    }
    public List<User> getUserList() {
        List<User> list = new ArrayList<>();
        for(int i=0;i<10;i++) {
            User user = new User(i+"", "itcast"+i, "传智播客","讲师", "1380000000"+i);
            list.add(user);
        }
        for(int i=0;i<5;i++) {
            User user = new User(i+"", "itheima"+i, "黑马程序员","讲师", "1380000000"+i);
            list.add(user);
        }
        return list;
    }
}

效果如下:

目录
相关文章
|
3月前
|
BI API
Form 中调用并发请求生成报表并输出PDF的方法
【9月更文挑战第11天】该文档介绍了在表单中通过并发请求生成报表并将其输出为PDF的方法,包括设置并发请求、配置输出选项、触发请求及处理结果。具体步骤涉及创建请求、配置参数、设置输出类型为PDF、添加触发按钮、调用请求API、等待请求完成、获取并显示PDF文件。需根据所用系统和技术调整实现细节。
|
4月前
|
XML Java BI
怎么通过itextpdf架包实现报表导出为pdf文件?
Java通过itextpdf架包实现报表导出为pdf文件
|
7月前
|
JSON 前端开发 BI
使用 Pandas, Jinja 和 WeasyPrint,轻松创建一个 PDF 报表
使用 Pandas, Jinja 和 WeasyPrint,轻松创建一个 PDF 报表
使用 Pandas, Jinja 和 WeasyPrint,轻松创建一个 PDF 报表
|
XML Java BI
医疗管理系统-PDF报表生成
医疗管理系统-PDF报表生成
102 0
|
存储 XML 前端开发
文件上传与PDF报表入门1
文件上传与PDF报表入门
810 0
文件上传与PDF报表入门1
|
前端开发 关系型数据库 MySQL
用户档案PDF报表2
用户档案PDF报表
90 0
|
XML SQL 数据可视化
文件上传与PDF报表入门2
文件上传与PDF报表入门
170 0
做报表pdf导出功能实现
做报表pdf导出功能实现
|
JSON 前端开发 BI
使用 Pandas, Jinja 和 WeasyPrint,轻松创建一个 PDF 报表
使用 Pandas, Jinja 和 WeasyPrint,轻松创建一个 PDF 报表
使用 Pandas, Jinja 和 WeasyPrint,轻松创建一个 PDF 报表
|
2天前
|
人工智能 文字识别 数据挖掘
MarkItDown:微软开源的多格式转Markdown工具,支持将PDF、Word、图像和音频等文件转换为Markdown格式
MarkItDown 是微软开源的多功能文档转换工具,支持将 PDF、PPT、Word、Excel、图像、音频等多种格式的文件转换为 Markdown 格式,具备 OCR 文字识别、语音转文字和元数据提取等功能。
43 8
MarkItDown:微软开源的多格式转Markdown工具,支持将PDF、Word、图像和音频等文件转换为Markdown格式