JasperReport与SpringBoot整合及模板制作
作者:mmseoamin日期:2023-12-13

0. 示例代码

示例代码地址

1. 报表介绍

1.1 为什么要使用报表?

在企业级应用开发中,报表生成、报表打印下载是其重要的一个环节。除了Excel报表之外,PDF报表也有广泛的应用场景,必须用户详细资料,用户简历等

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

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

2. JasperReport

2.1 框架介绍

  • 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就能生成最终用户想要的文档格式。

    2.2 相关文件介绍

    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文件)
      • Exporter:决定要输出的报表为何种格式,报表输出的管理类。

    2.3 开发流程概述

    JasperReport与SpringBoot整合及模板制作,image-20230720173908644,第1张

    2.4 模板工具Jaspersoft Studio

    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.4.1 Jaspersoft Studio CE下载

      JasperReport与SpringBoot整合及模板制作,image-20230720174339640,第2张

      我下载的是js-studiocomm_6.20.5_windows_x86_64.exe

      下载完成后无脑安装就行了

      JasperReport与SpringBoot整合及模板制作,image-20230720174442720,第3张

      2.4.2 面板介绍

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

      JasperReport与SpringBoot整合及模板制作,image-20230720174622966,第4张

      • Report editing area(主编辑区域) 通过拖动,定位,对齐和通过 Designer palette(设计器调色板)对报表元素调整大小

      • Editor Area

        • Design tab: 当你打开一个报告文件,它允许您以图形方式创建报表选中
        • Source tab: 包含用于报表的 JRXML 源代码。
        • Preview tab: 允许在选择数据源和输出格式后,运行报表预览。
        • Repository Explorer view 包含 JasperServer 生成的连接和可用的数据适配器列表

        • Outline view 在大纲视图中显示了一个树的形式的方式报告的完整结构

        • Properties view 控件属性设置

        • Design tab 以图形方式创建报表中的控件

        • Report Editor Area介绍

          JasperReport与SpringBoot整合及模板制作,image-20230721095503208,第5张

          • Title(标题)😗*只在整个报表的第一页的最上端显示。**只在第一页显示,其他页面均不显示
          • Page Header(页头):在整个报表中每一页都会显示。
            • 在第一页中,出现的位置在 Title Band的下面。
            • 在除了第一页的其他页面中Page Header 的内容均在页面的最上端显示。
            • Page Footer(页脚): **在整个报表中每一页都会显示。**显示在页面的最下端。一般用来显示页码。
            • Detail1(详细) : 报表内容,每一页都会显示。
            • Column Header(列头): Detail中打印的是一张表的话,这Column Header就是表中列的列头。
            • Column Footer(列脚) :Detail中打印的是一张表的话,这Column Footer就是表中列的列脚。
            • Summary(统计): 表格的合计段,出现在整个报表的最后一页中,在Detail 1 Band后面。主要是用来做报表的合计显示。

              2.4.3 Paramter,Field和Detail基本组件介绍

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

                JasperReport与SpringBoot整合及模板制作,image-20230724102309270,第6张

              2. 在Java程序中可以通过给对应的Paramter赋值,在打印时就可以输出你想要的结果。代码如下所示

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

                JasperReport与SpringBoot整合及模板制作,image-20230724102449497,第7张

              2. 在Java程序中可以通过集合给集合中的每一条数据的Field字段赋值,在打印时就可以输出你想要的结果。代码如下所示

                //给Field赋值
                List list = 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);
                
              2.4.3.3 Detail
              • Detail是打印Field字段的区域,一个报表可以有多个Detail,在Detail上右键可以通过Add Detail Band来增加新的Detail区
              • Detail会把传递进来的list的数据,循环打印出来,有多条就会打印多行,一页打印不下就会从下一页继续打印
              • 如果通过Detail来打印表格,Detail的高度最好和要打印的Field高度一样,这样每行就不会有缝隙,打印出来和表格一样的效果
              • 如果存在多个detail,他们是交替打印

              JasperReport与SpringBoot整合及模板制作,image-20230724104128439,第8张

              JasperReport与SpringBoot整合及模板制作,image-20230724102714741,第9张

              2.4.4 动态组件常用的属性的用法

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

                JasperReport与SpringBoot整合及模板制作,image-20230724102810556,第10张

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

                • 表达式例子:new Boolean($F{showtitle1}),new Boolean(true)
                • 表达式参考

                  JasperReport与SpringBoot整合及模板制作,image-20230724102904515,第11张

              2.5 springBoot 整合JasperReport基础案例(固定报表)

              2.5.1 引入依赖

              创建一个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
                          
                      
                  
              
              

              2.5.2 模板制作

              1. 创建jasper文件:File -> New -> Jasper Report

                我选择的空白A4

                JasperReport与SpringBoot整合及模板制作,image-20230721100535309,第12张

              2. 制作模版

                JasperReport与SpringBoot整合及模板制作,image-20230721113929017,第13张

              3. 点击Compile Repot生成Jasper文件

                JasperReport与SpringBoot整合及模板制作,image-20230721114010151,第14张

              4. 找到编译后的.jasper文件

                编译完成后在下方控制台会提示文件生成地址

                JasperReport与SpringBoot整合及模板制作,image-20230721114041711,第15张

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

                JasperReport与SpringBoot整合及模板制作,image-20230721102001212,第16张

              2.5.3 创建测试Controller

              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

              JasperReport与SpringBoot整合及模板制作,image-20230721114255923,第17张

              2.5.4 JasperReports 不显示中文问题及解决方案

              2.5.4.1 问题展示
              1. 新增了一个带中文Static Text

                JasperReport与SpringBoot整合及模板制作,image-20230721144550322,第18张

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

                JasperReport与SpringBoot整合及模板制作,image-20230721144641730,第19张

              3. 测试访问http://localhost:8080/jasper/test1

                新增的Text英文展示出来了,但是中文没有展示出来

                JasperReport与SpringBoot整合及模板制作,image-20230721144722061,第20张

              2.5.4.2 问题原因

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

              JasperReport与SpringBoot整合及模板制作,image-20230721163550902,第21张

              2.5.4.3 解决方案(添加中文字体库)
              1. 在JasperReport Studio工具的Window-> Preferences -> font 中add一个微软雅黑的字体

                我下载字体的位置

                JasperReport与SpringBoot整合及模板制作,image-20230721164004818,第22张

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

                JasperReport与SpringBoot整合及模板制作,image-20230721164239002,第23张

              3. 然后我们就可以保存文件重新编译一次然后放入templates目录下改名为demo.jasper

              4. 在Jaspersoft Studio 打包字体文件Font.jar包

                • Jaspersoft Studio中打包Font.jar,步骤如下: Window -> Preferences -> Jaspersoft Studio -> Fonts->Export

                  JasperReport与SpringBoot整合及模板制作,image-20230721164914758,第24张

                • 将导出的font.jar导入项目依赖

                  1. 通过maven引入

                    1. 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
                      
                    2. maven 引入依赖

                              
                                  site.zhourui.report
                                  font
                                  1.0.0
                              
                      
                    3. 也可以推送到maven远程仓库这个看你自己

                  2. 通过Add as Library引入

                    1. 只要保证 fonts.jar 在项目的 classpath 中即可!我放到在resources下面

                      JasperReport与SpringBoot整合及模板制作,image-20230721165519859,第25张

                    2. 然后点击鼠标右键

                      JasperReport与SpringBoot整合及模板制作,image-20230721165541179,第26张

                    3. 选择Classes

                      JasperReport与SpringBoot整合及模板制作,image-20230721165617905,第27张

                    4. 设置名称和适用范围等

                      JasperReport与SpringBoot整合及模板制作,image-20230721165715445,第28张

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

                  JasperReport与SpringBoot整合及模板制作,image-20230721160544999,第29张

              2.5.5 Java-map(parameter)的方式传入参数

              1. 新增两个参数year,name

                JasperReport与SpringBoot整合及模板制作,image-20230724100619878,第30张

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

                JasperReport与SpringBoot整合及模板制作,image-20230724100714747,第31张

              3. 模板

                如果是内容中文记住更换字体

                生成Jasper文件demo3.Jasper放入templates目录下

                JasperReport与SpringBoot整合及模板制作,image-20230724100757667,第32张

              4. 新建测试方法

                之前传的是一个空的HashMap

                现在传入对应的值

                JasperReport与SpringBoot整合及模板制作,image-20230724101027511,第33张

                    /**
                     * 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();
                        }
                    }
                
              5. 访问测试

                测试链接http://localhost:8080/jasper/test3

                JasperReport与SpringBoot整合及模板制作,image-20230724101520967,第34张

              2.5.6 Java-List(Failed)的方式传入参数,并打印多页表单

              1. 制作模板

                4个属性

                如果有中文注意选择字体

                JasperReport与SpringBoot整合及模板制作,image-20230724111911444,第35张

              2. 生成Jasper文件demo3.Jasper放入templates目录下

              3. 新建测试方法

                /**
                     * 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();
                        }
                    }
                
              4. 测试效果 访问http://localhost:8080/jasper/test4

                JasperReport与SpringBoot整合及模板制作,image-20230724111830672,第36张