一、前端

前端使用layui框架,主要通过点击导出按钮,然后ajax请求后端接口,后端返回流,ajax接收到流后,new Blob对象,通过a标签方式下载,具体代码如下:

let result;
  $.ajax({
      type: "POST",
      url: "url请求后端路径",
      data: { 参数 },
      xhrFields:{
          responseType: 'blob'
      },//重点,必须要有这个xhrFields,否则导出不成功
      // responseType: 'blob', //不能用这个,导出不成功
      complete:function (xhr){
           //获取Response Headers 中的 Content-Disposition
          let contentDisposition = xhr.getResponseHeader('Content-Disposition')
          let contentType = xhr.getResponseHeader('Content-type')
          if(contentDisposition && contentType){
                //获取fileName,先将"全局替换为空,再从=开始截取字符串
              let fileName =  contentDisposition.replace(/"/g,"").split('=')[1];
              let decodeStr = decodeURI(fileName)
              const blob = new Blob([result], { type: contentType })
              const url = window.URL.createObjectURL(blob)
              let link = document.createElement('a')
              link.style.display = 'none'
              link.href = url
              link.setAttribute('download', decodeStr)
              document.body.appendChild(link)
              link.click()
           }
       },
       success: function (res) {
           if(!res || res.size===0){
                top.layer.msg('查询数据为空,不能导出', {icon:2})
           }
           result = res
        },
        error: function (data) {
           top.layer.msg('查询数据为空,不能导出', {icon:2})
        }
   });

二、后端

后端使用springboot框架,使用poi-tl模板技术导出word,引入依赖:

我此处是引入的1.5.1版本,最新版本都是1.12.1了,新版本更好用,
但是我项目中引入新版本会不兼容,故使用低版本来实现word导出   
<dependency>
   <groupId>com.deepoove</groupId>
   <artifactId>poi-tl</artifactId>
   <version>1.5.1</version>
</dependency>

代码如下

//controller层代码
/**
 * 导出
 * 1、如果是一条数据,则导出一个word
 * 2、如果是多条数据,则导出一个压缩包,里面是各个word
 *
 * @param response
*/
@RequestMapping("/exportWord")
public void exportWord(String isAll, String villageName, String inspectObject, String inspectUser, String inspectType,
                           String inspectState, String year, String inspectTime, HttpServletResponse response) {
        try {
            CdInspectDetail cdInspectDetail = new CdInspectDetail();
            cdInspectDetail.setVillager(villageName);
            cdInspectDetail.setInspectObject(inspectObject);
            cdInspectDetail.setInspectUser(inspectUser);
            cdInspectDetail.setInspectType(inspectType);
            cdInspectDetail.setInspectState(inspectState);
            String startTime = "";
            String endTime = "";
            if (StringUtils.isNotEmpty(inspectTime) && inspectTime.length() == 23) {
                startTime = inspectTime.substring(0, 10);
                endTime = inspectTime.substring(13, 23);
            }
            cdInspectDetailService.exportWord(isAll, cdInspectDetail, year, startTime, endTime, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
//service层代码
 /**
  * @param isAll           isAll=0导出全部,isAll=1按条件导出
  * @param inspectDetail
  * @param year
  * @param response
  * @throws Exception
  */
 @Override
public void exportWord(String isAll, CdInspectDetail inspectDetail, String year, String startTime, String endTime, HttpServletResponse response) throws Exception {
   List<CdInspectDetail> cdInspectDetailList = new ArrayList<>();
   QueryWrapper<CdInspectDetail> queryWrapper = new QueryWrapper<>();
   if ("0".equals(isAll)) {
        queryWrapper.eq("is_del", 0);
        cdInspectDetailList = cdInspectDetailMapper.selectList(queryWrapper);
   } else if ("1".equals(isAll)) {
        if (StringUtils.isNotEmpty(inspectDetail.getVillager())) {
                queryWrapper.like("villager", inspectDetail.getVillager());
        }
        if (StringUtils.isNotEmpty(inspectDetail.getInspectObject())) {
                queryWrapper.like("inspect_object", inspectDetail.getInspectObject());
        }

        if (StringUtils.isNotEmpty(inspectDetail.getInspectType())) {
                queryWrapper.eq("inspect_type", inspectDetail.getInspectType());
        }
        if (StringUtils.isNotEmpty(inspectDetail.getInspectState())) {
                queryWrapper.eq("inspect_state", inspectDetail.getInspectState());
        }
        queryWrapper.eq("is_del", 0);
        cdInspectDetailList = cdInspectDetailMapper.selectList(queryWrapper);
   }
        if (cdInspectDetailList.size() == 0) {
            throw new RuntimeException("导出数据为空");
        }
        if (cdInspectDetailList.size() == 1) {
            //一条数据导出word
            CdInspectDetail cdInspectDetail = cdInspectDetailList.get(0);
            //使用 po-tl 技术导出word模板
            Map<String, Object> dataMap = new HashMap<>();
           
            String villager = cdInspectDetail.getVillager();
            dataMap.put("villager", villager);
            
            Date inspectTimeDate = cdInspectDetail.getInspectTime();
            String inspectTime = DateUtil.format(inspectTimeDate, "yyyyMMdd");
            dataMap.put("inspectTime", inspectTime);
           
            String inspectObject = cdInspectDetail.getInspectObject();
            dataMap.put("inspectObject", inspectObject);
           
            String inspectUser = cdInspectDetail.getInspectUser();
            dataMap.put("inspectUser", inspectUser);
            
            String problem = cdInspectDetail.getProblem();
            dataMap.put("problem", problem);
           
            String solve = cdInspectDetail.getSolve();
            dataMap.put("solve", solve);
            
            String unitConfirmation = cdInspectDetail.getUnitConfirmation();
            dataMap.put("unitConfirmation", unitConfirmation);
            //查询附件
            List<FileInfo> fileInfoList = fileService.getListFileCode(cdInspectDetail.getId());
            List<PictureRenderData> imgList = new ArrayList<>();
            if (fileInfoList != null && fileInfoList.size() > 0) {
                for (FileInfo fileInfo : fileInfoList) {
                    //后缀
                    String extname = fileInfo.getExtname();
                    //路径
                    String fullPath = fileInfo.getFullPath();
                    File imgFile = new File(fullPath);
                    if (imgFile.exists()) {
                        byte[] bytes = BytePictureUtils.getLocalByteArray(imgFile);
                        PictureRenderData pictureRenderData = new PictureRenderData(500, 800, extname, bytes);
                        pictureRenderData.setAltMeta("无");
                        imgList.add(pictureRenderData);
                    }
                }
                if (imgList.size() > 0) {
                    dataMap.put("imgs", new NumbericRenderData(NumbericRenderData.FMT_DECIMAL, imgList));
                }
            }
            //word模板路径
            String wordTemplatePath = "/templates/doc/securityRecord.docx";
            ClassPathResource templateFile = new ClassPathResource(wordTemplatePath);
            try {
                String filePath = templateFile.getFile().getPath();
                File file = new File(filePath);
                if (file.exists()) {
                    XWPFTemplate template = XWPFTemplate.compile(filePath).render(dataMap);
                    // 设置文件名
                    String tableName = inspectTime + "_" + villager + "_排查";
                    String fileName = URLEncoder.encode(tableName, "UTF-8");
                    response.addHeader("Content-Disposition", "attachment;fileName=" + fileName + ".docx");
                    response.setCharacterEncoding("UTF-8");
                    response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
                    OutputStream out = response.getOutputStream();
                    template.write(out);
                    out.close();
                    template.close();
                    System.out.println("下载成功");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            //多条数据导出压缩包
            // 设置压缩包文件名
            String zipName = "危房排查";
            OutputStream out = setResponse(response, zipName + ".zip");
            ZipOutputStream zipOutputStream = new ZipOutputStream(out);
            //word模板路径
            String wordTemplatePath = "/templates/doc/securityRecord.docx";
            ClassPathResource templateResource = new ClassPathResource(wordTemplatePath);
            try {
                String filePath = templateResource.getFile().getPath();
                File file = new File(filePath);
                if (file.exists()) {
                    for (CdInspectDetail cdInspectDetail : cdInspectDetailList) {
                        //使用 po-tl 技术导出word模板
                        Map<String, Object> dataMap = new HashMap<>();
                        
                        String villager = cdInspectDetail.getVillager();
                        dataMap.put("villager", villager);
                        
                        Date inspectTimeDate = cdInspectDetail.getInspectTime();
                        String inspectTime = DateUtil.format(inspectTimeDate, "yyyyMMdd");
                        dataMap.put("inspectTime", inspectTime);
                        
                        String inspectObject = cdInspectDetail.getInspectObject();
                        dataMap.put("inspectObject", inspectObject);
                       
                        String inspectUser = cdInspectDetail.getInspectUser();
                        dataMap.put("inspectUser", inspectUser);
                     
                        String problem = cdInspectDetail.getProblem();
                        dataMap.put("problem", problem);
                       
                        String solve = cdInspectDetail.getSolve();
                        dataMap.put("solve", solve);
                        
                        String unitConfirmation = cdInspectDetail.getUnitConfirmation();
                        dataMap.put("unitConfirmation", unitConfirmation);
                        //查询附件
                        List<FileInfo> fileInfoList = fileService.getListFileCode(cdInspectDetail.getId());
                        List<PictureRenderData> imgList = new ArrayList<>();
                        if (fileInfoList != null && fileInfoList.size() > 0) {
                            for (FileInfo fileInfo : fileInfoList) {
                                //后缀
                                String extname = fileInfo.getExtname();
                                //路径
                                String fullPath = fileInfo.getFullPath();
                                File imgFile = new File(fullPath);
                                if (imgFile.exists()) {
                                    byte[] bytes = BytePictureUtils.getLocalByteArray(imgFile);
                                    PictureRenderData pictureRenderData = new PictureRenderData(500, 800, extname, bytes);
                                    pictureRenderData.setAltMeta("无");
                                    imgList.add(pictureRenderData);
                                }
                            }
                            if (imgList.size() > 0) {
                                dataMap.put("imgs", new NumbericRenderData(NumbericRenderData.FMT_DECIMAL, imgList));
                            }
                        }

                        // 设置文件名
                        String docxName = inspectTime + "_" + villager + "_排查_"+System.currentTimeMillis();
                        //创建压缩文件
                        ZipEntry zipEntry = new ZipEntry(docxName + ".docx");
                        zipOutputStream.putNextEntry(zipEntry);
                        ZipSecureFile.setMinInflateRatio(-1.0d);

                        XWPFTemplate template = XWPFTemplate.compile(templateResource.getInputStream()).render(dataMap);
                        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                        //先把XWPFTemplate写入到ByteArrayOutputStream流中,再写入到zipOutputStream中,防止 zipOutputStream提前关闭
                        template.write(byteArrayOutputStream);
                        byteArrayOutputStream.writeTo(zipOutputStream);
                        template.close();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException(9999, e.getMessage());
            } finally {
                try {
                    zipOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private OutputStream setResponse(HttpServletResponse response, String zipFileName) throws Exception {
        zipFileName = URLEncoder.encode(zipFileName, "UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment; filename=" + zipFileName);
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "no-store");
        response.addHeader("Cache-Control", "max-age=0");
        return response.getOutputStream();
    }

更多推荐