springboot使用freemaker根据模板生成word/excel文件


前言

开发过程中,会有需要生成特定格式的文件。但是直接用java代码生成文件的过程中,不方便控制文件内容的格式。
但是这个问题应该怎么解决呢?


一、freemaker是什么?

1.概念

FreeMarker是一个模版引擎,一个基于文本的模板输出工具(生成任意的HTML表单代码)。它是一个Java包,面向Java程序员的类库。它本身并不是针对最终用户的应用,而是允许程序员将其嵌入到他们的产品中。

FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序。使用 MVC 模式作为动态的WEB页面的想法,是为了分隔页面设计者 (HTML 设计者) 和程序员。.每个人做自己擅长的那一部分。设计者可以不通过程序员的改变或修改代码来改变网页的样子,因为应用逻辑(Java程序)和页面设计(FreeMarker 模版)是分开的。模板不会被复杂繁琐的程序框架所破坏。即使当一个项目的程序员和HIMTL页面的制作者是同一个人时,这种分隔也是很有用,因为这样有助于保持应用的清晰并易于维护。

尽管FreeMarker有一些编程的能力,但它并不是一个象PHP那样的成熟的编程语言。与Java不同的是,Java程序准备用来显示的数据,而Freemarker仅是生成文本页,这个文本页显示用于模板的预备数据。

在这里插入图片描述
FreeMarker 不是一个Web 应用框架,而更适合充当 Web 应用框架里的一个组件的角色,但 FreeMarker 引擎本身对 HTTP 或 servlets 并不关心,它仅仅是生成文本。在非 Web 应用环境中它同样能够展示完美的用途。然而值得注意的是:我们为使用 FreeMarker 提供了方便的解决方案,作为 Model2 框架(如 Struts )的视图组件,你也可以在模版中使用JSP标签。

2.特点

模板并没有包含程序逻辑来查找当前的访问者是谁,或者去查询数据库获取最新的产品。显示的数据是在FreeMarker之外准备的,通常是一些“真正的”编程语言(比如Java)所编写的代码。模板作者无需知道这些值是如何计算出的。事实上,这些值的计算方式可以完全被修改,而模板可以保持不变,而且页面的样式也可以完全被修改而无需改动模板。当模板作者(设计师)和程序员不是同一人时,显示逻辑和业务逻辑相分离的做法是非常有用的,即便模板作者和程序员是一个人,这么来做也会帮助管理应用程序的复杂性。保证模板专注于显示问题(视觉设计,布局和格式化)是高效使用模板引擎的关键 。

  1. 通用性
    能够生成各种文本:HTML、XML、RTF、Java源代码等等。
    易于嵌入到产品中:轻量级;不需要Servlet环境。
    插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等等。
    可以按所需生成文本:保存到本地文件;作为Email发送;从Web应用程序发送它返回给Web浏览器。
  2. 模板语言
    所有常用的指令:include、if/elseif/else、循环结构。
    在模板中创建和改变变量。
    几乎在任何地方都可以使用复杂表达式来指定值。
    命名的宏,可以具有位置参数和嵌套内容。
    名字空间有助于建立和维护可重用的宏库,或者将一个大工程分成模块,而不必担心名字冲突。
    输出转换块:在嵌套模板片段生成输出时,转换HTML转义、压缩、语法高亮等等;可以定义自己的转换。
  3. 通用数据模型
    FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在模板中显示。
    可以使用抽象(接口)方式表示对象(JavaBean、XML文档、SQL查询结果集等等),告诉模板开发者使用。方法,使其不受技术细节的打扰。
  4. 为Web准备
    在模板语言中内建处理典型Web相关任务(如HTML转义)的结构。
    能够集成到Model2 Web应用框架中作为JSP的替代。
    支持JSP标记库。
    为MVC模式设计:分离可视化设计和应用程序逻辑;分离页面设计员和程序员。
  5. 智能的国际化和本地化
    字符集智能化(内部使用UNICODE)。
    数字格式本地化敏感。
    日期和时间格式本地化敏感。
    非US字符集可以用作标识(如变量名)。
    多种不同语言的相同模板。
  6. XML处理能力
    <#recurse> 和<#visit>指令(2.3版本)用于递归遍历XML树。
    在模板中清楚和直接的访问XML对象模型 。

