使用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>com.itextpdf</groupId>
-		<artifactId>itextpdf</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("下載個人檔案異常");
        }

好了今天的代碼就到這裏了,如有不明白之處歡迎留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章