FreeMarker 模板引擎快速入门 与 生成Word文档终极解决方案,Word 文档操作库汇总

目录

FreeMarker 模板引擎概述

FreeMarker 模板快速入门

Word 文档生成/导出终极解决方案

Word 文档操作库汇总


FreeMarker 模板引擎概述

1、Apache FreeMarker 是一个模板引擎:一个基于模板和不断变化的数据生成文本输出(HTML网页、电子邮件、配置文件、源代码等)的 Java 库。

2、市面上主流的 Java 模板引擎有:JSP、Velocity、Freemarker、Thymeleaf,Spring Boot 官方支持:Thymeleaf Templates、FreeMarker Templates、Groovy Templates 等模板引擎。

3、虽然 FreeMarker 最初是为在 mvc web 应用程序框架中生成 HTML 页面而创建的,但它并没有绑定到 servlet 或 HTML 或任何与 web 相关的内容,它也用于非 web 应用程序环境。

4、FreeMarker 的一些亮点特性:

1)强大的模板语言:条件块、迭代、赋值、字符串和算术运算和格式化、宏和函数(包括其他模板)、默认转义(可选)等
2)多用途和轻量级:零依赖,任何输出格式,可以从任何地方加载模板(可插拔),许多配置选项
3)国际化/本地化意识:对区域设置敏感的数字和日期/时间格式,本地化的模板变体。
4)XML处理功能:将XMLDOM-s放入数据模型中并遍历它们,甚至以声明方式处理它们
5)多功能数据模型:Java对象通过可插拔适配器作为变量树公开给模板,这决定了模板如何看待它们。

5、参考网址:

Apache FreeMarker 官网地址:https://freemarker.apache.org/、

官方原版英文使用手册:Apache FreeMarker Manual

翻译版中文在线手册:什么是 FreeMarker? - FreeMarker 中文官方参考手册

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

1、<#recurse> 和<#visit>指令(2.3版本)用于递归遍历XML树

2、在模板中清楚和直觉的访问XML对象模型

网页静态化

使用如 Freemarker/valocity 技术将动态的页面(jsp,asp.net,php) 转换成静态的页面(如 html),再通过浏览器直接访问静态页面。
浏览器直接访问静态的页面,不需要经过程序处理,访问速度高。
稳定性好。
更有效的防止安全漏洞问题,比如不易遭受黑客攻击。
静态的页面更容易被搜索引擎收录。

5、学过 JSP 或者Thymeleaf 任意一种模板引擎的,学习 FreeMarker 就不难,因为语法基本类似,都是使用模板引擎的标签将后台的数据注入到模板中:Template(模板) + data-model(数据模型) = output(静态页面)。

6、相对来说,JSP 和 Thymeleaf  更相似,而 FreeMarker  静态化的模板引擎多一个模板文件,JSP 和 Thymeleaf 都是用户访问后台,然后返回数据,最后直接填充到模板中(JSP或者Html)显示,而 FreeMarker 则必须先使用 Java 代码将数据注入到模板文件中,然后生成静态文件(如 html),最后用户直接访问静态文件。

7、FreeMarker 优点:因为访问的是静态文件,就像访问一个写死的 html 文件一样,它不需要再请求数据库,所以访问速度快;FreeMarker 缺点:缺点也恰恰在此,因为只要数据发生了改变,就必须得重新将新数据注入到模板文件重新生成静态文件,否则用户容易看到过期的数据。

8、个人感受:以后前后端分离才是王道,一是前后端分离后,后台只需要提供接口,不用再写什么模板引擎的标签了,这样前后端只需要调接口即可,对双方无疑都是最好的;二是前端技术日新月异,已经不是很多年前了,展示数据完全没必要再使用 JSP、Thymeleaf 、FreeMarker 这种模板引擎了,前端自己已经有足够优秀的库和框架了。

9、FreeMarker 最常见的用途:一是网页静态化;二是做代码生成,很多代码生成器都是使用的 FreeMarker,先提供模板文件,然后将数据注入进去,最后生成源代码。

FreeMarker 模板快速入门