二、使用步骤

1.搭建springboot项目

使用idea编译器搭建java项目。项目中pom.xml依赖如下

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.9</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.xxxx</groupId>
	<artifactId>xxxx</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>xxxx</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-all</artifactId>
			<version>5.3.2</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<!-- aspect -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjtools</artifactId>
			<version>1.8.9</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.7.4</version>
		</dependency>
		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-core</artifactId>
			<version>3.4.2</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.28</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>2.0.10</version>
		</dependency>
		<dependency>
			<groupId>commons-httpclient</groupId>
			<artifactId>commons-httpclient</artifactId>
			<version>3.1</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

2.引入库

maven依赖如下(示例):

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

java依赖如下(示例):

import freemarker.template.Configuration;
import freemarker.template.Template; 

3.制作ftl模板

第一步,创建模板的word文件

将需要填充的字段使用’${name}'方式进行放置,以便可以通过代码对该内容进行填充。
具体效果如下。
在这里插入图片描述

第二步,将doc/docx文件,另存为xml文件

在这里插入图片描述

第三步,将xml文件后缀名,改为‘ftl’

在这里插入图片描述

第四步,将ftl文件放入项目中的resources文件夹中

在这里插入图片描述

第五步,使用快捷键‘ctrl+alt+L’键,对ftl文件进行整理。

整理前文件,如下图。格式混乱,无法进行查看
在这里插入图片描述
使用快捷键对文档进整理,文档格式变得清晰可见,方便我们进行查看。
在这里插入图片描述

4.使用freemaker工具类,生成文件

使用WordUtils类,根据ftl模板文件以及java代码查询的数据,将其生成word文件。
代码如下。

String filepath = new WordUtils().createWordFile(new HashMap<String, Object>(){
    
    {
    
    
            put("name",0);
        }}, "shenqingbiao/", "templates/111.ftl", "表");

5.实现效果

使用freemaker完成的效果图,如下。

在这里插入图片描述


freemaker常用标签

freemaker模板文件,常用标签总结如下。

1.Freemarker判断对象是否为空

freemarker中显示某对象使用‘ n a m e ’。但如果 n a m e 为 n u l l , f r e e m a r k e r 就会报错。如果需要判断对象是否为空:当然也可以通过设置默认值 {name}’。 但如果name为null,freemarker就会报错。 如果需要判断对象是否为空: 当然也可以通过设置默认值 name。但如果namenullfreemarker就会报错。如果需要判断对象是否为空:当然也可以通过设置默认值{name!‘’}来避免对象为空的错误。
如果name为空,就以默认值(“!”后的字符)显示。
对象user,name为user的属性的情况,user,name都有可能为空,
那么可以写成${(user.name)!‘’},表示user或者name为null,都显示为空。判断为空

<!--判断对象是否为空-->
<#if name??> </#if>

<!--判断不为空,name为空,就以默认值(“!”后的字符)显示-->
${name!''}

<!--user,name都有可能为空 表示user或者name为null,都显示为空-->
${(user.name)!''}

2.freemarker导出word时添加或勾选复选框

要实现功能就要用到freemarker中的if else标签了,首先我们在java代码中添加变量值,比如map.put(“check”,“true”);
然后修改模板,使用标签判断,模板修改成类似这样:
在这里插入图片描述
输出的勾选复选框主要的核心就是<w:sym w:font=“Wingdings 2” w:char=“F052” />这句话,把之前的<w:r>标签去掉也行,最简单的写法可以直接这样:

<#if check=="true">
    <w:sym w:font="Wingdings 2" w:char="F052" />
<#else>
    <w:t></w:t>
</#if>

效果如下:
在这里插入图片描述


总结

freemaker可以完美地解决根据模板生成文件的问题,想了解更多的使用方法,或者获取java代码都请关注公众号。

欢迎关注公众号‘CV算法小屋’

猜你喜欢

转载自blog.csdn.net/weixin_43228814/article/details/129766419