springboot配合Freemark模板生成word,前台vue接收并下载【步骤详解并奉上源码】

简介: springboot配合Freemark模板生成word,前台vue接收并下载【步骤详解并奉上源码】

前言

FreeMarker是一款模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页、电子邮件、配置文件、源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

成果图:

从浏览器直接下载到本地

下载好的word文件 蓝色圈圈里的数据均为动态数据

注:这里可以自行写word模板

一、使用步骤

1.打开word模板,给需要赋值的位置先填上数据,方便查找编写freemarker代码,如下图

2.将word文件另存为xml文件 到桌面 ,然后修改jhj.xml修改后缀 改为 jhj.ftl 文件

1.刚打开的xml文件会比较长不太方便查看 可以把内容复制到菜鸟工具进行格式化 找到之前做好标记的位置 将数据替换

2.list循环数据 : 在<w:tr> 前加上 <#list taskstep as taskstep> ** </w:tr>在这之后加上结束标签 </#list>


二、后台代码

1.模板存放位置

2.依赖引入

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>3.9</version>
      </dependency>

      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
      </dependency>

3.后端代码

    @RequestMapping(value = "/Testrecord", method = RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<byte[]>   Testrecord(@RequestBody Map<String, Object> paras, HttpServletRequest request) throws Exception {
        String path = request.getServletContext().getRealPath("/");
        //设备信息  获取数据
        BaseResult<Map<String, Object>> DeviceTask= deviceModuleService.getOneDeviceTask((Integer) paras.get("id"));

        //测试条件 获取数据
  
        BaseResult<List<DeviceTaskStep>> deviceTaskStepByParas = deviceModuleService.getDeviceTaskStepByParas(paras);


        List<DeviceTaskStep> taskstep = deviceTaskStepByParas.getData();

//       循环方式
        BaseResult<List<DeviceTaskLoop>> deviceTaskLoopByParas = deviceModuleService.getDeviceTaskLoopByParas(paras);
        System.out.println(deviceTaskLoopByParas.getData().toString()+"SAD");
        List<DeviceTaskLoop> taskloop = deviceTaskLoopByParas.getData();
//        设备信息
        Map<String, Object> datataskstep = DeviceTask.getData();
        System.out.println(datataskstep);
        Object applyNo = datataskstep.get("reportNo");
        Configuration configuration = new Configuration();
        configuration.setDefaultEncoding("utf-8");
        // 模板存放路径
        configuration.setClassForTemplateLoading(this.getClass(), "/template");
        // 获取模板文件
        Template template = configuration.getTemplate("Testrecord.ftl");
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Map<String,Object> resultMap = new HashMap<>();
//        设备信息  
        resultMap.put("reportno",datataskstep.get("reportNo"));//word加入单数据
        resultMap.put("devicename",datataskstep.get("deviceName"));
        resultMap.put("manufacturer",datataskstep.get("manufacturer"));
        resultMap.put("basictypename",datataskstep.get("basicTypeName"));
        resultMap.put("devicecode",datataskstep.get("deviceCode"));

        System.out.println();
        if(datataskstep.get("startTime")==null){
            resultMap.put("starttime"," ");
        }else {
            resultMap.put("starttime",datataskstep.get("startTime"));
        }
        if(datataskstep.get("endTime")==null){
            resultMap.put("endtime"," ");
        }else {
            resultMap.put("endtime",datataskstep.get("endTime"));
        }


        // 测试条件
        List<Map<String, Object>> tasksteps = new ArrayList<Map<String, Object>>();
        if (taskstep.size()==0){
            Map<String, Object> map=new HashMap<String, Object>();
            map.put("stepNum"," ");
            map.put("temp",  " ");
            map.put("humid",  " ");
            map.put("timeHour",  " ");
            map.put("timeMin", " ");
            tasksteps.add(map);
        }else {
            for (int i = 0; i < taskstep.size(); i++) {
//
                Map<String, Object> map=new HashMap<String, Object>();
                map.put("stepNum", taskstep.get(i).getStepNum());
                map.put("temp",  taskstep.get(i).getTemp());
                map.put("humid",  taskstep.get(i).getHumid());
                map.put("timeHour",  taskstep.get(i).getTimeHour());
                map.put("timeMin",  taskstep.get(i).getTimeMin());
                tasksteps.add(map);
            }
        }



//        循环方式
        List<Map<String, Object>> taskloops = new ArrayList<Map<String, Object>>();
        //这里做一个判断  如果加入了空数据会报错
        if (taskloop.size()==0){
            Map<String, Object> map=new HashMap<String, Object>();
            map.put("loopNum", " ");
            map.put("stepStart", " ");
            map.put("stepStop", " ");
            map.put("loopCount",  " ");
            taskloops.add(map);
        }else {
            for (int i = 0; i < taskloop.size(); i++) {
//            System.out.println(taskloop.get(i).getTaskId()+"AAA");
                Map<String, Object> map=new HashMap<String, Object>();
                map.put("loopNum", taskloop.get(i).getLoopNum());
                map.put("stepStart",  taskloop.get(i).getStepStart());
                map.put("stepStop",  taskloop.get(i).getStepStop());
                map.put("loopCount",  taskloop.get(i).getLoopCount());
                taskloops.add(map);
            }
        }

    //word加入循环数据
        resultMap.put("taskstep",tasksteps);
        resultMap.put("taskloop",taskloops);
//        测试条件

        File outFile = new File(String.format("%s%s.%s",path,applyNo,"doc"));
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
        template.process(resultMap,out);
        out.flush();
        out.close();
        //这是是绝对路径
        // String path = "C:\\Users\\zhangyf\\";
        // String filename = "aaa.doc";
        String filename = String.format("%s.%s",applyNo,"doc");
        File file = new File(path+filename);
        HttpHeaders headers = new HttpHeaders();
        //下载显示的文件名,解决中文名称乱码问题
        String downloadFileName = new String(filename.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        //通知浏览器以attachment(下载方式)打开图片
        headers.setContentDispositionFormData("attachment", downloadFileName);
        //application/octet-stream:二进制流数据(最常见的文件下载)
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        //201 HttpStatus.CREATED
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers,HttpStatus.CREATED);

    }

3.前端vue 浏览器下载代码

export function Testrecord(data) {
    return axios({
        url: '/h/deviceModule/Testrecord',
        method: 'post',
        data: data,
     responseType: 'blob' //这里改一下
    })
}


  // 导出测试结果模板
    hanldeExportTaskDoc(record) {
      const params = {
        id: record.id,
     taskId: record.id,
      }
   
   
      this.$api.Testrecord(params).then((res) => {
        if (res) {
       console.log(res);
     
  this.downloadWordFile(res,record.reportNo);
  }
      })
  
    },
  
  downloadWordFile (file,No) {
    console.log(No+'.docx');
    const blob = new Blob([file], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
  
    const url = URL.createObjectURL(blob)
    const a = document.createElement('A')
  
    a.download = No+'.docx'  //下载的文件名  自行设置
    a.href = url
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
  },
  
  

五、最后一步完成后 ,就是成果图的效果啦!

相关文章
|
26天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的留守儿童爱心网站设计与实现(计算机毕设项目实战+源码+文档)
博主是一位全网粉丝超过100万的CSDN特邀作者、博客专家,专注于Java、Python、PHP等技术领域。提供SpringBoot、Vue、HTML、Uniapp、PHP、Python、NodeJS、爬虫、数据可视化等技术服务,涵盖免费选题、功能设计、开题报告、论文辅导、答辩PPT等。系统采用SpringBoot后端框架和Vue前端框架,确保高效开发与良好用户体验。所有代码由博主亲自开发,并提供全程录音录屏讲解服务,保障学习效果。欢迎点赞、收藏、关注、评论,获取更多精品案例源码。
61 10
|
26天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的家政服务管理平台设计与实现(计算机毕设项目实战+源码+文档)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
46 8
|
26天前
|
JavaScript 搜索推荐 Java
基于SpringBoot+Vue实现的家乡特色推荐系统设计与实现(源码+文档+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
57 8
|
26天前
|
JavaScript Java 测试技术
基于SpringBoot+Vue实现的高校食堂移动预约点餐系统设计与实现(源码+文档+部署)
面向大学生毕业选题、开题、任务书、程序设计开发、论文辅导提供一站式服务。主要服务:程序设计开发、代码修改、成品部署、支持定制、论文辅导,助力毕设!
70 3
|
29天前
|
XML Java 应用服务中间件
Spring Boot 两种部署到服务器的方式
本文介绍了Spring Boot项目的两种部署方式:jar包和war包。Jar包方式使用内置Tomcat,只需配置JDK 1.8及以上环境,通过`nohup java -jar`命令后台运行,并开放服务器端口即可访问。War包则需将项目打包后放入外部Tomcat的webapps目录,修改启动类继承`SpringBootServletInitializer`并调整pom.xml中的打包类型为war,最后启动Tomcat访问应用。两者各有优劣,jar包更简单便捷,而war包适合传统部署场景。需要注意的是,war包部署时,内置Tomcat的端口配置不会生效。
233 17
Spring Boot 两种部署到服务器的方式
|
29天前
|
Dart 前端开发 JavaScript
springboot自动配置原理
Spring Boot 自动配置原理:通过 `@EnableAutoConfiguration` 开启自动配置,扫描 `META-INF/spring.factories` 下的配置类,省去手动编写配置文件。使用 `@ConditionalXXX` 注解判断配置类是否生效,导入对应的 starter 后自动配置生效。通过 `@EnableConfigurationProperties` 加载配置属性,默认值与配置文件中的值结合使用。总结来说,Spring Boot 通过这些机制简化了开发配置流程,提升了开发效率。
61 17
springboot自动配置原理
|
1月前
|
XML JavaScript Java
SpringBoot集成Shiro权限+Jwt认证
本文主要描述如何快速基于SpringBoot 2.5.X版本集成Shiro+JWT框架,让大家快速实现无状态登陆和接口权限认证主体框架,具体业务细节未实现,大家按照实际项目补充。
87 11
|
1月前
|
缓存 安全 Java
Spring Boot 3 集成 Spring Security + JWT
本文详细介绍了如何使用Spring Boot 3和Spring Security集成JWT,实现前后端分离的安全认证概述了从入门到引入数据库,再到使用JWT的完整流程。列举了项目中用到的关键依赖,如MyBatis-Plus、Hutool等。简要提及了系统配置表、部门表、字典表等表结构。使用Hutool-jwt工具类进行JWT校验。配置忽略路径、禁用CSRF、添加JWT校验过滤器等。实现登录接口,返回token等信息。
369 12
|
1月前
|
Java 测试技术 应用服务中间件
Spring Boot 如何测试打包部署
本文介绍了 Spring Boot 项目的开发、调试、打包及投产上线的全流程。主要内容包括: 1. **单元测试**:通过添加 `spring-boot-starter-test` 包,使用 `@RunWith(SpringRunner.class)` 和 `@SpringBootTest` 注解进行测试类开发。 2. **集成测试**:支持热部署,通过添加 `spring-boot-devtools` 实现代码修改后自动重启。 3. **投产上线**:提供两种部署方案,一是打包成 jar 包直接运行,二是打包成 war 包部署到 Tomcat 服务器。
47 10
|
1月前
|
存储 安全 Java
Spring Boot 3 集成Spring AOP实现系统日志记录
本文介绍了如何在Spring Boot 3中集成Spring AOP实现系统日志记录功能。通过定义`SysLog`注解和配置相应的AOP切面,可以在方法执行前后自动记录日志信息,包括操作的开始时间、结束时间、请求参数、返回结果、异常信息等,并将这些信息保存到数据库中。此外,还使用了`ThreadLocal`变量来存储每个线程独立的日志数据,确保线程安全。文中还展示了项目实战中的部分代码片段,以及基于Spring Boot 3 + Vue 3构建的快速开发框架的简介与内置功能列表。此框架结合了当前主流技术栈,提供了用户管理、权限控制、接口文档自动生成等多项实用特性。
84 8