SpringBoot 中使用 freemarker 模板文件动态生成/导出 word 文档

jar 包依赖

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

 

生成word方法

/**
 * 生成 word 文件
 *
 * @param dataMap 待填充数据
 * @param templateName 模板文件名称
 * @param filePath 模板文件路径
 * @param fileName 生成的 word 文件名称
 * @param response 响应流
 */
public static void createWord(Map dataMap, String templateName, String filePath, String fileName, HttpServletResponse response){
    // 创建配置实例
    Configuration configuration = new Configuration(Configuration.VERSION_2_3_28);
    // 设置编码
    configuration.setDefaultEncoding(StandardCharsets.UTF_8.name());
    // ftl模板文件
    configuration.setClassForTemplateLoading(WordUtil.class, filePath);

    try {
        // 获取模板
        Template template = configuration.getTemplate(templateName);
        response.setHeader("Content-disposition",
                "attachment;filename=" + URLEncoder.encode(fileName + ".doc", StandardCharsets.UTF_8.name()));
        // 定义输出类型
        response.setContentType("application/msword");
        Writer out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
        // 生成文件
        template.process(dataMap, out);

        out.flush();
        out.close();
    } catch (Exception e){
        e.printStackTrace();
    }
}

 

数据准备

简单数据

@RequestMapping("/download")
public void download(HttpServletResponse response) {
    Map map = Maps.newHashMap();
    map.put("name", "张三");
    map.put("age", 20);
    map.put("sex","男");
    WordUtil.createWord(map, "template.ftl", "/templates/", "测试文件", response);
}

 

集合数据

若需生成如下格式的 word
在这里插入图片描述

freemarker 中对于集合对象的遍历

<#if (userList?? && userList?size > 0) >
	<#list userList as user>
		...
		${user.name} 
		...
		${user.sex} 
		...
	</#list>
</#if>

如果占位符是集合类型,需要在 XXX.doc 文件 转 XXX.ftl 模板文件中修改为以上格式

集合类型模板数据模拟

