SpringBoot如何基于POI-tl和word模板导出庞大的Word文件

目录
  • 前言
  • 知识准备
    • 什么是poi-tl
    • poi-tl的TDO模式
    • Template:模板
    • Data-model:数据
    • Output:输出
  • 实现案例
    • Pom依赖
    • 导出基于template的word
    • 导出markdown为word

前言

poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你可以非常方便的加入到你的项目中,并且拥有着让人喜悦的特性。本文主要介绍通过SpringBoot集成poi-tl实现模板方式的Word导出功能。

知识准备

需要理解文件上传和下载的常见场景和技术手段。@pdai

什么是poi-tl

如下内容来源于,​poi-tl官网​​。

poi-tl(poi template language)是Word模板引擎,使用Word模板和数据创建很棒的Word文档。

优势:

它还支持自定义插件,如下是官网代码仓库支持的特性

poi-tl supports custom functions (plug-ins), functions can be executed anywhere in the Word template, do anything anywhere in the document is the goal of poi-tl.


Feature


Description


:white_check_mark: Text


Render the tag as text


:white_check_mark: Picture


Render the tag as a picture


:white_check_mark: Table


Render the tag as a table


:white_check_mark: Numbering


Render the tag as a numbering


:white_check_mark: Chart


Bar chart (3D bar chart), column chart (3D column chart), area chart (3D area chart), line chart (3D line chart), radar chart, pie chart (3D pie Figure) and other chart rendering


:white_check_mark: If Condition


Hide or display certain document content (including text, paragraphs, pictures, tables, lists, charts, etc.) according to conditions


:white_check_mark: Foreach Loop


Loop through certain document content (including text, paragraphs, pictures, tables, lists, charts, etc.) according to the collection


:white_check_mark: Loop table row


Loop to copy a row of the rendered table


:white_check_mark: Loop table column


Loop copy and render a column of the table


:white_check_mark: Loop ordered list


Support the loop of ordered list, and support multi-level list at the same time


:white_check_mark: Highlight code


Word highlighting of code blocks, supporting 26 languages and hundreds of coloring styles


:white_check_mark: Markdown


Convert Markdown to a word document


:white_check_mark: Word attachment


Insert attachment in Word


:white_check_mark: Word Comments


Complete support comment, create comment, modify comment, etc.


:white_check_mark: Word SDT


Complete support structured document tag


:white_check_mark: Textbox


Tag support in text box


:white_check_mark: Picture replacement


Replace the original picture with another picture


:white_check_mark: bookmarks, anchors, hyperlinks


Support setting bookmarks, anchors and hyperlinks in documents


:white_check_mark: Expression Language


Fully supports SpringEL expressions and can extend more expressions: OGNL, MVEL...


:white_check_mark: Style


The template is the style, and the code can also set the style


:white_check_mark: Template nesting


The template contains sub-templates, and the sub-templates then contain sub-templates


:white_check_mark: Merge


Word merge Merge, you can also merge in the specified position


:white_check_mark: custom functions (plug-ins)


Plug-in design, execute function anywhere in the document

poi-tl的TDO模式

TDO模式:Template + data-model = output

以官网的例子为例:

XWPFTemplate template = XWPFTemplate.compile("template.docx").render(
new HashMap<String, Object>(){{
put("title", "Hi, poi-tl Word模板引擎");
}});
template.writeAndClose(new FileOutputStream("output.docx"));
  • compile 编译模板 - Template
  • render 渲染数据 - data-model
  • write 输出到流 - output

Template:模板

模板是Docx格式的Word文档,你可以使用Microsoft office、WPS Office、Pages等任何你喜欢的软件制作模板,也可以使用Apache POI代码来生成模板。

所有的标签都是以{{开头,以}}结尾,标签可以出现在任何位置,包括页眉,页脚,表格内部,文本框等,表格布局可以设计出很多优秀专业的文档,推荐使用表格布局。

poi-tl模板遵循“所见即所得”的设计,模板和标签的样式会被完全保留。

Data-model:数据

数据类似于哈希或者字典,可以是Map结构(key是标签名称):

Map<String, Object> data = new HashMap<>();
data.put("name", "Sayi");
data.put("start_time", "2019-08-04");

可以是对象(属性名是标签名称):