1、既然前后端分离才是王道,那模板引擎就不学了吗?这也不绝对,因为像 FreeMarker 除了生成网页,还可以做一些其它操作,比如生成 RFT 办公文档、生成文件作为Email发送、操作 XML 文档等等.

2、本文先一步一步练习 FreeMarker 的标签语法,后面再整合 Spring Boot。本文环境:Java JDK 1.8 + freemarker 2.3.30.

3、导入依赖如下,更多版本以及二进制 Jar 包可以从官网获取。

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

4、准备 freeMarker 模板文件,官方默认后缀名是 .ftl,理论上任意格式都可以,但是只有 .ftl 格式时,IDEA 才会有 freeMarker 模板标签的语法提示。(模板文件入门示例源码)。

5、使用 FreeMarker 提供 API 将数据模型填充到模板文件中,然后生成静态文件静态页面生成源码)。

6、下面是演示的动图:

7、freeMarker 的语法相对 JSP 和 Thymeleaf  来说还是有些另类,但好在 IDEA 不用安装插件也能对 .ftl 文件中的 FreeMarker 语法进行提示,下面将平时开发中常见的需求汇总说明如下:

1)freeMarker 控制严格,当操作数据的值为 null 时,生成静态文件时会报错,比如 ${user},如果 user 不存在,或者 user 的值为 null,则生成静态文件时报错。

2)FTL 标记/标签(FreeMarker模板语言标记):类似于 HTML 标记/标签,为了与 HTML 标记区分,用 #或者@ 开始。
3)ftl 注释:包含在 <#-- 和 -->(而不是 <!-- 和 -->)之间,生成的静态文件中是不含这些注释的。

4)ftl 严格区分大小写,如 <#list> 正确,<#LIST> 错误,${name} 和 ${NAME} 结果不一样。
5)ftl 标记不能位于另一个 FTL 标记内部,例如 <#if <#include 'foo'>='bar'>...</if> 是错误的。

6)注释可以位于 FTL 标记和 ${xxx} 内部

7)FreeMarke r会忽略 FTL 标记中的空白字符,但是 "<"、"</" 和指令之间不允许有空白字符。

${ key }key 为变量,${ key } 取值后可以直接显示内容,如:${person.pid}、${userName}
${ .now }获取当前时间
${ key?cap_first }首字母转大写
${ key?uncap_first }首字母转小写
${ key?lower_case}字母全部转小写
${ key?upper_case}字母全部转大写
${ key.name?length}获取字符串内容长度
${ key?size}获取数组、集合的大小,如:${basicList?size}
${ key?replace(String substring,String replacement) }替换子符串,如 ${personA1.name?replace("MX","猫熊")}
<#if key == "xxx">xxxx</#if>字符串比较与数字比较一样,都是使用 ==,不等于是 != .
<#if key?contains(String substring)>xxxx</#if>判断值是否包含子字符串(substring)
${ key?index_of(String substring)}获取字符串的索引位置,从0开始
${ key?substring(from)}、${ key?substring(int from,int toExclusive)}
FreeMarker 不会自动进行类型转换,必须手动转换,比如 key 的值是 100001,${ key } 返回的数字,默认会使用千分位符号,所以显示的是 10,001,而 ${ key?c} 转成字符串后,则显示为 100001
${ key?c }数字类型转字符串类型
${ key?string("currency")}数字转货币字符串,比如 :9500.11F -> ¥9,500.11
${ key?string("percent")}数字转百分比,比如:9500.11F -> 9,50011%
${person.birthday?date}
${person.birthday?time}
${person.birthday?datetime}
${person.birthday?string("yyyy/MM/dd HH:mm:ss")}

表示取 yyyy-MM-dd,如 2021-1-2

表示取 HH:mm:ss,如 13:02:45

表示取 yyyy-MM-dd HH:mm:ss,如 2021-1-2 13:03:06

自定义日期格式,如 2021/01/02 13:04:31

