word下载

在实际开发中,经常会遇到将数据库的数据写到word模板中再下载的需求,开贴记录一下.

首先准备一个带有占位符的word模板并放到resources目录中

然后开始编写下载的方法

@ApiOperation(value = "下载零星工程审批表", notes = "下载零星工程审批表", httpMethod = "POST")
    @RequestMapping(value = "/downloadSporadicProject/{passId}", produces= MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void downloadSporadicProject(@PathVariable("passId")String passId, HttpServletRequest request, HttpServletResponse response) {
        // 查询数据
        ManagementSporadicProject sporadicProject = managementSporadicProjectService.getById(passId);
        Map<String, String> docMap = new HashMap<>();
        docMap.put("projectName", sporadicProject.getProjectName());
        docMap.put("location", sporadicProject.getLocation());
        docMap.put("construction", sporadicProject.getConstruction());
        docMap.put("supervision", sporadicProject.getSupervision());
        docMap.put("basis", sporadicProject.getBasis());
        docMap.put("detail", sporadicProject.getDetail());
        docMap.put("invest", sporadicProject.getInvest());
        docMap.put("oftime", sporadicProject.getOftime());
        String inputUrl = "白鹤滩水电站零星工程申报(审批)表.docx";
        // 临时文件
        String outputUrl = "白鹤滩水电站零星工程申报(审批)表temp.doc";
        // 替换模板中的占位符并写入到临时文件
        Common.changWord(inputUrl, outputUrl, docMap);
        // 将临时文件以流的方法输出
        try {
            //获取资源文件
            FileInputStream fileInputStream = new FileInputStream(outputUrl);
            //设置响应类型
            response.setCharacterEncoding("UTF-8");
            String type = new MimetypesFileTypeMap().getContentType(inputUrl);
            response.setHeader("content-Type", type);
            if(Objects.equals(getBrowser(request), "FF")){//如果是火狐,解决火狐中文名乱码问题
                response.setHeader("Content-Disposition",
                        "attachment;fileName=" +new String(inputUrl.getBytes("UTF-8"),"iso-8859-1"));
            }else{
                response.setHeader("Content-Disposition",
                        "attachment;filename=" + URLEncoder.encode(inputUrl, "UTF-8"));
            }

            //获取资源文件输入流和httpServletResponse的输出流
            try (InputStream inputStream =fileInputStream; ServletOutputStream servletOutputStream = response.getOutputStream()) {
                //把资源文件的二进制流数据copy到response的输出流中
                IOUtils.copy(inputStream, servletOutputStream);
                //清除flush所有的缓冲区中已设置的响应信息至客户端
                response.flushBuffer();
            } catch (Exception e) {
                //错误日志记录
                log.error(e.getMessage());
            }
        } catch (Exception e) {
            //自定义业务异常
            throw new ProjectException("导出模板失败");
        } finally {
            // 删除临时文件
            File file = new File(outputUrl);
            file.delete();
        }
    }


    // 判断浏览器种类的方法
    private String getBrowser(HttpServletRequest request) {
        String UserAgent = request.getHeader("USER-AGENT").toLowerCase();
        if (UserAgent.contains("msie"))
            return "IE";
        if (UserAgent.contains("firefox"))
            return "FF";
        if (UserAgent.contains("safari"))
            return "SF";
        return null;
    }
common方法

/**
     * 根据模板生成新word文档
     * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
     * @param inputUrl 模板存放地址
     * @param outputUrl 新文档存放地址
     * @param textMap 需要替换的信息集合
     */
    public static boolean changWord(String inputUrl, String outputUrl,
                                    Map<String, String> textMap) {
        //模板转换默认成功
        boolean changeFlag = true;
        try {
            ClassPathResource resource = new ClassPathResource(inputUrl);
            InputStream inputStream = resource.getInputStream();
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(inputStream);
            //解析替换文本段落对象
            changeText(document, textMap);
            //生成新的word
            File file = new File(outputUrl);
            FileOutputStream outputStream = new FileOutputStream(file);
            document.write(outputStream );
            outputStream .close();
        } catch (IOException e) {
            e.printStackTrace();
            changeFlag = false;
        }

        return changeFlag;
    }

/**
     * 替换段落文本
     * @param document docx解析对象
     * @param textMap 需要替换的信息集合
     */
    public static void changeText(XWPFDocument document, Map<String, String> textMap){
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            if(checkText(text)){
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {
                    //替换模板原来位置
                    String textValue = changeValue(run.toString(), textMap);
                    run.setText(textValue,0);
                }
            }
        }
    }

/**
     * 匹配传入信息集合与模板
     * @param value 模板需要替换的区域
     * @param textMap 传入信息集合
     * @return 模板需要替换区域信息集合对应值
     */
    public static String changeValue(String value, Map<String, String> textMap){
        Set<Map.Entry<String, String>> textSets = textMap.entrySet();
        for (Map.Entry<String, String> textSet : textSets) {
            //匹配模板与替换值 格式${key}
            String key = "${"+textSet.getKey()+"}";
            if(value.contains(key)){
                value = value.replace(key, textSet.getValue());//仅替换参数
            }
        }
        //模板未匹配到区域替换为空
        if(checkText(value)){
            value = "";
        }
        return value;
    }

前端

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
</head>
 
<body>
<input type="button" onclick="down()" value="点击">
</body>
<script type="text/javascript">
  function down(){
    // var url = window.encodeURI(this.axios.defaults.baseURL + '/ev/CommodityMaster/downloadTemp?fileName=D1120物资总清单导入模板.xlsx&token=' + localStorage.getItem("set_token"))
    // window.location.href = url
    // window.open("http://localhost:10000/download", '_blank')
    window.location.href = 'http://ip:30020/workflows/managementsporadicproject/download/2020092519170120bd63a2e25c49cb96a38dd1f123a623'
  }
</script>

 

©️2020 CSDN 皮肤主题: 技术工厂 设计师:CSDN官方博客 返回首页