目录

  • 一、背景

  • 二、实现思路

  • 三、快速上手

  • 四、多行数据如何生成?

  • 五、局限性

  • 六、总结

一、背景

小哈最近这段时间开始负责一个新的产品:下载中心。啥玩意这是?

产品的目的其实就是统一管控各业务组文件下载功能(包括一些海量数据的导出,文件合并上传等),项目组不用自己再去实现各式各样的文件(PDF, Word, Excel)生成, 统一对接下载中心,由下载中心统一完成文件的生成、合并、上传、下载流程。

问题来了,这里面包括一些复杂文件的生成,如带有复杂样式的 Excel 文件,比如下面这个样子的:

这种复杂样式的 Excel, 如果说放到各个业务线去实现还是好办的,因为站在各个业务组的角度,场景变化不会太多,按照文件格式,代码写死即可。

但是站在下载中心的角度,因为需要对接各个业务中心,每个业务中心生成的样式都不一样,不可能每个业务组接进来,我都得定制的写一套生成代码吧!这显然也不合常理!

那么,有没有什么一劳永逸的办法呢?答案是肯定的!

二、实现思路

要说实现方式,你的脑海里可能第一会想到传统的 Apache poi,jxl ,亦或者是阿里出品 EasyExcel 等等。

PS: 关于阿里的 EasyExcel, 小哈之前有分享过 ,没看过的小伙伴们,可以看下《惊了!7 行代码优雅地实现 Excel 文件导出功能?》这篇文章。

对于这种复杂样式,要是用 Apache poi, jxl, 阿里 EasyExcel 去实现,不可避免的,代码肯定会非常繁琐。

有没有啥优雅(偷懒的)的方式呢?

其实我们可以通过视图引擎 Freemark、Velocity 来帮我们生成复杂样式 Excel 文件,无需关心花里胡哨的复杂样式,只关注于填充数据即可。接下来,我们以 Freemark 作为示例来讲解,如何生成这个复杂样式的 Excel 文件。

拓展阅读: 什么是 Freemark ?

FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。

其实,对于Java 后端来说,它更常被用来服务端动态渲染 html 页面返回给浏览器。前些年还比较火热,近些年因为前后端分离的火热,也开始慢慢淡出视野了。

三、开始上手

3.1 添加依赖

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

注意: 小哈这里基于 Spring Boot 写的测试代码,版本号可以无需指定,否则,你需要手动指定好版本号。

3.2 导出 xml 模板文件

首先,将复杂样式的 Excel 文件另存为 .xml 视图模板,如下图所示:

打开 xml 模板文件,可以清晰的看到里面定义了各种节点,节点描述了整个 Excel 的样式结构, 如下图所示:

3.3 填充占位符

再回过头来看下之前那个复杂 Excel 文件, 观察一下哪些单元格的值需要动态设置:

图中用红色特意标注出来了。

在刚刚另存为的 xml 模板文件中填写 freemark 表达式,考虑到这里只是个示例 Demo, 仅仅选取几个示例单元格来填写占位符,如下所示:

订单标题:

其他需要动态填充的单元格:

PS: xml 文件中, <Row> 节点代表一行, <Cell>代表一个单元格。

在需要动态填充数据的地方,加上相关 freemark 表达式,如 ${commodity.name!},如下所示:

  1. <Row ss:AutoFitHeight="0" ss:Height="54">

  2. <Cell ss:StyleID="s18"><Data ss:Type="String">1</Data></Cell>

  3. <Cell ss:StyleID="s18"><Data ss:Type="String">${commodity.name!}</Data></Cell>

  4. <Cell ss:StyleID="s18"/>

  5. <Cell ss:StyleID="s18"><Data ss:Type="String">${commodity.num!}</Data></Cell>

  6. <Cell ss:StyleID="s18"><Data ss:Type="String">${commodity.num1!}</Data></Cell>

  7. <Cell ss:StyleID="s18"><Data ss:Type="String">22</Data></Cell>

  8. <Cell ss:StyleID="s18"><Data ss:Type="String">44</Data></Cell>

  9. <Cell ss:StyleID="s18"><Data ss:Type="String">55</Data></Cell>

  10. <Cell ss:StyleID="s18"><Data ss:Type="String">盒</Data></Cell>

  11. <Cell ss:StyleID="s18"><Data ss:Type="String">${commodity.price!}</Data></Cell>

  12. <Cell ss:StyleID="s18"><Data ss:Type="String">${commodity.price2!}</Data></Cell>

  13. <Cell ss:StyleID="s18"><Data ss:Type="String">${commodity.price3!}</Data></Cell>

  14. <Cell ss:StyleID="s18"><Data ss:Type="String">${commodity.timestamp}</Data></Cell>

  15. <Cell ss:StyleID="s18"><Data ss:Type="String">${commodity.createTime?string('yyyy-MM-dd HH:mm:ss')}</Data></Cell>

  16. <Cell ss:StyleID="s18"/>

  17. </Row>

