java+freemarker生成Word文档 循环java对象 Vue前端下载Word文档

模板:

1.1准备ftl或xml模板文件

1.2另存为xml文件 然后编辑xml文件 在需要循环位置 xml文件中加上循环代码 

<#list fieldListMap as list>  </#list>  (filedListMap = javaEntity ; as=自己随便定义的变量名)

 

 我这里折叠了 sublimitext node++ 都可以 加上循环标签 

 1.3 存储为ftl格式 或 xml格式 都可以  这里读取就行了

 后端

2.后端使用freemarker-2.3.30生成  pom引入

    <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.30</version>
        </dependency>

Controller


    @PostMapping("generateInterfaceWord")
    public void generateInterfaceWord(@RequestBody InterfaceInfo interfaceInfo, HttpServletResponse response) {
        generateInterfaceWordService.genWord(interfaceInfo,response);
        System.out.println(interfaceInfo);
    }

Service

  public   void genWord(InterfaceInfo interfaceInfo,HttpServletResponse response){
//        List<Map<String, String>> maps = interfaceFieldMapper.selectInterfaceFieldByInterfaceId(interfaceInfo.getId());
        interfaceInfo.setFieldListMap(
                interfaceFieldMapper.selectInterfaceFieldByInterfaceId(interfaceInfo.getId())
        );



        String property = System.getProperty("user.dir");
        try {
           Configuration configuration = new Configuration();
            configuration.setDefaultEncoding("utf-8");
            //.xml 模板文件所在目录
            configuration.setDirectoryForTemplateLoading(new File(property+"/hisicom-admin/src/main/resources/tem"));
            // 输出文档路径及名称 (下载到指定位置
            File outFile = new File(property+"/hisicom-admin/src/main/resources/tem/generateInterfaceWord.docx");
            //以utf-8的编码读取模板文件
            Template t =  configuration.getTemplate("interfaceWordTemplate.ftl","utf-8");
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"),10240);
            t.process(interfaceInfo, out); //塞入数据
            out.close();
            System.out.println("生成成功");
            downLoadFile(outFile,response);
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("生成失败");
        }
    }


  /**
     * file下载
     * @author huangjie
     * @date 2022-8-5 17:31
     * @return void
     */
    public  void downLoadFile(File file,  HttpServletResponse response){
            //添加跨域访问
            //以流的形式传输
            response.setContentType("application/octet-stream");
            // 设置文件流编码格式
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition属性名 (attachment表示以附件的方式下载;inline表示在页面内打开)
            response.setHeader("Content-Disposition", "attachment; fileName="+file.getName()+".docx");
            try { //输入输出
                FileInputStream is = new FileInputStream(file);
                ServletOutputStream out = response.getOutputStream();
                byte[] buffer = new byte[1024];
                int i = 0;
                while ((i = is.read(buffer)) != -1) {
                    out.write(buffer,0,i);
                }
                //缓存区的数据进行输出
                out.flush();
                //关闭流
                out.close();
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

 entity domain 结构       (List<Map>为子级 需要word里循环的)


public class InterfaceInfo extends BaseEntity
{
    private static final long serialVersionUID = 1L;

    
    private String id;


    private String interfaceName;

    private String interfaceTablename;

    private Date interfaceCjsj;

    private String interfaceCjyh;

    private String interfaceSm;

    private String interfaceType;

    private String interfaceLrlcType;

    private JSONArray interfacetabledata;


    private List<Map<String,String>> fieldListMap;

}

前端 Vue+element-ui

 <el-button type="primary" @click="generateWord()">生成word接口文档</el-button>

  generateWord() { //生成接口文档
      var interfaceInfo = this.form;
      this.$confirm('确定生成接口文档, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        closeOnClickModal: false,

        type: 'warning'
      }).then(() => {

        generateInterfaceWord(interfaceInfo).then(res=>{
          const link=document.createElement('a');
          // let blob = new Blob([res.data],{type: 'applicationnd.ms-excel'});    //如果后台返回的不是blob对象类型,先定义成blob对象格式
            let blob =   new Blob([res], { type: 'application/octet-stream' })    //如果后台返回的直接是blob对象类型,直接获取数据
            // let _fileName = res.headers['content-disposition'].split(';')[1].split('=')[1]; //拆解获取文件名,
            link.style.display='none';
            // 兼容不同浏览器的URL对象
            const url = window.URL || window.webkitURL || window.moxURL;
            link.href=url.createObjectURL(blob);
            link.download =`数据中心接口对接文档.docx`;   //下载的文件名称
            link.click();
            window.URL.revokeObjectURL(url);  //  #URL.revokeObjectURL()方法会释放一个通过URL.createObjectURL()创建的对象URL. 当你要已经用过了这个对象URL,然后要让浏览器知道这个URL已经不再需要指向对应的文件的时候,就需要调用这个方法.
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
      console.log('当前实体entity',interfaceInfo)
    },

猜你喜欢

转载自blog.csdn.net/liuchenhaoy/article/details/131187376