JasperReport填充数据的方式

前言:

上一篇介绍了JasperReport是什么,以及使用创建模板,下面来说一下JasperReport的数据填充;

我们可以通过以下源码看到,JasperReport对报表模板中的数据填充有很多中方式,最典型的有以下两种

  • Parameters (参数)填充
  • DataSource (数据源) 填充
1
2
3
4
5
6
7
8
 /**
* 填充数据构造JasperPrint
* is: 文件输入流
* parameters:参数
* dataSource:数据源
*/
public static JasperPrint fillReport(InputStream is, Map<String, Object> parameters,
JRDataSource dataSource) throws JRException {

1.使用Parameters(也就是参数为Map) 的方式填充数据

1,创建一个新的Jasper Report模板,删除掉不需要的Band,只留下Title,和Detail 1

我们需要四个参数username,moblie,company,dept,在Outline面板下面找到Parameters选项,右键创建一个username

Parameters代表的就是java代码传递过来的参数,参数可以自己创建

2,在Properties面板下修改名字,类型选择String类型,其他参数也是同样方法创建

3,然后把创建好的这四个Properties托入到Detail1 Bean中,前面是静态的文字说明。

$P代表的是:要用到Properties里面的数据了,括号里面就是参数的名称

创建完成后最好是把字体的样式设置为华文宋体,以免的麻烦

也可以点击Perview进行一个预览:

会要求你输入四个参数模拟数据,根据名称输入就好了,然后点击Reset即可看到效果

4,找到compile Report编译成为.jasper文件,复制到resources–>templates文件夹下

5,编写一个测试的Controller,这里application.yml文件配置和启动类可以参考上一篇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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 JasperController2 {

//基于 paramters 以Map的形式填充数据
@GetMapping("/testJasper2")
public void createPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {
//1.引入jasper文件
Resource resource = new ClassPathResource("templates/testParameters.jasper");
FileInputStream fis = new FileInputStream(resource.getFile());
//2.创建JasperPrint,向jasper文件中填充数据

ServletOutputStream os = response.getOutputStream();
try {
Map parameters = new HashMap();
//注意 设置的参数的key必须使用parameters中的参数名称是一样的
parameters.put("username","张三");
parameters.put("mobile","110");
parameters.put("company","云哈");
parameters.put("dept","开发部");
JasperPrint print = JasperFillManager.fillReport(fis,parameters,new JREmptyDataSource());
//3.将JasperPrint已PDF的形式输出
JasperExportManager.exportReportToPdfStream(print,os);

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

}

浏览器访问:http://localhost:8082/testJasper2,如果报错提示:找不到文件路劲的话请重启`IDE`即可

1.2 数据源填充数据

1,创建一个模板然后只留下Title以及Detail1

2,我们可以在Jaspersoft Studio先配置一个数据库连接,选择Repository Explorer

右键创建一个数据库连接,选择JDBC Connection

然后点击Next,这里配置基本的信息

最后点击Driver Classpath配置Mysql的驱动包,然后点击Test连接测试,如果弹出Successful就说明连接成功了

3,查询数据库,帮我们自动生成Fields

Fields 就是数据库中的一个字段,也就是每一个对象的属性

在Outline面板里面右键模板的名称点击Dataset and Query Dialog点击打开,记得点击Read Fields执行查询

点击OK之后在Outline面板找到Fields下拉就可以看到刚查询出来的字段

然后把这些属性全部托入模板中:托入模板中之后会有两个框框,我们留下带$符号的,把前面的Static Text删除掉即可

然后字体样式选择华文宋体避免中文出现不了问题

然后点击Preview预览效果就可以看到你数据库中的数据了,如果数据之间显示相隔的太多,我们可以修改Detail1的高度改成矮一点的

A,同样的找到源文件,然后找到compile Report编译成为.jasper文件,复制到resources–>templates文件夹下

B,编写一个测试的Controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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.DriverAction;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

@RestController
public class JasperController3 {

//基于 JDBC数据源的形式填充数据
@GetMapping("/testJasper3")
public void createPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {
//1.引入jasper文件
Resource resource = new ClassPathResource("templates/testComm.jasper");
FileInputStream fis = new FileInputStream(resource.getFile());
//2.创建JasperPrint,向jasper文件中填充数据

ServletOutputStream os = response.getOutputStream();
try {
Map parameters = new HashMap();
//parameters.put("cid","1");

Connection conn = getConnection();
// JasperController3 controller3 = new JasperController3();
// Connection conn = controller3.getConnection();
JasperPrint print = JasperFillManager.fillReport(fis,parameters,conn);
//3.将JasperPrint已PDF的形式输出
JasperExportManager.exportReportToPdfStream(print,os);

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

//编写一个连接jdbc方法
public Connection getConnection(){
Connection conn = null;
try {
//获取驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接url
conn = DriverManager.getConnection("jdbc:mysql://localhost/ihrm","root","root");
}catch (SQLException e){
e.printStackTrace();
}catch (ClassNotFoundException e){
e.printStackTrace();
}
return conn;
}

}

C,浏览器访问:http://localhost:8082/testJasper2 ,如果报错文件找不到可以重启IDE

上面是查询全部的信息,如果想要查询某一个企业或者某一个部门,我们可以传递一个参数。

首先我们在JasperSoft Studio里面创建一个Parameters,取名可以叫做Cid的参数,或者其他。

然后找到之间编写的sql查询语句去构造查询条件,在Outline面板里面右键模板的名称点击Dataset and Query

点击OK之后再去预览就会要你输入一个Cid,输入即可看到效果,最上方运行方式一定要选择在你的数据库中运行,不然没有效果

A,编写一个测试Controller,也就是在Map中传递一个参数,去查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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.DriverAction;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

@RestController
public class JasperController3 {

//基于 JDBC数据源的形式填充数据
@GetMapping("/testJasper3")
public void createPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {
//1.引入jasper文件
Resource resource = new ClassPathResource("templates/testComm.jasper");
FileInputStream fis = new FileInputStream(resource.getFile());
//2.创建JasperPrint,向jasper文件中填充数据

ServletOutputStream os = response.getOutputStream();
try {
Map parameters = new HashMap();
parameters.put("cid","1");

Connection conn = getConnection();
// JasperController3 controller3 = new JasperController3();
// Connection conn = controller3.getConnection();
JasperPrint print = JasperFillManager.fillReport(fis,parameters,conn);
//3.将JasperPrint已PDF的形式输出
JasperExportManager.exportReportToPdfStream(print,os);

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

//编写一个连接jdbc方法
public Connection getConnection(){
Connection conn = null;
try {
//获取驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接url
conn = DriverManager.getConnection("jdbc:mysql://localhost/ihrm","root","root");
}catch (SQLException e){
e.printStackTrace();
}catch (ClassNotFoundException e){
e.printStackTrace();
}
return conn;
}

}

B,浏览器访问:http://localhost:8082/testJasper3 ,如果报错文件找不到可以重启IDE

1.2.2 JAVABean数据源

如果在连接的时候担心内存泄漏的问题,我们可以使用JavaBean的方式,来填充数据。

1,同样也是创建一个新的Jasper Report模板,删除不需要的模板,留下Title以及Detail1

2,我们需要创建几个参数Fields,注意Fieldsname和你的实体类名称是一样的,然后托入Detail 1,字体样式选择华文宋体

3,然后编译compile Report,复制.jasper文件到resources–>templates文件夹下

4,编写一个测试Controller:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
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.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class JasperController4 {

//基于 javaBean数据源的形式填充数据
@GetMapping("/testJasper4")
public void createPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {
//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<>();
//1.从对象中获取list集合
List<User> userList = getUserList();
//2.通过list集合创建javaBean的数据源对象
JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(userList);

//构造javaBean数据源
JasperPrint print = JasperFillManager.fillReport(fis,parameters,ds);
//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 =0;i<10;i++){
User user = new User(i+"", "用户"+i, "允浩科技","讲师", "1380000000"+i);
list.add(user);
}
return list;
}

}

5,java实体类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package cn.itcast.domain;

public class User {

private String id;
private String username;
private String mobile;
private String company;
private String 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;
}

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


}

浏览器访问:http://localhost:8082/testJasper4,如果报错提示:找不到文件路劲的话请重启`IDE`即可

2,分组报表

1,同样也是创建一个新的Jasper Report模板,删除不需要的模板,留下Title以及Detail1

2,再创建几个Fields,也可以从之前的模板中复制过来也可以,接着托入Deatail 1中

3,创建分组,在Outline面板中找到右键模板名称选择:Create Group,根据企业进行分组

然后点击Next

勾选上 Add the Group HeaderAdd the Group Footer

点击完成你会看到模板中多了两个Bead,可以在Header里面添加展示分组的名称,比如我以企业名称为分组,把companye托入到Header中,双击打开

然后选中选择字体样式为华文宋体,如果你要想统计多少条数目或者需要一个页码,在Outline面板中找到Variables下拉你会看到很多的内置方法,比如当前页码和总页数。

我们可以创建自己的参数:右键创建一个 Create Variables

右键创建一个 Create Variables然后这个totalNum拖入到Group Footer 1当中,如果想要当前的页码 找到PAGE_NUMBER拖入到Page Footer

3,编写一个测试Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
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.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
public class JasperController5 {

//分组报表
@GetMapping("/testJasper5")
public void createPdf(HttpServletRequest request, HttpServletResponse response) throws IOException {
//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<>();
//1.从对象中获取list集合
List<User> userList = getUserList();
//2.通过list集合创建javaBean的数据源对象
JRBeanCollectionDataSource ds = new JRBeanCollectionDataSource(userList);

//构造javaBean数据源
JasperPrint print = JasperFillManager.fillReport(fis,parameters,ds);
//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 =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;
}

}

浏览器访问:http://localhost:8082/testJasper5,如果报错提示:找不到文件路劲的话请重启`IDE`即可

3,父子报表

1,同样也是创建一个新的Jasper Report模板,删除不需要的模板,留下Title以及Detail1

2,找到Sbreport托入Detail 1

3,选择本地模板,点击Browse查找

4,接下来选择你的模板:

然后点击ok

5,我们再创建两个个Parameters取名为subpath,sublist,点击模板中的Sbreport

编写子报表需要的数据:

1
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{sublist})

6,然后编译你的父报表和你的子报表,把.jasper文件复制到resources–>templates文件夹下

7,编写一个测试Controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package cn.itcast.controller;

import cn.itcast.domain.UserCount;
import net.sf.jasperreports.engine.*;
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 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 HashMap<>();

//参数:子报表的路径
Resource subResout = new ClassPathResource("templates/testCharts.jasper");
parameters.put("sublist",getUserCountList());//子报表需要的数据
parameters.put("subpath",subResout.getFile().getPath()); //子报表的路径
JasperPrint print = JasperFillManager.fillReport(fis,parameters,new JREmptyDataSource());
JasperExportManager.exportReportToPdfStream(print,os);
} catch (JRException e) {
e.printStackTrace();
}finally {
os.flush();
}
}

public List<UserCount> getUserCountList() {
List<UserCount> list = new ArrayList<>();

UserCount uc1 = new UserCount("doge",1000l);
UserCount uc2 = new UserCount("google",1000l);
UserCount uc3 = new UserCount("baidu",1000l);
list.add(uc1);
list.add(uc2);
list.add(uc3);
return list;
}


}

浏览器访问:http://localhost:8082/testJasper7,如果报错提示:找不到文件路劲的话请重启`IDE`即可

end