SpringBoot整合freemark动态生成word

前言

在日常工作中可能遇到这样的场景,像一些报告,合同,统计等等,这些word文档都有固定的格式,模板。只需要替换部分的内容数据就可以了,本文使用SpringBoot+freemaker实现这样的功能。

一、新建SpringBoot工程,导入依赖

<dependencies>
    <!--    引入web模块    -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!--   springboot提供了freemarker的starter     -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-freemarker</artifactId>
    </dependency>
</dependencies>

二、配置application.yml

#spring.freemarker.allow-request-override: false #是否允许HttpServletRequest属性覆盖(隐藏)控制器生成的同名模型属性。
#spring.freemarker.allow-session-override=false #是否允许HttpSession属性覆盖(隐藏)控制器生成的同名模型属性。
#spring.freemarker.enabled=true # 是否为此技术启用MVC视图解析。
#spring.freemarker.check-template-location: true #是否检查模板位置是否存在。
#spring.freemarker.expose-request-attributes=false # 在与模板合并之前,是否应该将所有请求属性添加到模型中。
#spring.freemarker.expose-session-attributes=false # 在与模板合并之前,是否应该将所有HttpSession属性添加到模型中。
#spring.freemarker.prefer-file-system-access=true # 是否倾向于在加载模板时访问文件系统。文件系统访问允许对模板更改进行热检测。
#spring.freemarker.prefix= # 在构建URL时用于查看名称的前缀。
#spring.freemarker.request-context-attribute= # 所有视图的RequestContext属性的名称。
#spring.freemarker.settings.*= # 传递到FreeMarker配置的知名FreeMarker密钥。
#spring.freemarker.template-loader-path=classpath:/templates/ # 以逗号分隔的模板路径列表。

# 配这几个够了
spring:
  freemarker:
    cache: false #是否启用模板缓存, 开发时关闭为好
    charset: UTF-8 #模板的字符编码
    content-type: text/xml; charset=utf-8
    expose-spring-macro-helpers: false # 是否公开一个名为“springMacroRequestContext”的RequestContext以供Spring的宏库使用。
    suffix: .ftl #在构建URL时附加到查看名称的后缀。
    template-loader-path: classpath:/templates/ #多个路径以逗号分隔

三、准备word模板

在这里插入图片描述

四、将word另存为xml文件

​ 将word另存为xml文件后复制到项目中类路径的templates文件夹下,修改后缀为.ftl。完成之后打开文件,格式化代码,找到之前写的占位符字符,数字,一一替换,有时需要稍微调整下格式,格式化代码后,应该很好调整。

在这里插入图片描述

​ 02占位符分开了,两个<w:r>留一个就好了。

​ 图片位置类似

在这里插入图片描述

五、开始代码

@GetMapping("/test/word")
    public void exportWorld() throws IOException {
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_0);
        configuration.setDefaultEncoding("utf-8");
        configuration.setClassForTemplateLoading(this.getClass(), "/templates");
        Template template = configuration.getTemplate("freemark生成world测试.ftl");
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("nameA","疤叔");
        dataMap.put("nameB","三皮");
        dataMap.put("city","大唐");
        dataMap.put("district","塔雁");
        dataMap.put("number","88");
        dataMap.put("area","120");
        dataMap.put("useArea","20");
        dataMap.put("device","次卧");
        dataMap.put("deviceItem","居住");
        dataMap.put("month","5");
        dataMap.put("beginTime","2020年12月10日");
        dataMap.put("endTime","2021年05月10日");
        // 无序列表数据
        List<String> listA = Arrays.asList("1.擅自将房屋转租、分租、转让、转借、联营、入股或与他人调剂交换的;",
                "2.利用承租房屋进行非法活动,损害公共利益的;",
                "3. 乙方租用期间,如需要装修,需征得甲方同意,退房时不得拆除装修物,否则甲方有权索赔;",
                "4. 合同生效后甲乙双方原则上不得毁约。如有特殊情况,需提前通知对方,否则给对方造成损失由过错方承担。");
        dataMap.put("listA",listA);
        // 表格数据
        Map<String, Object> tableMap = new HashMap<>();
        tableMap.put("furniture","电视");
        tableMap.put("isProvide","是");
        tableMap.put("price","5000");
        Map<String, Object> tableMap2 = new HashMap<>();
        tableMap2.put("furniture","冰箱");
        tableMap2.put("isProvide","是");
        tableMap2.put("price","6000");
        Map<String, Object> tableMap3 = new HashMap<>();
        tableMap3.put("furniture","洗衣机");
        tableMap3.put("isProvide","是");
        tableMap3.put("price","7000");
        Map<String, Object> tableMap4 = new HashMap<>();
        tableMap4.put("furniture","马桶");
        tableMap4.put("isProvide","否");
        tableMap4.put("price","0");
        List<Map<String, Object>> listB = Arrays.asList(tableMap,tableMap2,tableMap3,tableMap4);
        dataMap.put("listB",listB);
        // 图片数据
        String path = ResourceUtils.getURL("classpath:").getPath()+"static/aa.jpg";
        InputStream in = null;
        byte[] data = null;
        try {
            in = new FileInputStream(path);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e){
            e.printStackTrace();
        }
        BASE64Encoder encoder = new BASE64Encoder();
        String picture = encoder.encode(data);
        dataMap.put("picture",picture);
        // 输出   这里可以替换成响应流
        File outFile = new File("freemark已经生成world.doc");
        Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile),"UTF-8"));
        try {
            template.process(dataMap,out);
            out.flush();
            out.close();
        } catch (TemplateException e) {
            e.printStackTrace();
        }
    }

六、结果

在这里插入图片描述
在这里插入图片描述

到这里就OK了,快去试试吧!

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值