按照服务端数据模型的定义,填写好相应的字段名称,再对照下后台 Commodity 商品类的定义:

这个商品类中,我们定义了不同类型的字段,如 String、int、Integer、Double、Float、金额类型 BigDecimal、日期类型 Date 等,用以测试对不同数据类型的兼容性。

确认相关属性字段名无误后,再来看下 freemark 生成 Excel 的核心代码:

可以看到生成复杂样式的 Excel 的代码非常简洁。关于每一行代码什么意思,注释已经说得很清楚了,这里就不加以说明了。

运行单元测试,看下效果:

完美,在需要填充内容的地方都已经动态设置上了内容。

四、多行数据如何生成?

如何做到动态生成多行呢?其实也很简单,重新打开刚刚修改的 xml 模板文件,在需要动态生成多行的地方,添加 freemark 循环表达式即可:

PS: 关于 Freemark 更多表达式的使用,小伙伴们可以自行在各大搜索引擎中搜索,因为如何使用 Freemark 不是本文关注的重点~

上图中,我们对后台的 commodities 字段做了循环,所以对应的,后台代码也需要做相关修改:

我们在 commodities 中添加了两个商品对象。赶快代码跑起来,看看效果!

别急,还有个地方需要做下修改,不然会报错!!

找到 <Table> 节点,有个属性叫 ExpandedRowCount, 它定义了表格行的总数,如果数值与实际的行数对应不上的话,会出问题。

这里我们添加 Freemark 表达式,总行数为商品 commodites 集合的大小加上 16, 注意:16 为除了动态生成的行数外,固定不变的行数大小,小伙伴们如果使用的是不同的 xml 模板,需要自行确认好这个数值的大小。

修改完了以后,再次运行单元测试,效果如下:

OK! 大功告成!

五、局限性

通过视图解析器来生成 Excel 的确很优雅(偷懒),同时兼具灵活性。但是它同样存在一些局限性!小伙伴们在技术选型时,需要结合实际的业务场景审视它是否适合。

  • 版本问题;

目前个人测试结果是,在 MAC 系统上仅支持生成 03 版本 Excel, 07 版本存在打不开的情况;

  • 无法写入大批量数据;

视图引擎生成文件无法往 Excel 里面追加数据,所以仅仅适用于数据量不大的个性化 Excel 生成,否则写入大批量数据时,存在内存溢出(OOM)的情况发生;

  • MAC 系统存在生成的 Excel 文件无法编辑保存的情况:

小哈在测试中发现,生成 excel 在 MAC 系统上存在编辑后,无法保存的情况;而 Windows 系统 Microsoft Excel 和 WPS 均能够正常编辑保存;

---------- END ----------

推荐阅读

为什么阿里代码规约要求避免使用 Apache BeanUtils 进行属性复制

Spring Boot MyBatis 动态数据源切换、多数据源,读写分离

如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版

java8实战读书笔记:初识Stream、流的基本操作(流计算)

