示例代码地址
在企业级应用开发中,报表生成、报表打印下载是其重要的一个环节。除了Excel报表之外,PDF报表也有广泛的应用场景,必须用户详细资料,用户简历等
目前世面上比较流行的制作PDF报表的工具如下:
| 名称 | 介绍 |
|---|---|
| Jasper Report | 是一个强大、灵活的报表生成工具,能够展示丰富的页面内容,并将之转换成PDF |
| Openoffice | openoffice是开源软件且能在windows和linux平台下运行,可以灵活的将word或者Excel转化为PDF文档。 |
| iText PDF | iText是著名的开放项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。 |

Jaspersoft Studio是JasperReports库和JasperReports服务器的基于Eclipse的报告设计器; 它可以作为Eclipse插件或作为独立的应用程序使用。

我下载的是js-studiocomm_6.20.5_windows_x86_64.exe
下载完成后无脑安装就行了

左侧切换outline视图,调整视图的位置

Report editing area(主编辑区域) 通过拖动,定位,对齐和通过 Designer palette(设计器调色板)对报表元素调整大小
Editor Area
Repository Explorer view 包含 JasperServer 生成的连接和可用的数据适配器列表
Outline view 在大纲视图中显示了一个树的形式的方式报告的完整结构
Properties view 控件属性设置
Design tab 以图形方式创建报表中的控件
Report Editor Area介绍

- Paramters是一张报表中全局的属性,初始自带了一些属性,也可以自定义属性。大家可以理解为存放一个报表的表头数据
- Paramter的属性可以是任何类型,String,Long,Double,List等等
- Paramter可以用在报表的任何区域,一般用在报表的Title,Page Header,Page Footer区域
Paramters的创建:在左侧的Outline框,在Paramters上右键 Create Paramter 就可以创建一个新的Paramter,在右侧可以设置名称和类型。使用时直接拖拽到相应的区域即可。如下图所示

在Java程序中可以通过给对应的Paramter赋值,在打印时就可以输出你想要的结果。代码如下所示
//给Paramter赋值 HashMapparameters = new HashMap (); parameters.put("name", "小明");//这里的key要和报表中的Paramter的name对应 parameters.put("age", "18"); //中间代码省略 //核心代码,把Paramters传入JasperReport提供的方法,并返回JasperPrint 对象 JasperPrint jasperPrint = JasperFillManager.fillReport(jasperStream, parameters, dataSource);
- Fields是报表中数据集合中的字段属性,只能自定义Field字段。大家可以理解为一个报表的明细列表数据
- Field的属性可以是任何类型,String,Long,Double,List等等
- Field只能用在报表的Detail区域
Fields的创建:在左侧的Outline框,在Fields上右键 Create Field 就可以创建一个新的Field,在右侧可以设置名称和类型。使用时直接拖拽到相应的区域即可。如下图所示

在Java程序中可以通过集合给集合中的每一条数据的Field字段赋值,在打印时就可以输出你想要的结果。代码如下所示
//给Field赋值 Listlist = new ArrayList<>(); for (int i = 0; i < 100; i++) { HashMap item = new HashMap (); item.put("Field1", "Field1-" + i); item.put("Field2", "Field2-" + i); item.put("Field3", "Field3-" + i); item.put("Field4", "Field4-" + i); item.put("Field5", "Field5-" + i); list.add(item); } //中间代码省略 //核心代码,用包含Field字段的集合创建一个JRDataSource,传入JasperReport提供的方法,并返回JasperPrint 对象 JRDataSource dataSource = new JRBeanCollectionDataSource(list); JasperPrint jasperPrint = JasperFillManager.fillReport(jasperStream, parameters, dataSource);
- Detail是打印Field字段的区域,一个报表可以有多个Detail,在Detail上右键可以通过Add Detail Band来增加新的Detail区
- Detail会把传递进来的list的数据,循环打印出来,有多条就会打印多行,一页打印不下就会从下一页继续打印
- 如果通过Detail来打印表格,Detail的高度最好和要打印的Field高度一样,这样每行就不会有缝隙,打印出来和表格一样的效果
- 如果存在多个detail,他们是交替打印


所有动态的组件都是通过Expression表达式来绑定要打印的数据,比如Paramter,Field,Image,Table组件等等。

所有组件都有一块Print When属性,**其中有一个Print When Expression表达式,可以在返回true的情况下打印,在false的情况下不打印。**这个表达式可以依赖其他Paramter,Field,可以通过它实现一些特殊的打印需求

创建一个springBoot项目
4.0.0 org.springframework.boot spring-boot-starter-parent 2.3.12.RELEASE site.zhourui jasper-report-demo 0.0.1-SNAPSHOT jasper-report-demo Demo project for Spring Boot 8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test net.sf.jasperreports jasperreports 6.5.0 org.olap4j olap4j 1.2.0 com.lowagie itext 2.1.7 org.springframework.boot spring-boot-maven-plugin 2.4.1
创建jasper文件:File -> New -> Jasper Report
我选择的空白A4

制作模版

点击Compile Repot生成Jasper文件