public class Data {
private String name;
private String startTime;
private Author author;
}

数据可以是树结构,每级之间用点来分隔开,比如​​{ {author.name} }​​标签对应的数据是author对象的name属性值。

Word模板不是由简单的文本表示,所以在渲染图片、表格等元素时提供了数据模型,它们都实现了接口RenderData,比如图片数据模型PictureRenderData包含图片路径、宽、高三个属性。

Output:输出

以流的方式进行输出:

template.write(OutputStream stream);

可以写到任意输出流中,比如文件流:

template.write(new FileOutputStream("output.docx"));

比如网络流:

response.setContentType("application/octet-stream");
response.setHeader("Content-disposition","attachment;filename=\""+"out_template.docx"+"\"");

// HttpServletResponse response
OutputStream out = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(out);
template.write(bos);
bos.flush();
out.flush();
PoitlIOUtils.closeQuietlyMulti(template, bos, out); // 最后不要忘记关闭这些流。

实现案例

这里展示SpringBoot集成poi-tl基于word模板导出Word, 以及导出markdown为word的例子。

Pom依赖

引入poi的依赖包

基础的包:

<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.12.0</version>
</dependency>

插件的包如下,比如highlight,markdown包

<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl-plugin-highlight</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl-plugin-markdown</artifactId>
<version>1.0.3</version>
</dependency>

导出基于template的word

controller中的方法:

@ApiOperation("Download Word")
@GetMapping("/word/download")
public void download(HttpServletResponse response){
try {
XWPFTemplate document = userService.generateWordXWPFTemplate();
response.reset();
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition",
"attachment;filename=user_word_" + System.currentTimeMillis() + ".docx");
OutputStream os = response.getOutputStream();
document.write(os);
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}

Service中的实际方法:

@Override
public XWPFTemplate generateWordXWPFTemplate() throws IOException {
Map<String, Object> content = new HashMap<>();
content.put("title", "Java 全栈知识体系");
content.put("author", "pdai");
content.put("site", new HyperlinkTextRenderData("https://pdai.tech", "https://pdai.tech"));

content.put("poiText", "Apache POI 是创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。用它可以使用Java读取和创建,修改MS Excel文件.而且,还可以使用Java读取和创建MS Word和MSPowerPoint文件。更多请参考[官方文档](https://poi.apache.org/index.html)");

content.put("poiText2", "生成xls和xlsx有什么区别?POI对Excel中的对象的封装对应关系?");
content.put("poiList", Numberings.create("excel03只能打开xls格式,无法直接打开xlsx格式",
"xls只有65536行、256列; xlsx可以有1048576行、16384列",
"xls占用空间大, xlsx占用空间小,运算速度也会快一点"));

RowRenderData headRow = Rows.of("ID", "Name", "Email", "TEL", "Description").textColor("FFFFFF")
.bgColor("4472C4").center().create();
TableRenderData table = Tables.create(headRow);
getUserList()
.forEach(a -> table.addRow(Rows.create(a.getId() + "", a.getUserName(), a.getEmail(), a.getPhoneNumber() + "", a.getDescription())));
content.put("poiTable", table);

Resource resource = new ClassPathResource("pdai-guli.png");
content.put("poiImage", Pictures.ofStream(new FileInputStream(resource.getFile())).create());

return XWPFTemplate.compile(new ClassPathResource("poi-tl-template.docx").getFile()).render(content);
}

private List<User> getUserList(){
List<User> userList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
userList.add(User.builder()
.id(Long.parseLong(i + "")).userName("pdai" + i).email("pdai@pdai.tech" + i).phoneNumber(121231231231L)
.description("hello world" + i)
.build());
}
return userList;
}

准备模板:

导出word:

导出markdown为word

controller中的方法:

@ApiOperation("Download Word based on markdown")
@GetMapping("/word/downloadMD")
public void downloadMD(HttpServletResponse response){
try {
XWPFTemplate document = userService.generateWordXWPFTemplateMD();
response.reset();
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition",
"attachment;filename=user_word_" + System.currentTimeMillis() + ".docx");
OutputStream os = response.getOutputStream();
document.write(os);
os.close();
} catch (Exception e) {
e.printStackTrace();
}
}

Service中实现的方法:

