使用Freemarker输出word文档到浏览器与本地

本期我们介绍如何使用Freemarker导出word文档?

项目需求如下:
前些时间开发人力资源项目,项目在正式上线之后,客户录入的大良人员基础信息,包括人员基础信息,教育经历,工作经历,培训经历与家庭情况,这些数据都是使用独立的表来存储的,后来客户反馈,说查看个人信息不方便,在人员调动时候还需要打印个人简历给领导看,特别提出导出个人简历功能
最后输出效果如下:
在这里插入图片描述

经过考虑: 有两种备选方案,第一种是使用itextPDF输出PDF文档,第二种是使用Freemarker导出word,但是在实际开发中发现,使用itextPDF在填充工作经历等信息时候需要用到循环,而itextPDF对循环支持的不是很友好,于是果断时候了Freemarker

使用模板引擎至少需要四步走:

1.定义模板引擎
2.创建数据模型
3.填充数据到模板中
4.输出文档

1.首先定义模板

1.1 创建word文档,定义个人简历模板,效果如下:

在这里插入图片描述

1.2另存为XML文件

在这里插入图片描述使用文本编辑器打开

1.3定义插值

我们使用文本编辑器打开之后会有一些乱,可以使用代码在线格式化工具格式化一下,地址https://tool.oschina.net/codeformat/xml

我们根据word模板搜索姓名,找到‘5’,并替换为插值表达式

在这里插入图片描述
个人基础信息全部使用以上方式替换

工作经历教育经历等需要使用循环:
搜索工作经历:找到<w:tr>标签,除标题之外只保留一个,每一个<w:tr>代表为一行数据
在这里插入图片描述
注意

<#list workList as work>

</#list>

workList 是数据源,as 表示循环 work 代表每次循环的对象
在这里插入图片描述
教育经历,家庭信息同理
处理完成后,修改后缀名为.ftl,放到项目templates目录下
在这里插入图片描述

2.代码开始

2.1、引入依赖

	<!--PDF常用工具类 -->
	<dependency>
	    <groupId>org.freemarker</groupId>
	    <artifactId>freemarker</artifactId>
	    <version>2.3.28</version>
	</dependency>
/**
     * 下载个人简历word文档
     * @param response
     * @param userId
     * @throws IOException
     * @throws TemplateException
     */
    @GetMapping("/parint1/{userId}")
    @ResponseBody
    public void print(HttpServletResponse response,@PathVariable("userId") String userId) throws IOException, Exception {
        Long userId1 = Long.valueOf(userId);
        HrStaffInfo staffInfo = hrStaffInfoService.selectHrStaffInfoById(userId1);

        String content = exportFile(staffInfo);

        InputStream inputStream = IOUtils.toInputStream(content);
        ServletOutputStream out = null;
        try {
            
            //输出文件
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream;charset=UTF-8");
            //response.setHeader("Content-Disposition", "attachment;filename=" + "aaa企业在编在职人员情况登记表bb"+".doc");
            response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(staffInfo.getUserName()+"-顺德区区属国有企业在编在职人员情况登记表", "UTF-8")+ ".doc")));

            out = response.getOutputStream();
            byte[] buffer = new byte[1024]; // 缓冲区
            int bytesToRead = -1;
            // 通过循环将读入的Word文件的内容输出到浏览器中
            while((bytesToRead = inputStream.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        }catch (Exception e){
            log.error("导出Excel异常{}", e.getMessage());
            throw new BusinessException("导出word失败,请联系网站管理员!");
        }finally {
            out.flush();
            out.close();
            inputStream.close();
        }
    }


