您当前的位置:首页 > 电脑百科 > 程序开发 > 框架

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

时间:2022-08-01 09:34:51  来源:  作者:Java全栈知识体系

前文我们介绍了通过Apache POI通过来导出word的例子;那如果是word模板方式,有没有开源库通过模板方式导出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 officewps 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 responseoutputStream 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中的实际方法

@Overridepublic 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中实现的方法

@Overridepublic 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

 

示例源码

https://Github.com/realpdai/tech-pdai-spring-demos

参考文章

http://deepoove.com/poi-tl/

更多内容

告别碎片化学习,无套路一站式体系化学习后端开发: Java 全栈知识体系(https://pdai.tech)



Tags:SpringBoot   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
详解基于SpringBoot的WebSocket应用开发
在现代Web应用中,实时交互和数据推送的需求日益增长。WebSocket协议作为一种全双工通信协议,允许服务端与客户端之间建立持久性的连接,实现实时、双向的数据传输,极大地提升了用...【详细内容】
2024-01-30  Search: SpringBoot  点击:(23)  评论:(0)  加入收藏
SpringBoot如何实现缓存预热?
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。那么问题来了,在 Spring Boot 项目启动之后,在什么时候?在哪里可以将数据加载到缓存系...【详细内容】
2024-01-19  Search: SpringBoot  点击:(91)  评论:(0)  加入收藏
SpringBoot3+Vue3 开发高并发秒杀抢购系统
开发高并发秒杀抢购系统:使用SpringBoot3+Vue3的实践之旅随着互联网技术的发展,电商行业对秒杀抢购系统的需求越来越高。为了满足这种高并发、高流量的场景,我们决定使用Spring...【详细内容】
2024-01-14  Search: SpringBoot  点击:(94)  评论:(0)  加入收藏
公司用了六年的 SpringBoot 项目部署方案,稳得一批!
本篇和大家分享的是springboot打包并结合shell脚本命令部署,重点在分享一个shell程序启动工具,希望能便利工作。 profiles指定不同环境的配置 maven-assembly-plugin打发布压...【详细内容】
2024-01-10  Search: SpringBoot  点击:(185)  评论:(0)  加入收藏
简易版的SpringBoot是如何实现的!!!
SpringBoot作为目前最流行的框架之一,同时是每个程序员必须掌握的知识,其提供了丰富的功能模块和开箱即用的特性,极大地提高了开发效率和降低了学习成本,使得开发人员能够更专注...【详细内容】
2023-12-29  Search: SpringBoot  点击:(144)  评论:(0)  加入收藏
用 SpringBoot+Redis 解决海量重复提交问题
前言 一:搭建redis的服务Api 二:自定义注解AutoIdempotent 三:token创建和检验 四:拦截器的配置 五:测试用例 六:总结前言:在实际的开发项目中,一个对外暴露的接口往往会面临很多...【详细内容】
2023-12-20  Search: SpringBoot  点击:(56)  评论:(0)  加入收藏
SpringBoot中如何优雅地个性化定制Jackson
当使用 JSON 格式时,Spring Boot 将使用ObjectMapper实例来序列化响应和反序列化请求。在本教程中,我们将了解配置序列化和反序列化选项的最常用方法。一、默认配置默认情况下...【详细内容】
2023-12-20  Search: SpringBoot  点击:(139)  评论:(0)  加入收藏
springboot-如何集成Validation进行参数校验
一、步骤概览 二、步骤说明1.引入依赖包在 pom.xml 文件中引入 validation 组件,它提供了在 Spring Boot 应用程序中进行参数校验的支持。<!-- WEB 程序依赖包 --><dependen...【详细内容】
2023-12-13  Search: SpringBoot  点击:(159)  评论:(0)  加入收藏
优雅的springboot参数校验,你学会了吗?
前言在后端的接口开发过程,实际上每一个接口都或多或少有不同规则的参数校验,有一些是基础校验,如非空校验、长度校验、大小校验、格式校验;也有一些校验是业务校验,如学号不能重...【详细内容】
2023-11-29  Search: SpringBoot  点击:(200)  评论:(0)  加入收藏
Springboot扩展点之BeanDefinitionRegistryPostProcessor,你学会了吗?
前言通过这篇文章来大家分享一下,另外一个Springboot的扩展点BeanDefinitionRegistryPostProcessor,一般称这类扩展点为容器级后置处理器,另外一类是Bean级的后置处理器;容器级...【详细内容】
2023-11-27  Search: SpringBoot  点击:(180)  评论:(0)  加入收藏
▌简易百科推荐
Qt与Flutter:在跨平台UI框架中哪个更受欢迎?
在跨平台UI框架领域,Qt和Flutter是两个备受瞩目的选择。它们各自具有独特的优势,也各自有着广泛的应用场景。本文将对Qt和Flutter进行详细的比较,以探讨在跨平台UI框架中哪个更...【详细内容】
2024-04-12  刘长伟    Tags:UI框架   点击:(7)  评论:(0)  加入收藏
Web Components实践:如何搭建一个框架无关的AI组件库
一、让人又爱又恨的Web ComponentsWeb Components是一种用于构建可重用的Web元素的技术。它允许开发者创建自定义的HTML元素,这些元素可以在不同的Web应用程序中重复使用,并且...【详细内容】
2024-04-03  京东云开发者    Tags:Web Components   点击:(11)  评论:(0)  加入收藏
Kubernetes 集群 CPU 使用率只有 13% :这下大家该知道如何省钱了
作者 | THE STACK译者 | 刘雅梦策划 | Tina根据 CAST AI 对 4000 个 Kubernetes 集群的分析,Kubernetes 集群通常只使用 13% 的 CPU 和平均 20% 的内存,这表明存在严重的过度...【详细内容】
2024-03-08  InfoQ    Tags:Kubernetes   点击:(23)  评论:(0)  加入收藏
Spring Security:保障应用安全的利器
SpringSecurity作为一个功能强大的安全框架,为Java应用程序提供了全面的安全保障,包括认证、授权、防护和集成等方面。本文将介绍SpringSecurity在这些方面的特性和优势,以及它...【详细内容】
2024-02-27  风舞凋零叶    Tags:Spring Security   点击:(62)  评论:(0)  加入收藏
五大跨平台桌面应用开发框架:Electron、Tauri、Flutter等
一、什么是跨平台桌面应用开发框架跨平台桌面应用开发框架是一种工具或框架,它允许开发者使用一种统一的代码库或语言来创建能够在多个操作系统上运行的桌面应用程序。传统上...【详细内容】
2024-02-26  贝格前端工场    Tags:框架   点击:(52)  评论:(0)  加入收藏
Spring Security权限控制框架使用指南
在常用的后台管理系统中,通常都会有访问权限控制的需求,用于限制不同人员对于接口的访问能力,如果用户不具备指定的权限,则不能访问某些接口。本文将用 waynboot-mall 项目举例...【详细内容】
2024-02-19  程序员wayn  微信公众号  Tags:Spring   点击:(43)  评论:(0)  加入收藏
开发者的Kubernetes懒人指南
你可以将本文作为开发者快速了解 Kubernetes 的指南。从基础知识到更高级的主题,如 Helm Chart,以及所有这些如何影响你作为开发者。译自Kubernetes for Lazy Developers。作...【详细内容】
2024-02-01  云云众生s  微信公众号  Tags:Kubernetes   点击:(58)  评论:(0)  加入收藏
链世界:一种简单而有效的人类行为Agent模型强化学习框架
强化学习是一种机器学习的方法,它通过让智能体(Agent)与环境交互,从而学习如何选择最优的行动来最大化累积的奖励。强化学习在许多领域都有广泛的应用,例如游戏、机器人、自动驾...【详细内容】
2024-01-30  大噬元兽  微信公众号  Tags:框架   点击:(72)  评论:(0)  加入收藏
Spring实现Kafka重试Topic,真的太香了
概述Kafka的强大功能之一是每个分区都有一个Consumer的偏移值。该偏移值是消费者将读取的下一条消息的值。可以自动或手动增加该值。如果我们由于错误而无法处理消息并想重...【详细内容】
2024-01-26  HELLO程序员  微信公众号  Tags:Spring   点击:(95)  评论:(0)  加入收藏
SpringBoot如何实现缓存预热?
缓存预热是指在 Spring Boot 项目启动时,预先将数据加载到缓存系统(如 Redis)中的一种机制。那么问题来了,在 Spring Boot 项目启动之后,在什么时候?在哪里可以将数据加载到缓存系...【详细内容】
2024-01-19   Java中文社群  微信公众号  Tags:SpringBoot   点击:(91)  评论:(0)  加入收藏
站内最新
站内热门
站内头条