如何优雅地生成那些花里胡哨的复杂样式 Excel 文件?相关推荐

  1. electron中使用adm-zip将多个excel文件压缩进文件夹,使用XLSX以及XLSXStyle生成带样式excel文件

    需求:electron环境下想要实现根据多个表生成多个Excel文件,打包存入文件夹内并压缩下载到本地.(实际场景描述:界面中有软件工程一班学生信息.软件工程二班学生信息.软件工程三班学生信息,上方有 ...

  2. SpringBoot项目生成二维码,再生成Excel文件导出,亲测采坑

    1.项目环境 maven依赖 pom文件 <!--easypoi--><dependency><groupId>cn.afterturn</groupId&g ...

  3. node-xlsx 生成并下载有超链接的excel文件

    需求:将微信小程序云数据库中的数据导出为excel文件,文件按团队分为不同的sheet页,首页汇总每个sheet页的数据总数,并可点击跳转至对应的sheet页.下载时可选择今年某月份进行下载对应的数据 ...

  4. Java基础系列19:使用JXL或者POI生成和解析Excel文件

    一 简介 如题所示,当我们需要在Java中解析Excel文件时,可以考虑使用JXL或POI的API来解析. 二者的区别如下: jxl现在基本上没被维护了,最近一次更新时间还是几年前.相反,poi属于A ...

  5. JAVA自动生成雪碧图sprites和样式CSS文件(包含原始图标CSS、雪碧图CSS)

    在项目的开发过程中,如果一个页面有很多的小图标展现.浏览器展示页面时会向后台服务器发送很多的请求获取对应的图片,这样既浪费资源,也使得页面的加载变得很慢,影响客户的体验.此时我们可以采用将这些小图标放 ...

  6. 惊了!7 行代码优雅地实现 Excel 文件生成下载功能

    欢迎关注个人微信公众号: 小哈学Java 个人网站: www.exception.site/essay/how-t- 目录 一.前言 二.Apache poi.jxl 的缺陷 三.阿里出品的 Easy ...

  7. @excel注解_惊了!如何通过阿里 EasyExcel 7 行代码, 优雅地实现 Excel 文件导出功能?...

    目录 一.前言 二.Apache poi.jxl 的缺陷 三.阿里出品的 EasyExcel,安利一波 四.EasyExcel 解决了什么 五.快速上手 六.特殊场景支持 七.Web 下载示例代码 八 ...

  8. 7 行代码优雅地实现 Excel 文件导出功能?

    文章目录 一.前言 二.Apache poi.jxl 的缺陷 三.阿里出品的 EasyExcel,安利一波 四.EasyExcel 解决了什么 五.快速上手 5.1 添加依赖 5.2 七行代码搞定 E ...

  9. Excel 文件的生成与下载

    一.Apache 开源框架 poi.jxl 的缺陷 两者都存在生成 excel 文件不够简单优雅快速的问题.而且它们都还存在一个严重的问题,那就是非常耗内存,严重时会导致内存溢出.POI 虽然目前来说 ...

最新文章

  1. mpls 保留标签值_MPLS 标签模式/分发行为/保留模式/标签空间
  2. BI商业智能项目中的若干风险要素
  3. 机械制造技术学习笔记(七)
  4. 5分钟了解Mockito
  5. sh 脚本执行sql文件传参数
  6. h5的formData 上传文件及.net后台
  7. 使用BootStrap框架设置全局CSS样式
  8. 会写高考作文的AI,内含17亿参数、2亿数据、1万行代码
  9. 疑似华为P30系列售价曝光:欧洲售价最高8400元
  10. 【转】s3c2440 按键驱动 — 字符设备
  11. vue封装了个日历组件(包含农历,节日)
  12. DITHER抖动算法
  13. [论文笔记]Arbitrary-Oriented Scene Text Detection via Rotation Proposals
  14. 流利阅读 2019.1.24 China’s about to rediscover Peppa Pig
  15. 《阿里巴巴java规范》 Result 方式杂谈
  16. 图形图像-无中生有Photoshop CS6背景素材技法ps教程 [超多案例]-韦语洋(Lccee)-专题视频课程...
  17. 【魔方教程】三阶多阶异形魔方教程大合集
  18. 上海首批双学士学位项目来了,复合型人才如何培养?
  19. 一篇没有技术点的文章
  20. 数据库备份和还原bak文件

热门文章

  1. 金橙子这段代码是什么意思
  2. API Manager PHP 接口管理工具
  3. 赔 1.79 亿美元!谷歌前工程师违反竞业协议
  4. 泰山OFFICE技术讲座:重新研究了中英文间隔,提出了柳氏中英文间隔计算公式
  5. 文件快速拷贝工具FastCopy
  6. Echarts-实现结直肠癌知识图谱可视化
  7. 【转】webpack是什么?有什么用?怎么用?
  8. 【博客系统】前端页面
  9. 蓝桥杯 - 核桃的数量(最小公倍数)
  10. 基于SSM框架的项目:图书管理系统