Java使用freemarker生成word文件
首先声明我的项目是一个web项目,生成的word文件直接通过response响应发送给前端。如果不是web项目的话可以像网上的其他教程一样将生成的word保存在本地。
要利用freemarker生成word文档,首先需要创建word文档模板(即.doc文档),word模板中要动态生成的文字都使用占位符${string}代替,如下图
将word模板另存为xml文件
然后将文件的后缀.xml改为.ftl。
将这个模板(.ftl)文件放到我们项目的resource目录下,这里我是新建了一个wordtemp文件夹,用于放word模板。顺便放两张图片在这个wordtemp目录下。
打开这个模板文件。这里有一个坑,在word另存为xml文件的时候很可能会把我们写好的占位符拆分掉,就像下面这样
我们需要自己手动把占位符${string}恢复,只需把中间多余的标签删除掉就好
然后我们找到<<w:binData>标签,会发现这个标签中有一大堆的英文字符串
这些字符串是图片的base64码。
我们将这些base64码删除掉,用一个占位符替代
为了实现动态的添加表格行数和图片数量,我们还要用到freemarker的<list>
标签。
list标签的语法:<#list 集合名 as 迭代元素临时变量名></#list>
<w:tr></w:tr>
标签表示word中的表格的一行记录,我们找到<w:tr></w:tr>
标签,并用freemarker的<list>
标签将其包起来。
找到离我们的图片占位符最近的<w:p></w:p>标签,用list标签将他们括起来
模板文件修改完了,接下来我们开始在代码里为这些占位符填充数据。
引入freemarker依赖:
<dependency><groupId>org.freemarker</groupId><artifactId>freemarker</artifactId><version>2.3.28</version>
</dependency>
创建一个单例的Configuration对象,真心不推荐像网上的很多教程一样,每次生成word都要重新创建一个Configuration
@org.springframework.context.annotation.Configuration
public class WordConf {/*** 将freemarker的Configuration对象作为一个单例对象,可以避免重复创建的性能开销* 这里我是将Configuration对象作为bean交给spring容器来管理,如果不是spring项目的话可以自己写一个单例模式* 从Configuration类上的注释可以找到说明:Configuration是有状态的,线程不安全的,但是它的各种get方法是线程安全的* 所以一旦这个单例对象被配置好以后就不该再调用它的set方法* @return*/@Beanpublic Configuration wordConfiguration(){Configuration result = new Configuration(DEFAULT_INCOMPATIBLE_IMPROVEMENTS);result.setDefaultEncoding("utf-8");//设置模板加载器result.setClassForTemplateLoading(this.getClass(), "/wordtemp");return result;}
}
书本实体类代码:
@Data
@AllArgsConstructor
public class Book {private String name;private Double price;private Date createTime;
}
controller层代码
@Controller
@Slf4j
public class WordController {@Resource(name = "wordConfiguration")private Configuration wordConfiguration;/*** 导出word* @param response*/@GetMapping("/getBookWord")public void getBookWord(HttpServletResponse response) {//书本集合List<Book> books = new ArrayList<>();books.add(new Book("笑傲江湖", 20.5, new Date()));books.add(new Book("倚天屠龙记", 30.8, new Date()));try {//图片的base64集合List<String> bookImages = new ArrayList<>();String image1 = encodeBase64File("wordtemp/timg.jpg");String image2 = encodeBase64File("wordtemp/timg_2.jpg");bookImages.add(image1);bookImages.add(image2);Map<String, Object> dataModel = new HashMap<>();dataModel.put("shopName", "陈大大出版社");dataModel.put("books", books);dataModel.put("bookImages", bookImages);response.setCharacterEncoding("UTF-8");response.setHeader("Content-Disposition", "attachment; filename=books.doc");//加载模板Template template = wordConfiguration.getTemplate("booksTemp.ftl", "utf-8");template.process(dataModel, response.getWriter());//response的Writer不需要我们手动关,tomcat会帮我们关的} catch (Exception e) {log.error("导出word异常:", e);}}/*** 将文件转为base64字符串* @param path 文件地址* @return* @throws IOException*/public String encodeBase64File(String path) throws IOException {//读取resource目录下的文件try (InputStream inputStream = WordController.class.getClassLoader().getResourceAsStream(path)){byte[] buffer = new byte[inputStream.available()];inputStream.read(buffer);return new BASE64Encoder().encode(buffer);}}}
启动项目,用浏览器测试一下,成功下载了word
总结一下用freemarker生成word的几个步骤:
- 创建word,在word中设计排版,要动态生成的文字使用占位符${string}
- 将word另存为xml文件。将保存好的xml文件后缀修改为.ftl
- 将模板文件(.ftl)放到项目中,打开文件看看占位符是否被拆分了。
- 编写Java代码,给占位符赋值。
PS,由于freemarker每次生成word都要从磁盘中读取.ftl文件,相比于其他纯内存生成word的工具包,freemarker多了一次IO操作,所以性能稍弱,不适用于大并发的场景。
Java使用freemarker生成word文件相关推荐
- Java使用freemarker生成word文档并转pdf文档
Java使用freemarker生成word文档后转pdf 先来看看效果图 进入正题 项目需求: 为订单后生成对应的pdf文档,文档内包含图片. 方案一:使用freemarker和itext把html ...
- 若依 springboot 使用freemarker生成word文件,并导出下载
目录 freemarker生成word文件并导出 一.环境准备 二.编写代码 1.实体类 2.mapper.xml文件 3.mapper.java文件 4.Service.java 5.Service ...
- Freemarker生成word文件,打开后页眉和页脚图片不显示
Freemarker生成word文件,打开后页眉和页脚图片不显示 在我们开发过程中通常会把模板文件Ctrl+Alt+L格式化,方便处理.这样就造成word的标签格式产生多余的换行或者空白,但是word ...
- Java 用 Freemarker 生成 Word 时内容换行
一.原因 试过各种换行符 '\r' '\n' '\r\n' '(char)11' 全部都不行!!! 原因是:Java 用 Freemarker 生成 Word 时的换行符被自动解析忽略掉 二.解决方法 ...
- Java技术:SpringBoot集成FreeMarker生成word文件
今天给大家分享SpringBoot集成FreeMarker模板引擎生成word文件的用法,感兴趣的可以学一下,完整源码地址在文章末尾处,欢迎互相沟通交流! 一.什么是F ...
- Java通过Freemarker生成docx文件
一:doc和docx文件 首先我们要了解doc和docx两种word文件的相同点和不同点,为什么ftl可以直接生成doc而生成docx就会报错. 1.doc和docx文件构成 我们可以把doc格式的w ...
- Java实现freemarker生成word模板
博主在做的是将word源文件中的内容读取出来,然后按照固定的格式输出,当然,源文件有大量,所以编写了程序来批量自动生成目标文件. 本文要介绍的就是如何生成模板,并将从源文件截取的内容填充到模板文件(即 ...
- Java使用iText生成word文件的完美解决方案(亲测可行)
JAVA生成WORD文件的方法目前有以下种: 一种是jacob 但是局限于windows平台 往往许多JAVA程序运行于其他操作系统 在此不讨论该方案 一种是pio但是他的excel处理很程序 wor ...
- Java使用iText生成word文件的解决方案
JAVA生成WORD文件的方法目前有以下种: 一种是jacob 但是局限于windows平台 往往许多JAVA程序运行于其他操作系统 在此不讨论该方案 一种是pio但是他的excel处理很程序 wor ...
最新文章
- 一段C语言和汇编的对应分析,揭示函数调用的本质
- linux cmake编译源码,linux安装mysql(源码)以及cmake编译
- Windows版本Oracle审计日志,【情报】Oracle ORA-28056: 未能将审计记录写入 Windows 事件日志...
- router3 BGP2 属性及选路
- MD5 32位加密算法源码(测试通过)(系转载 飞扬天下)
- STM32跑分?看看你的能跑多少分!
- Google | 突破瓶颈,打造更强大的Transformer
- AI 崛起,科学家的天下,程序员的谢幕
- [PhalApi实战篇(1)]Redis队列处理异步任务
- JAVA-数据类型、变量、常量
- python基础语法手册-python语法手册
- c 语言重载参数类型不同重载和,C/C++函数重载与缺省参数
- 考虑云计算来降成本:良药或毒药?
- 电脑计算机推荐笔记本电脑,十佳办公笔记本电脑排名,性价比高的笔记本电脑推荐...
- cce是什么意思_CCE 是什么
- thunderbird 配置exchange邮箱
- lay和lied_高考英语词汇辨析:lie, lay, lain, laid, lying等用法
- 如何看懂Elastic解决方案与Gartner的魔力象限
- 又省时间又省心,微信小程序记住密码功能大揭秘
- Out of range value for column