public String exportFile(HrStaffInfo staffInfo ) throws Exception{
        HrStaffEducation education1 = new HrStaffEducation();
        HrStaffWork hrStaffWork = new HrStaffWork();
        HrStaffTrain hrStaffTrain = new HrStaffTrain();
        HrStaffFamily hrStaffFamily = new HrStaffFamily();
        education1.setStaffInfoId(staffInfo.getUserId());
        hrStaffWork.setStaffInfoId(staffInfo.getUserId());
        hrStaffTrain.setStaffInfoId(staffInfo.getUserId());
        hrStaffFamily.setStaffInfoId(staffInfo.getUserId());
        List<HrStaffEducation> educationList = educationService.selectHrStaffEducationList(education1);
        SysDictData dictData2 = new SysDictData();
        dictData2.setDictType("hr_staff_degree");

        List<SysDictData> eduList = dictDataService.selectDictDataList(dictData2);
        for (HrStaffEducation hrStaffEducation : educationList) {
            String degree = hrStaffEducation.getDegree();
            if(degree == null){
                continue;
            }
            for (SysDictData dictData : eduList) {
                if(degree.equals(dictData.getDictValue())){
                    hrStaffEducation.setDegree(dictData.getDictLabel());
                    continue;
                }
            }
            continue;
        }
		//查询工作经历
        List<HrStaffWork> workList = workService.selectHrStaffWorkList(hrStaffWork);
        //查询培训经历
        List<HrStaffTrain> trainList = trainService.selectHrStaffTrainList(hrStaffTrain);
        //查询家庭情况
        List<HrStaffFamily> familyList = familyService.selectHrStaffFamilyList(hrStaffFamily);

        //创建配置类
        Configuration configuration = new Configuration(Configuration.getVersion());
        String classPath = this.getClass().getResource("/").getPath();
        configuration.setDirectoryForTemplateLoading(new File(classPath+"templates/"));
        //获取模板文件
        Template template = configuration.getTemplate("curriculum_vitae.ftl");
        Map<String, Object> data = new HashMap<String, Object>();
        Long companyId = staffInfo.getCompanyId();
        String companyName = hrOrgCompanyService.selectHrOrgCompanyById(companyId).getDeptName();
        data.put("companyName", companyName);
        Calendar cal = Calendar.getInstance();
        String model="yyyy-MM-dd";  //指定格式化的模板
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(model);
        String date = simpleDateFormat.format(new Date());
        String[] split = date.split("-");
        data.put("year", split[0]);
        data.put("month", split[1]);
        data.put("day", split[2]);
        //-------------------------------------------------------------
        SysDictData dictData = new SysDictData();
        List<SysDictData> sexList = dictDataService.selectDictDataList(dictData);

        String sex = "";
        String national = "";
        String highestDegree = "";
        String partHighestDegree = "";
//        String national = "";
//        String national = "";
        for (SysDictData sysDictData : sexList) {

            if (staffInfo.getSex()!= null && staffInfo.getSex().equals(sysDictData.getDictValue())&&"sys_user_sex".equals(sysDictData.getDictType())){
                sex = sysDictData.getDictLabel();
            }

            if ( staffInfo.getNational()!= null && staffInfo.getNational().equals(sysDictData.getDictValue())&&"hr_staff_national".equals(sysDictData.getDictType())){
                national = sysDictData.getDictLabel();
            }

            if (staffInfo.getHighestDegree()!= null && staffInfo.getHighestDegree().equals(sysDictData.getDictValue())&&"hr_staff_qualification".equals(sysDictData.getDictType())){
                highestDegree = sysDictData.getDictLabel();
            }

            if (staffInfo.getPartHighestDegree() != null && staffInfo.getPartHighestDegree().equals(sysDictData.getDictValue())&&"hr_staff_qualification".equals(sysDictData.getDictType())){
                partHighestDegree = sysDictData.getDictLabel();
            }

        }
        //-------------------------------------------------------------
        String deptName = hrOrgCompanyService.selectHrOrgCompanyById(staffInfo.getDeptId()).getDeptName();


        //-------------------------------------------------------------
        data.put("userName", staffInfo.getUserName());      //5
        data.put("sex",  sex);       //7
        data.put("bornYear", staffInfo.getBornYear());      //8
        data.put("bornMonth", staffInfo.getBornMonth());    //8
        data.put("nativePlace",  staffInfo.getNativePlace());   //9
        data.put("national",  national);     //10
        data.put("idNumber",  staffInfo.getIdNumber());     //11
        data.put("partyTime",  staffInfo.getPartyTime());    //12
        data.put("workTime",  staffInfo.getWorkTime());  //13
        data.put("birthPlace",  staffInfo.getBirthPlace()); //14
        data.put("registeredPlace",  staffInfo.getRegisteredPlace());   //15
        data.put("highestDegree",  highestDegree);   //16
        data.put("highestProfessional",  staffInfo.getHighestProfessional());   //17
        data.put("graduateSchool",  staffInfo.getGraduateSchool()); //18
        data.put("partHighestDegree",  partHighestDegree);   //19
        data.put("partHighestProfessional",  staffInfo.getPartHighestProfessional());   //20
        data.put("partGraduateSchool", staffInfo.getPartGraduateSchool());     //21
        data.put("professionalQualifications",  staffInfo.getProfessionalQualifications()); //22
        data.put("maritalStatus",  staffInfo.getMaritalStatus()); //22
        data.put("unitTime",  staffInfo.getUnitTime());  //25
        data.put("positionName",  staffInfo.getPositionName()); //26
        data.put("dept",  deptName);    //27
        data.put("currentAddress",  staffInfo.getCurrentAddress()); //28
        data.put("phoneNumber",  staffInfo.getPhonenumber());   //29
        //-------------------------------------------------------------

//        data.put("staffInfo",staffInfo);
		//要和模板中定义的变量名保持一致
        data.put("educationList",educationList);
        data.put("workList",workList);
        data.put("trainList",trainList);
        data.put("familyList",familyList);

        String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, data);

        return content;
    }

定义前端接收请求:

/**
         * 下载word文档
         */
        function print1() {
            window.location.href = ctx + "hr/hrStaffInfo/parint1/" + userId;
        }

在这里插入图片描述

如果你想输出到本地
定义输出路径即可,其他代码与输出到浏览器保持一致

	@GetMapping("/export/{userId}")
    @ResponseBody
    public TableDataInfo list(@PathVariable("userId") Long userId, HttpServletResponse response) throws Exception {

        HrStaffInfo staffInfo = hrStaffInfoService.selectHrStaffInfoById(userId);
        String content = exportFile(staffInfo);
        try {
            InputStream inputStream1 = IOUtils.toInputStream(content);
            //定义输出路径即可,其他代码与输出到浏览器保持一致
            FileOutputStream fileOutputStream = new FileOutputStream(new File("d:/test1.doc"));
            int copy = IOUtils.copy(inputStream1, fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
            inputStream1.close();
        } catch (Exception e) {
            logger.error("下载个人档案异常", e);
            throw new BaseException("下载个人档案异常");
        }

好了今天的代码就到这里了,如有不明白之处欢迎留言。

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值