@Override
public XWPFTemplate generateWordXWPFTemplateMD() throws IOException {
MarkdownRenderData code = new MarkdownRenderData();

Resource resource = new ClassPathResource("test.md");
code.setMarkdown(new String(Files.readAllBytes(resource.getFile().toPath())));
code.setStyle(MarkdownStyle.newStyle());

Map<String, Object> data = new HashMap<>();
data.put("md", code);

Configure config = Configure.builder().bind("md", new MarkdownRenderPolicy()).build();

return XWPFTemplate.compile(new ClassPathResource("markdown_template.docx").getFile(), config).render(data);
}

准备模板:

导出word:

到此这篇关于SpringBoot如何基于POI-tl和word模板导出庞大的Word文件的文章就介绍到这了,更多相关SpringBoot导出Word文件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Springboot整合PageOffice 实现word在线编辑保存功能

    目录 一.查看官网 二.查看下载包 三.测试 四.gitee地址 一.查看官网 http://www.zhuozhengsoft.com/ 点击首页下载,进入页面: 最新得5.2,我们就下载5.2版本进行测试. 二.查看下载包 Samples5 为示例文件.放入tomcat中得webapps可以直接访问. localhost:8080/Samples5/index.html集成文件 里面有我们需要jar包 新建springboot项目以及简单测试这里就不多说了. 1.springboot 引入

  • SpringBoot之Helloword 快速搭建一个web项目(图文)

    背景: Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者. Spring Boot(英文中是"引导"的意思),是用来简化Spring应用的搭建到开发的过程.应用开箱即用,只要通过 "just

  • 解决springboot 连接 mysql 时报错 using password: NO的方案

    最近使用 springboot 配置 mysql 时出现了一个错误 Access denied for user ''@'localhost' (using password: YES) 或者 Access denied for user ''@'localhost' (using password: NO) 经发现这是 springboot 中 yml 语法的的一个坑,在我现在用的最新版本2.2.4 的springBoot中所推荐 yml 的格式是 data-username: root da

  • Java SpringBoot集成文件之如何使用POI导出Word文档

    目录 前言 知识准备 什么是POI 实现案例 Pom依赖 导出Word 前言 通过Apache POI导出excel,而Apache POI包含是操作Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API.所以也是可以通过POI来导出word的.本文主要介绍通过SpringBoot集成POI工具实现Word的导出功能. 知识准备 需要理解Apache POI遵循的标准(Office Open XML(OOXML)标准和微软的OLE 2复合文档

  • SpringBoot如何实现word文档转pdf

    目录 一.背景 二.方案选择 1.Spire.Doc for Java方案 2.docx4j方案 3.jodconverter+LibreOffice 方案 4.其他 三.实操 1.docx4j 2.poi-tl+jodconverter+LibreOffice 方案 四.结论 1.docx4j方案 2.jodconverter+LibreOffice 方案 一.背景 项目中有个需求大体意思是,上传一个word模板,根据word模板合成word文件,再将word文件转为pdf. 二.方案选择 1

  • 使用Springboot实现word在线编辑保存

    目录 一.查看官网 二.查看下载包 1.springboot 引入 pageoffice5.2.0.12.jar 2.springboot 引入thymleaf 3.编写配置文件 4.编写 index.html 和 word.html 4.1 index.html 4.2 word.html 5.编写PageOfficeController 6.application.yml 配置 7.注意 项目结构 三.测试 输入网址 注意事项 四.gitee地址 总结 一.查看官网 http://www.z

  • SpringBoot如何基于POI-tl和word模板导出庞大的Word文件

    目录 前言 知识准备 什么是poi-tl poi-tl的TDO模式 Template:模板 Data-model:数据 Output:输出 实现案例 Pom依赖 导出基于template的word 导出markdown为word 前言 poi-tl是一个基于Apache POI的Word模板引擎,也是一个免费开源的Java类库,你可以非常方便的加入到你的项目中,并且拥有着让人喜悦的特性.本文主要介绍通过SpringBoot集成poi-tl实现模板方式的Word导出功能. 知识准备 需要理解文件上

  • C# 使用Word模板导出数据的实现代码

    使用NPOI控件导出数据到Word模板中方式: 效果如下: Word模板: 运行结果: 实现如下: Student.cs using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ExportWord { public class Student { public Str

  • 基于apache poi根据模板导出excel的实现方法

    需要预先新建编辑好一个excel文件,设置好样式. 编辑好输出的数据,根据excel坐标一一对应. 支持列表数据输出,列表中列合并. 代码如下: package com.icourt.util; import org.apache.commons.collections4.CollectionUtils; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.user

  • springMVC导出word模板的方法

    本文实例为大家分享了springMVC导出word模板的具体代码,供大家参考,具体内容如下 controller 调用 @RequestMapping(value = "/exportWord") public void exportWord(HttpServletResponse response, HttpServletRequest request) throws IOException { String templatePath = request.getServletCont

  • Java 实现word模板转为pdf

    1. pom相关依赖 工具poi-tl (操作word文档模板) + jacob (将操作后的word模板转为pdf) <!-- poi-tl的pom依赖 --> <dependency> <groupId>com.deepoove</groupId> <artifactId>poi-tl</artifactId> <version>1.9.1</version> </dependency> <

  • 解析SpringBoot 搭建基于 MinIO 的高性能存储服务的问题

    目录 1.什么是MinIO 2.使用docker搭建minio服务 2.1.GNU/Linux和macOS 2.2.windows 3.下面开始搭建springboot环境 1.什么是MinIO MinIO是根据GNU Affero通用公共许可证v3.0发布的高性能对象存储.它与Amazon S3云存储服务兼容.使用MinIO构建用于机器学习,分析和应用程序数据工作负载的高性能基础架构. 官网地址:https://min.io/ 文档地址:https://docs.min.io/ 2.使用doc

  • Python基于回溯法子集树模板实现8皇后问题

    本文实例讲述了Python基于回溯法子集树模板实现8皇后问题.分享给大家供大家参考,具体如下: 问题 8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 分析 为了简化问题,考虑到8个皇后不同行,则每一行放置一个皇后,每一行的皇后可以放置于第0.1.2.....7列,我们认为每一行的皇后有8种状态.那么,我们只要套用子集树模板,从第0行开始,自上而下,对每一行的皇后,遍历它的8个状态即可. 代码: ''' 8皇后问题 '''

  • Python基于回溯法子集树模板解决0-1背包问题实例

    本文实例讲述了Python基于回溯法子集树模板解决0-1背包问题.分享给大家供大家参考,具体如下: 问题 给定N个物品和一个背包.物品i的重量是Wi,其价值位Vi ,背包的容量为C.问应该如何选择装入背包的物品,使得放入背包的物品的总价值为最大? 分析 显然,放入背包的物品,是N个物品的所有子集的其中之一.N个物品中每一个物品,都有选择.不选择两种状态.因此,只需要对每一个物品的这两种状态进行遍历. 解是一个长度固定的N元0,1数组. 套用回溯法子集树模板,做起来不要太爽!!! 代码 '''0-

  • Python基于回溯法子集树模板解决取物搭配问题实例

    本文实例讲述了Python基于回溯法子集树模板解决取物搭配问题.分享给大家供大家参考,具体如下: 问题 有5件不同的上衣,3条不同的裤子,4顶不同的帽子,从中取出一顶帽子.一件上衣和一条裤子作为一种搭配,问有多少种不同的搭配? 分析 换个角度看,现有头.身.腿三个元素,每个元素都有各自的几种状态. 头元素有['帽1', '帽2', '帽3', '帽4']共4种状态,身元素有['衣1', '衣2', '衣3', '衣4', '衣5']共5种状态,腿元素有['裤1', '裤2', '裤3']共3种状

  • Python基于回溯法子集树模板解决数字组合问题实例

    本文实例讲述了Python基于回溯法子集树模板解决数字组合问题.分享给大家供大家参考,具体如下: 问题 找出从自然数1.2.3.....n中任取r个数的所有组合. 例如,n=5,r=3的所有组合为: 1,2,3 1,2,4 1,2,5 1,3,4 1,3,5 1,4,5 2,3,4 2,3,5 2,4,5 3,4,5 分析 换个角度,r=3的所有组合,相当于元素个数为3的所有子集.因此,在遍历子集树的时候,对元素个数不为3的子树剪枝即可. 注意,这里不妨使用固定长度的解. 直接套用子集树模板.

随机推荐