${ key?eval }字符串类型转数字类型,整数浮点数都可以
${ key?number }字符串类型转数字类型,整数浮点数都可以
<#if key != "">判断值是否为空
<#if key??> xxxx </#if>判断值是否为 null 或者 key 不存在,如左侧所示表示当 key 的值不为  null 时,输出 xxxx。
${key!"为null时的默认值"}、${key!""}、${testNull!}当值为 null 时,可以给出默认值,或者变为空值,!"" 可以省略为 !
<#if key>xxx</#if>布尔值判断,如:<#if person.married>已婚</#if>, married 属性是一个 Boolean 类型。
${ key?string(String true,String false)}如果 key 的结果为 true,则输出 true 的内容,否则输出 false 的内如,如:${p.married?string("是","否")}
${ key[int index]}、${ key[int index].xxx}获取指定索引位置的元素,如数组、List 等等,例如:${array[0]}、${personList[2].name}
<#if person.salary < 8000>
    &nbsp;低产阶级
<#elseif person.salary < 8000>
    &nbsp;中产阶级
<#else >
    &nbsp;资本家
</#if>
if 指令:条件判断语句
<#list personList as person>
    <tr>
        <td> 序号:${person_index+1},</td>
        <td> 名称:${person.name},</td>
        <td> 薪资:${person.salary?c}</td>
    </tr>
</#list>
list 指令:数组遍历、集合遍历。其中为变量加上后缀 _index 表示当前循环的索引,从0开始。
<#include "./commFooter.ftl">include 指令:引入公共的模板,比如公共的头、公共的底部,或者公共的左侧菜单树等等。注意是引入模板文件,被引用的模板只需要提供公共内容即可,其它的如 <html> <title>等标签都不需要重复写。
<#assign toekn=xxx>

自定义变量,如:

<#--自定义变量,值有:普通类型、对象类型、接收后台传递的值-->
<#assign toekn="8748378TT8Y66">
<#assign book={"id":"77878TTR55","name":"水浒传","price":89.88}>

算数运算符FreeMarker 表达式中完全支持算术运算, 包括:+、-、*、/、%
逻辑运算符&、||、!,逻辑运算符只能作用于布尔值,否则异常
比较运算符

==、!=、> 或者 gt、>= 或者 gte、< 或者 lt、<= 或者 lte

<#if book.price gte 89.88>价格大于60</#if>

<#if book.price gte 89.88 && book.name == "水浒传">水浒传价格大于60</#if>

Word 文档生成/导出终极解决方案

1、对于 Word 文档生成/导出功能,虽然 Apache POI 也能做,但是 API 却比较繁琐,所有的格式都需要通过代码来控制,比如字体、颜色、缩进、行距、大小、标题等等,而如果使用 FreeMarker 却非常简单。

2、这得先归功于 Microsoft、WPS、OpenOffice 等办公软件,它们可以将 .doc、.docx 等格式的 Word 文档另存为 .xml 格式,这个 xml 文件里面存储了整个 Word 文档的内容以及格式,如果把 Word 文档比作浏览器中的网页,那么这个 xml 文件就相当于 html 文件。

3、你可以亲自测试一下,将 Word 文档另存为 xml 文件,然后右击保存后的 xml 文件,打开方式仍然选择 Microsoft、WPS、OpenOffice 等办公软件,可以发现和 .doc、docx 等格式完全一样。

4、所以 Java 应用 Word 文档导出终极解决方案如下:

1)先准备一个 .doc、.docx 等格式的 Word 文档模板,后期不变的内容可以直接写死,后期需要变化的内容可以自定义一些占位符先占着位置,比如 #1、#2...,然后设置好文档的格式,比如 字体、颜色、缩进、行距、大小、表格等等。
2)然后将设置好格式的 Word 模板另存为 .xml 文件,使用工具(比如 notepad++ 或者网上的在线格式化工具)对 xml 文件内容进行格式化,然后导入到项目中,并修改后缀名为 .ftl
3)提供 FreeMarker 模板对应的数据模型,也就是需要往 ftl 文件中注入数据的对象,比如 Map、POJO 等等。
4)然后将 ftl 模板文件中的占位符 #1、#2...使用 FreeMarker 标签进行替换,比如单个值使用 ${xxx} 取值,表格使用 <#list> 遍历等等。
5)最后 Java 后台使用 FreeMarker API 将 .ftl 模板和数据模型生成 .doc 文档。
6)如果是 Web 应用,需要导出文档,则可以将生成好的 .doc 文件使用 javax.servlet.ServletResponse#getWriter 打印流进行输出,让浏览器自动下载。

