记一次jasper的PDF模板父子报表实现功能


前言

近期项目中的心需求是要通过教师提交的听课记录进行PDF打印预览功能,为了实现这个功能我采用jasper的PDF模板+java进行实现
主要工具:idea+studio


需求格式:
其中课堂图片与课堂点评可以多条存在,鉴于这种需求采用jasper的父子报表进行实现.

在这里插入图片描述

开始打算使用一个模板进行功能实现,后来发现图片与评论只能取一条,这才意识到图片与评论的话是一个list集合,要进行遍历,所以采用父子报表进行功能实现.下面介绍一下我的实现方法.

一、具体步骤

1.解决模板问题

使用studio进行模板制作
在自己的百度网盘中放了一个版本比较旧的studio,如果有需要的话可以进行下载

https://pan.baidu.com/s/1t9x6KqTxOVcPW2TqkJejQw
提取码: sohy

模板软件的结构如图:
在这里插入图片描述
创建新的project,取名为parentPdf,然后创建所需要的Paremeters,如图:
在这里插入图片描述
将各个参数拖拽至detail板块中并进行排版:如图
在这里插入图片描述
下面的文件为子报表,子报表就是sonPdf那个文件,如图:
在这里插入图片描述
注意一点:子报表中的属性不是partemeters,而是field属性.

难点

报表的难点在于父子报表传参问题:
主要解决步骤:
在这里插入图片描述
拖拽一个subreport组件进入父报表,然后对改组件进行设置,主要设置两个参数:
1:数据源
2:子报表路径

子报表路径表达式:$P{listPath}
子报表数据源构造:new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{commentList})

模板最终步骤

将parentPdf.jrxml文件与sonPdf.jrxml文件进行编译得到两个jasper文件.

2.服务端代码

这里主要是为父子报表进行数据构造与传参.
话不多说,直接上代码


    @GetMapping("/downloadMyReport/{id}/myReport.pdf")
    @IgnoreAuthenticated
    public void myReport(HttpServletRequest request, HttpServletResponse response, @PathVariable("id") Integer id) throws Exception {

        // 1.引入jasper文件
        File file = ResourceUtils.getFile(path + "/parentPdf.jasper");
        logger.info(file.getPath()+"====================================>>>>");
        FileInputStream fis = new FileInputStream(file);

        //2.创建JasperPrint,向jasper文件中填充数据
        ServletOutputStream os = response.getOutputStream();
        try {
            /**
             * fis: jasper 文件输入流
             * new HashMap :向模板中输入的参数
             * JasperDataSource:数据源(和数据库数据源不同)
             *              填充模板的数据来源(connection,javaBean,Map)
             *               填充空数据来源:JREmptyDataSource
             */
            File listFile = ResourceUtils.getFile(path + "/sonPdf.jasper");
            logger.info(listFile.getPath()+"====================================>>>>");

            /*
             * 构建父报表数据
             */
            Map<String, Object> map = new HashMap<>();
            map.put("listPath", listFile.getPath());//子报表1路径
            CampusAttendanceNote campusAttendanceNote = campusAttendanceNoteService.getAttendanceNoteById(id);
            map.put("teacherName", campusAttendanceNote.getTeacherName() == null ? "未填写" : campusAttendanceNote.getTeacherName());
            map.put("submitDate", campusAttendanceNote.getCreateTime() == null ? "未填写" : campusAttendanceNote.getCreateTime());
            map.put("schoolName", campusAttendanceNote.getSpeakSchool() == null ? "未填写" : campusAttendanceNote.getSpeakSchool());
            map.put("courseName", campusAttendanceNote.getCourseName() == null ? "未填写" : campusAttendanceNote.getCourseName());
            map.put("courseTeacher", campusAttendanceNote.getSpeakTeacherName() == null ? "未填写" : campusAttendanceNote.getSpeakTeacherName());
            map.put("topic", campusAttendanceNote.getTopic() == null ? "未填写" : campusAttendanceNote.getTopic());
            String listenDate = campusAttendanceNote.getListenDate();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
            SimpleDateFormat sdfToDate = new SimpleDateFormat("yyyy-MM-dd");
            Date _listenDate = sdfToDate.parse(listenDate);
            String format = sdf.format(_listenDate);

            System.err.println(format);
            String dateStr = DateUtils.getDateStr(_listenDate);
            String resultCourseDate = format + " 第" + campusAttendanceNote.getWeekCount() + "周 " + dateStr + campusAttendanceNote.getPeriod() + " 第" + campusAttendanceNote.getCourseCount() + "节";
            map.put("courseDate", resultCourseDate);

            map.put("advice", campusAttendanceNote.getAdvice() == null ? "未填写" : campusAttendanceNote.getAdvice());
            List<CampusAttendanceCourseComment> list = campusAttendanceNoteService.getCourseNoteByAttendanceId(campusAttendanceNote.getId());
            map.put("commentList", list);//填充子报表数据
            JasperPrint print = JasperFillManager.fillReport(fis, map, new JREmptyDataSource());
            //3.将JasperPrint已PDF的形式输出
            JasperExportManager.exportReportToPdfStream(print, os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            os.flush();
        }
    }

需要在代码中构造出map,父子报表传参主要通过map中的子报表jasper路径,与子报表的list数据进行传参.

3.接口访问效果

在这里插入图片描述

二、总结

这次的技术记录也仅限于自身学习总结,需求来的比较急,以至于代码还有模板都比较粗糙,这次的分享也比较粗糙,还请见谅,至于PDF模板的开发肯定还有各式各样的,如果有其他的技术,还请大家多多的交流一下,文章对大家有所帮助的话,那也是荣幸之至.
还请大家批评指导.

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值