@RequestMapping("/download")
public void download(HttpServletResponse response) {
    ArrayList<UserInfo> userList = Lists.newArrayList();
    for (int i = 0; i < 5; i++) {
        UserInfo userInfo = new UserInfo("Jaemon" + i, i % 2, i + 10, "13566321235");
        userList.add(userInfo);
    }
    ArrayList<RoleInfo> roleList = Lists.newArrayList();
    roleList.add(new RoleInfo(1L, "管理员", "admin"));

    Map<String, Object> map = Maps.newHashMap();
    map.put("date", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
    map.put("author", "Jaemon");
    map.put("userTable","用户表格");
    map.put("userList", userList);
    map.put("roleTable","角色表格");
    map.put("roleList",roleList);

    WordUtils.createWord(map, "template.ftl", "/templates/", "测试文件", response);
}

 

生成的文件
在这里插入图片描述

 

ftl 模板文件编写说明

新建 word 文件, 填写模板内容, 待填充内容使用占位符 ${key}, 列表使用 ${list.name} , 然后另存为 .xml 文件, 注意: 检查 xml 文件中占位符是否有错乱, 最后重命名为 ftl 文件即可

具体详见: 模板文件生成规则

 

Freemarker 语法

<!-- list的大小判断 -->
<#if (list?size>0)>
</#if>

<!-- 布尔判断 -->
<#if flag == true>
</#if>

<!-- list<map<string,list>> -->
<#list list as map>
    <#list map?keys as key>  
        <#if key== "客户管理">
            <#list map[key] as item>
                ${item_index+1}
            </#list>
        </#if>
    </#list>
</#list>

<!-- 与三目运算符结合使用 -->
${((item.is_tem!)==1)?string('是','否')}

<!-- 有值显示 -->
${item.city!}

<!-- ?? 判断左侧的变量是否丢失,相当于java中的null的判断,或者这个变量是否未定义 -->
<#if data.page_no ??>
    
<!-- 变量为空设置默认值 -->
${user!"变量为空则给一个默认值"}
    
<!-- 如果值是数字的话,如果过大,会采用科学计数法,数字中间会多一个逗号,比如1,1500, 去掉科学计数法 -->
{$ur.id?c}
    
<!-- 空判断和对象集合 -->
<#if users??>
    <#list users as user >
        ${user.id} - ${user.name}
    </#list>
<#else>
	${user!"变量为空则给一个默认值"}
</#if>
    
<!-- Map集合 -->
<#list mapData?keys as key>
	Key: ${key} - Value: ${mapData[key]}
</#list>

<!-- 通过Value遍历Map -->
<#list mapData?values as value>
	Value: ${value}
</#list>  

list指令

<#list nameList as names>    
  ${names}   
</#list>

<#list 1..count as x> 
</#list>

<#list sequence as item>  
	<#if item = "spring">
        <#break>
	</#if>  
</#list>  

<#assign seq = ["winter", "spring", "summer", "autumn"]>  
<#list seq as x>  
	${x_index + 1}. ${x}
    <#if x_has_next>,</#if>  
</#list>  


<#-- list排序 -->
<!-- list内元素是基本数值,字符串日期 -->    
<#list sequence?sort as item>
    ...
</#list>

<!-- list内元素是对象 -->
<#list sequence?sort_by("age") as item>
    ...
</#list>

<!-- list内元素是对象且降序排序 -->
<#list sequence?sort_by("age")?reverse as item>
    ...
</#list>

list 内置相关指令

  • item_index: 当前变量的索引值
  • item_has_next: 是否存在下一个对象
  • break: 跳出迭代

if 指令

<#if (number1 + number2 > 12 || number1 - number2 > 6)>
    "*" : ${number1 * number2}
<#else>
    "/" : ${number1 / number2}
</#if>
    
    
<#if users??>  <!-- 空判断 -->
    <#list users as user >
        ${user.id} - ${user.name}
    </#list>
<#else>
    ${user!"变量为空则给一个默认值"}
</#if>

switch 指令

<#switch name>
    <#case "freemarker">This is a freemarker's template.<#break>
    <#case "velocity">This is a velocity's template.<#break>
    <#default>This is a jsp's template.
</#switch>

内建函数指令

<!-- 第一个字母大写 -->
${data?cap_first}

<!-- 所有字母小写 -->
${data?lower_case}

<!-- 所有字母大写 -->
${data?upper_case}

<!-- 数值取整数 -->
${floatData?int}

<!-- 获取集合的长度 -->
${users?size}

<!-- 时间格式化 -->
${dateTime?string("yyyy-MM-dd")}

<!-- 三种不同的数字格式  -->
${book?string.number}   <!-- 20 -->
${book?string.currency} <!-- $20.00 --> 
${book?string.percent}  <!-- 20% -->  

 

Reference

Spring Boot是一个用于创建独立的、基于Spring的应用程序的框架。它简化了基于Spring的应用程序的开发过程,提供了自动配置和约定大于配置的原则。LibreOffice是一个开源的办公套件软件,它提供了创建和编辑Word文档等功能。Freemarker是一个适用于Java平台的模板引擎,可以实现动态生成文本文件,比如docx文档。 在Spring Boot应用程序使用LibreOffice和Freemarker动态生成docx文档的过程如下: 1. 在pom.xml文件添加相关依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>org.libreoffice</groupId> <artifactId>libreoffice-java</artifactId> <version>1.1.0</version> </dependency> ``` 2. 创建一个Freemarker模板文件,用于定义生成docx文档的格式和内容。模板文件可以包含动态的变量,比如用户的姓名、日期等。 3. 在Spring Boot的主类创建一个API接口,用于接收生成docx文档的请求。可以使用`@GetMapping`或`@PostMapping`注解指定API的路径。 4. 在API的方法使用Freemarker模板引擎来动态生成docx文档。可以使用`Configuration`类来加载模板文件使用`Template`类来渲染模板生成文档内容。 5. 使用LibreOffice的Java API来将docx文档转换为其他文件格式,比如PDF。可以使用`OfficeManager`类来启动一个LibreOffice实例,使用`OfficeDocumentConverter`类来执行转换操作。 6. 将生成的docx文档保存到服务器指定的目录,并返回给客户端进行下载。 通过以上步骤,就可以在Spring Boot应用程序利用Freemarker模板和LibreOffice实现动态生成docx文档的功能了。这样可以更加灵活和方便地生成各种格式的文档,并且可以自定义文档的内容和样式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jaemon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值