5、如上所示,使用 FreeMarker 生成 Word 的优点如下:

1)因为模板的格式是提前设置好的,所以生成的 Word 文档完全和事先的预期一模一样。
2)即使是再复杂的格式,只要用户事先能将 Word 文档的格式做得出来,那么 FreeMarker 就能为它注入数据,保证格式一致。
3)Word 另存为 xml 后,后缀改成 ftl 的好处是 IDEA 会有 FreeMarker 语法提示,原则上不改后缀名都是可以的。
4)FreeMarker 根据 xml 生成 .doc 文件和根据 ftl 生成 .html 完全一样的,FreeMarker 标签可以在任意文件中编写,比如 ftl、xml、java、js 等等。

6、涉及到的在线源码如下:

word 源文件以及 .xml 源文件:https://github.com/wangmaoxiong/red-door/tree/master/src/test/resources/word

freeMarker 模板文件:https://github.com/wangmaoxiong/red-door/blob/master/src/test/resources/ftl/purchaseContract.ftl

FreeMarker 后台生成源码:https://github.com/wangmaoxiong/red-door/blob/master/src/test/java/com/wmx/reddoor/freeMarker/PurchaseContract.java

7、此种方式的优点是简单,缺点是只能生成 .doc 格式,无法生成 .docx 格式,如果需要生成 .docx 格式,则操作步骤稍微要多一点点(因为没有需求,所以暂时不讨论)。

Word 文档操作库汇总

1、推荐使用 poi-tl,poi-tl(poi template language)是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,使用模板和数据创建很棒的Word文档,可以非常方便的加入到项目中,并且拥有着让人喜悦的特性。

方案移植性功能性易用性

Poi-tl

Java跨平台

Word模板引擎,基于Apache POI,提供更友好的API

低代码,准备文档模板和数据即可

Apache POI

Java跨平台

Apache项目,封装了常见的文档操作,也可以操作底层XML结构

文档不全,这里有一个教程:Apache POI Word快速入门

Freemarker

XML跨平台

仅支持文本,很大的局限性

不推荐,XML结构的代码几乎无法维护

OpenOffice

部署OpenOffice,移植性较差

-

需要了解OpenOffice的API

HTML浏览器导出

依赖浏览器的实现,移植性较差

HTML不能很好的兼容Word的格式,样式糟糕

-

Jacob、winlib

Windows平台

-