找到编译后的.jasper文件
编译完成后在下方控制台会提示文件生成地址

找到文件将文件复制到springboot的templates目录下改名为demo.jasper

package site.zhourui.jasperreportdemo.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.RequestMapping;
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;
/**
* @author zr
* @date 2023/7/20 14:52
*/
@RestController
@RequestMapping("/jasper")
public class demoController {
/**
* JasperReport的简单使用
*/
@GetMapping("/test1")
public void createHtml(HttpServletResponse response, HttpServletRequest request) throws Exception {
Resource resource = new ClassPathResource("templates/demo.jasper");
FileInputStream is = new FileInputStream(resource.getFile());
ServletOutputStream os = response.getOutputStream();
try {
/**
* 创建JasperPrint对象
* 数据填充
* is:inputstream params:参数填充 DataSource:数据源填充
*/
JasperPrint jasperPrint = JasperFillManager.fillReport(is, new HashMap<>(), new JREmptyDataSource());
// 写入pdf数据
JasperExportManager.exportReportToPdfStream(jasperPrint, os);
} finally {
os.flush();
os.close();
}
}
}
访问http://localhost:8080/jasper/test1

新增了一个带中文Static Text

再次生成Jasper文件demo2.Jasper放入templates目录下

测试访问http://localhost:8080/jasper/test1
新增的Text英文展示出来了,但是中文没有展示出来

jasperreports的jar包源码中不包含中文字体库。

在JasperReport Studio工具的Window-> Preferences -> font 中add一个微软雅黑的字体
我下载字体的位置

此时就可以选择我们添加的字体了(注意这里有两个微软雅黑要选我们自定义的那个)

然后我们就可以保存文件重新编译一次然后放入templates目录下改名为demo.jasper
在Jaspersoft Studio 打包字体文件Font.jar包
Jaspersoft Studio中打包Font.jar,步骤如下: Window -> Preferences -> Jaspersoft Studio -> Fonts->Export

将导出的font.jar导入项目依赖
通过maven引入
maven打包
注意:你的文件路径可能和我的不一样
mvn install:install-file -Dfile=C:\Users\Administrator\JaspersoftWorkspace\MyReports\font\font.jar -DgroupId=site.zhourui.report -DartifactId=font -Dversion=1.0.0 -Dpackaging=jar
maven 引入依赖
site.zhourui.report font 1.0.0
也可以推送到maven远程仓库这个看你自己
通过Add as Library引入
只要保证 fonts.jar 在项目的 classpath 中即可!我放到在resources下面

然后点击鼠标右键

选择Classes

设置名称和适用范围等

访问测试http://localhost:8080/jasper/test2

新增两个参数year,name

创建模板使用我们创建的参数

模板
如果是内容中文记住更换字体
生成Jasper文件demo3.Jasper放入templates目录下

新建测试方法
之前传的是一个空的HashMap
现在传入对应的值

/**
* JasperReport携带参数
* @param response
* @throws Exception
*/
@RequestMapping("/test3")
public void test3(HttpServletResponse response) throws Exception{
Resource resource = new ClassPathResource("templates/demo3.jasper");
FileInputStream is = new FileInputStream(resource.getFile());
ServletOutputStream os = response.getOutputStream();
Map parameters = new HashMap();
parameters.put("year", "2023");
parameters.put("name", "测试");
try {
/**
* 创建JasperPrint对象
* 数据填充
* is:inputstream params:参数填充 DataSource:数据源填充
*/
JasperPrint jasperPrint = JasperFillManager.fillReport(is, parameters, new JREmptyDataSource());
// 写入pdf数据
JasperExportManager.exportReportToPdfStream(jasperPrint, os);
} finally {
os.flush();
os.close();
}
}
访问测试
测试链接http://localhost:8080/jasper/test3

制作模板
4个属性
如果有中文注意选择字体

生成Jasper文件demo3.Jasper放入templates目录下
新建测试方法
/**
* JasperReport携带参数 ,打印多页表单
* @param response
* @throws Exception
*/
@RequestMapping("/test4")
public void test4(HttpServletResponse response) throws Exception{
Resource resource = new ClassPathResource("templates/demo4.jasper");
FileInputStream is = new FileInputStream(resource.getFile());
ServletOutputStream os = response.getOutputStream();
Random random = new Random();
List list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
HashMap item = new HashMap();
item.put("Field_1", "员工-" + i);
item.put("Field_2", "部门-" + i);
item.put("Field_3", i%2==0?"男":"女");
item.put("Field_4", String.valueOf(random.nextInt(10000 - 8000) + 8000 + 1));//8000-10000
list.add(item);
}
JRDataSource dataSource = new JRBeanCollectionDataSource(list);
try {
/**
* 创建JasperPrint对象
* 数据填充
* is:inputstream params:参数填充 DataSource:数据源填充
*/
JasperPrint jasperPrint = JasperFillManager.fillReport(is, new HashMap<>(), dataSource);
// 写入pdf数据
JasperExportManager.exportReportToPdfStream(jasperPrint, os);
} finally {
os.flush();
os.close();
}
}
测试效果 访问http://localhost:8080/jasper/test4