复杂,完全不推荐使用

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: Java导出Word文档可以利用Apache POI和Freemarker模板引擎来实现。 Apache POI是一个用于操作Microsoft Office文档的Java API。它提供了对Word文档的读取、创建和修改的功能。通过使用Apache POI,可以轻松地在Java代码中创建一个空的Word文档,并添加文本、表格、图片等内容。同时,还可以设置文档的样式、格式和布局等,以满足不同的需求。 而Freemarker模板引擎则是用于生成动态文本输出的工具。它基于模板和数据模型,可以将数据动态填充到指定的Word模板中,生成最终的Word文档。使用Freemarker模板引擎可以使文档生成更加灵活和可扩展,根据不同的数据模型生成不同的文档内容,提高了代码的可维护性和重用性。 要实现导出Word文档的功能,首先需要引入Apache POI和Freemarker的相关依赖。接下来,创建一个空的Word文档,使用Apache POI的API对文档进行操作,例如添加标题、段落、表格等内容,以及设置样式和格式。然后,结合Freemarker模板引擎,根据自定义的数据模型填充数据到Word模板中,生成最终的Word文档。 通过以上的方法,利用Apache POI和Freemarker模板引擎可以轻松地实现Java导出Word文档的功能。这种方式方便、灵活,适用于需要动态生成Word文档的各种场景,例如报告生成、合同生成等。同时,这两个工具都有良好的文档和丰富的示例代码,方便开发者进行学习和使用。 ### 回答2: Java 导出 Word 文档利用 Apache POI 和 FreeMarker 模板引擎的基本步骤如下: 1. 首先,确保你的项目已经导入了 Apache POI 和 FreeMarker 的相关依赖。 2. 创建一个 Word 文档模板,可以使用 Microsoft Office 软件创建一个空白文档,并将需要的样式和占位符添加到模板中。占位符可以使用自定义的标记,例如 `${name}`。 3. 在 Java 代码中,使用 Apache POI 创建一个 Word 文档对象 `XWPFDocument`。例如:`XWPFDocument document = new XWPFDocument();`。 4. 使用 FreeMarker 模板引擎加载并解析 Word 文档模板。创建一个 `Configuration` 对象,并设置模板文件的路径或类路径。例如:`Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);`。 5. 根据模板文件路径或类路径加载模板文件。例如:`Template template = configuration.getTemplate("template.docx");`。 6. 创建一个数据模型,将数据填充到模板中。可以使用 `Map` 或自定义的 Java 对象作为数据模型。例如:`Map<String, String> data = new HashMap<>();`,然后将需要填充的数据放入 `data` 中。 7. 使用 FreeMarker 模板引擎的 `process` 方法将数据模型与模板进行合并,生成最终的 Word 文档内容。例如:`StringWriter writer = new StringWriter();`,`template.process(data, writer);`。 8. 将生成Word 文档内容写入到 Apache POI 的 `XWPFDocument` 对象中。可以使用 `OutputStream` 将内容写入到文档对象中。例如:`OutputStream outputStream = new FileOutputStream("output.docx");`,`writer.flush();`,`document.write(outputStream);`,`outputStream.close();`。 9. 最后,记得在使用完毕后关闭相关资源,例如关闭输出流、释放内存等。 以上就是利用 Apache POI 和 FreeMarker 模板引擎导出 Word 文档的基本步骤,通过动态填充数据,可以生成灵活且具有个性化内容的 Word 文档。 ### 回答3: Java导出Word文档可以使用Apache POI和Freemarker模板引擎相结合的方法来实现。Apache POI是一个用于处理Microsoft Office文档的Java,而Freemarker是一个基于模板的文本生成引擎。 首先,我们需要在项目中引入Apache POI和Freemarker的相关依赖。 然后,我们需要创建一个Word文档的模板文件,模板文件中可以包含一些占位符,用于动态添加数据。比如,我们可以在模板文件中添加一个{{name}}的占位符。 接下来,在Java中,我们可以使用Freemarker来解析模板文件。首先,我们需要创建一个Configuration对象,并指定模板文件的路径。然后,我们可以使用Template类的getTemplate方法来获取模板对象。 接着,我们可以创建一个Map对象,将需要动态添加的数据放入其中。比如,我们可以将姓名(name)放入Map中。 然后,我们可以调用Template类的process方法来解析模板并将数据填充到占位符中。我们可以将解析后的结果保存在一个字符串中。 最后,我们可以使用Apache POI来创建一个新的Word文档。我们可以创建一个XWPFDocument对象,并使用其createParagraph方法来创建段落。然后,我们可以使用XWPFRun对象的setText方法将之前解析后的结果添加到段落中。 最后,我们可以将生成Word文档保存到指定路径。我们可以使用XWPFDocument对象的write方法将文档保存为文件。 综上所述,通过使用Apache POI和Freemarker模板引擎,我们可以方便地导出Word文档。我们只需要创建一个模板文件,使用Freemarker来解析模板并将数据填充到占位符中,然后使用Apache POI来创建新的文档并保存即可。这种方法可以加快开发速度,同时也使得代码结构更加清晰易读。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

蚩尤后裔-汪茂雄

芝兰生于深林,不以无人而不芳。

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

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

打赏作者

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

抵扣说明:

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

余额充值