EasyExcel读写Excel
转载,侵删
原文链接:https://mp.weixin.qq.com/s/T_xBuoYgj1NuM7_yHe084Q
最近读者小 H 在知识星球中给阿粉发来私信:
阿粉,最近我在负责公司报表平台开发,需要导出报表到 Excel 中。每次使用 POI 开发,都要写长长的一坨代码,好几次因为没加入判空判断,导致生成失败。想跟你请教下有没有更加高效一点读写 Excel 方法?
ps:知识星球汇集一片大神,感兴趣的同学可以加入知识星球,有任何问题都会有大神及时解答。
使用过 poi 的开发同学可能都有此体会,每次都要写一坨代码,最后的代码如下面一样:
这样的代码是不是又臭又长?当字段数量多的时候,一不小心还容易写错。阿粉还记得当初使用 poi 导出一个二十多字段的 excel,不断复制粘贴,行号一不小心就写错了,那叫个一个心酸。
今天阿粉就来推荐一个阿里开源的项目『EasyExcel』,带大家彻底告别上面又长又臭的代码,彻底解决这个问题。
EasyExcel
EasyExcel 是一个阿里出品的开源项目 ,看名字就能看出这个项目是为了让你更加简单的操作 Excel。另外 EasyExcel 还解决了poi 内存溢出问题,修复了一些并发情况下一些 bug。
github 地址:https://github.com/alibaba/easyexcel
截止阿粉写文章时,已有 13.6k star 数据,可见这个项目还是深受大家欢迎。
废话不多说,我们直接进入源码实战环节。
首先我们需要引入 EasyExcel pom 依赖:
<dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.6</version>
</dependency>
这里建议大家使用 2.0 以上的正式版本,不要再使用 1.0 的老版本,两者使用 API 差别很大。另外 beta 版本可能会存在某些 bug,大家谨慎使用。
普通方式
一行代码生成 Excel
// 写法1
String fileName = "temp/" + "test" + System.currentTimeMillis() + ".xlsx";
EasyExcel.write(fileName).head(head())// 设置表头.sheet("模板")// 设置 sheet 的名字// 自适应列宽.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).doWrite(dataList());// 写入数据
生成 excel 代码特别简单,这里使用链式语句,一行代码直接搞定生成代码。代码中再也不用我们指定行号,列号了。
上面代码中使用自适应列宽的策略。
下面我们来看下表头与标题如何生成。
创建表头
/*** 创建表头,可以创建复杂的表头** @return*/
private static List<List<String>> head() {List<List<String>> list = new ArrayList<List<String>>();// 第一列表头List<String> head0 = new ArrayList<String>();head0.add("第一列");head0.add("第一列第二行");// 第二列表头List<String> head1 = new ArrayList<String>();head1.add("第一列");head1.add("第二列第二行");// 第三列List<String> head2 = new ArrayList<String>();head2.add("第一列");head2.add("第三列第二行");list.add(head0);list.add(head1);list.add(head2);return list;
}
上面每个 List 代表一列的数据,集合内每个数据将会顺序写入这列每一行。如果每一列的相同行数的内容相同,将会自动合并单元格。通过这个规则,我们创建复杂的表头。
最终创建表头如下:
写入表体数据
private static List dataList() {List<List<Object>> list = new ArrayList<List<Object>>();for (int i = 0; i < 10; i++) {List<Object> data = new ArrayList<Object>();data.add("点赞+" + i);// date 将会安装 yyyy-MM-dd HH:mm:ss 格式化data.add(new Date());data.add(0.56);list.add(data);}return list;
}
表体数据然后也是使用 List<List>,但是与表头规则不一样。
每个 List 代表一行的数据,数据将会按照顺序写入每一列中。
集合中数据 EasyExcel 将会按照默认的格式化转换输出,比如 date 类型数据就将会按照 yyyy-MM-dd HH:mm:ss 格式化。
如果需要转化成其他格式,建议直接将数据格式化成字符串加入 List,不要通过 EasyExcel 转换。
最终效果如下:
看完这个是不是想立刻体验一下?等等,上面使用方式还是有点繁琐,使用 EasyExcel 还可以更快。我们可以使用注解方式,无需手动设置表头与表体。
注解方式
注解方式生成 Excel 代码如下:
String fileName = "temp/annotateWrite" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcel.write(fileName, DemoData.class).sheet("注解方式").registerWriteHandler(createTableStyle())// Excel 表格样式.doWrite(data());
这里代码与上面大体一致,只不过这里需要在 write 方法传入 DemoData 数据类型。EasyExcel 会根据 DemoData 类型自动生成表头。
下面我们来看下 DemoData这个类到底内部到底是啥样?
@ContentRowHeight(30)// 表体行高
@HeadRowHeight(20)// 表头行高
@ColumnWidth(35)// 列宽
@Data
public class DemoData {/*** 单独设置该列宽度*/@ColumnWidth(50)@ExcelProperty("字符串标题")private String string;/*** 年月日时分秒格式*/@DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")@ExcelProperty(value = "日期标题")private Date date;/*** 格式化百分比*/@NumberFormat("#.##%")@ExcelProperty("数字标题")private Double doubleData;@ExcelProperty(value = "枚举类",converter = DemoEnumConvert.class)private DemoEnum demoEnum;/*** 忽略这个字段*/@ExcelIgnoreprivate String ignore;
}
DemoData 就是一个普通的 POJO 类,上面使用 ExayExcel 相关注解,ExayExcel 将会通过反射读取字段类型以及相关注解,然后直接生成 Excel 。
ExayExcel 提供相关注解类,直接定义 Excel 的数据模型:
- @ExcelProperty 指定当前字段对应excel中的那一列,内部 value 属性指定表头列的名称
- @ExcelIgnore 默认所有字段都会和excel去匹配,加了这个注解会忽略该字段
- @ContentRowHeight 指定表体行高
- @HeadRowHeight 指定表头行高
- @ColumnWidth 指定列的宽度
另外 ExayExcel 还提供几个注解,自定义日期以及数字的格式化转化。
- @DateTimeFormat
- @NumberFormat
另外我们可以自定义格式化转换方案,需要实现 Converter 类相关方法即可。
public class DemoEnumConvert implements Converter<DemoEnum> {@Overridepublic Class supportJavaTypeKey() {return DemoEnum.class;}@Overridepublic CellDataTypeEnum supportExcelTypeKey() {return CellDataTypeEnum.STRING;}/*** excel 转化为 java 类型,excel 读时将会被调用* @param cellData* @param contentProperty* @param globalConfiguration* @return* @throws Exception*/@Overridepublic DemoEnum convertToJavaData(CellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {return null;}/*** java 类型转 excel 类型,excel 写时将会被调用* @param value* @param contentProperty* @param globalConfiguration* @return* @throws Exception*/@Overridepublic CellData convertToExcelData(DemoEnum value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception {return new CellData(value.getDesc());}
}
最后我们还需要在 @ExcelProperty 注解上使用 converter 指定自定义格式转换方案。
使用方式如下:
@ExcelProperty(value = "枚举类",converter = DemoEnumConvert.class)
private DemoEnum demoEnum;
最后我们运行一下,看下 Excel 实际效果如何:
怎么样,效果还是可以吧。
对了,默认的样式表格样式可不是这样,这个效果是因为我们在 registerWriteHandler 方法中设置自定义的样式,具体代码如下:
/**** 设置 excel 的样式* @return*/
private static WriteHandler createTableStyle() {// 头的策略WriteCellStyle headWriteCellStyle = new WriteCellStyle();// 背景设置为红色headWriteCellStyle.setFillForegroundColor(IndexedColors.PINK.getIndex());// 设置字体WriteFont headWriteFont = new WriteFont();headWriteFont.setFontHeightInPoints((short) 20);headWriteCellStyle.setWriteFont(headWriteFont);// 内容的策略WriteCellStyle contentWriteCellStyle = new WriteCellStyle();// 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);// 背景绿色contentWriteCellStyle.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.getIndex());WriteFont contentWriteFont = new WriteFont();// 字体大小contentWriteFont.setFontHeightInPoints((short) 20);contentWriteCellStyle.setWriteFont(contentWriteFont);// 设置边框的样式contentWriteCellStyle.setBorderBottom(BorderStyle.DASHED);contentWriteCellStyle.setBorderLeft(BorderStyle.DASHED);contentWriteCellStyle.setBorderRight(BorderStyle.DASHED);contentWriteCellStyle.setBorderTop(BorderStyle.DASHED);// 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现HorizontalCellStyleStrategy horizontalCellStyleStrategy =new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);return horizontalCellStyleStrategy;
}
使用注意点
poi 冲突问题
理论上当前 easyexcel兼容支持 poi 的3.17,4.0.1,4.1.0所有较新版本,但是如果项目之前使用较老版本的 poi,由于 poi 内部代码调整,某些类已被删除,这样直接运行时很大可能会抛出以下异常:
NoSuchMethodException
ClassNotFoundException
NoClassDefFoundError
所以使用过程中一定要注意统一项目中的 poi 的版本。
非注解方式自定义行高列宽
非注解方式自定义行高以及列宽比较麻烦,暂时没有找到直接设置的入口。查了一遍 github 相关 issue,开发人员回复需要实现 WriteHandler 接口,自定义表格样式。
总结
本文主要给各位小伙伴们安利 EasyExcel 强大的功能,介绍 EasyExcel 两种生成 excel 方式,以及演示相关的示例代码。EasyExcel 除了写之外,当然还支持快读读取 Excel 的功能,这里就不再详细介绍。Github 上相关文档例子非常丰富,大家可以自行参考。
Github 文档地址:https://alibaba-easyexcel.github.io/index.html
EasyExcel读写Excel相关推荐
- Alibaba开源工具EasyExcel读写Excel文件
前言 工作中使用 excel 表格处理数据是很常见的操作,经常会使用 excel 文件来导入数据或者导出数据,是不是脑海中已经思考有哪些处理excel框架? 小编之前呢就知道Java 解析.生成 Ex ...
- 使用easyexcel读写Excel
title: "使用easyexcel读写Excel" url: "https://wsk1103.github.io/" tags: Java 学习笔记 JA ...
- 阿里EasyExcel读写excel文件的基本使用
EasyExcel读写excel文件 1.EasyExcel简介 2.对excel的写操作 1.1 创建一个普通的maven项目并引入相关依赖 1.2 创建实体类 1.3 实现写操作 1.3.1 创建 ...
- 使用EasyExcel读写Excel文件
笔者之前一直使用POI读写Excel文件,最近有个需求需要读取大概80万行数据的Excel,使用POI读取到10.2万行左右就卡死不动了,而且CPU占用直接拉满到100%,内存占用也很高. 查找资料后 ...
- 阿里云EasyExcel读写excel表数据
阿里云EasyExcel读取excel表数据 1.待读取的excel表test.xls 2.导入Maven依赖 <dependency><groupId>com.alibaba ...
- EasyExcel读写Excel的基本使用
Excel导入导出的应用场景 1.数据导入:减轻录入工作量 2.数据导出:统计信息归档 3.数据传输:异构系统之间数据传输 EasyExcel简介 EasyExcel特点 Java领域解析.生成Exc ...
- 【精品】使用阿里的EasyExcel读写Excel文档
EasyExcel简介 EasyExcel官网 Apache POI 技术在Excel 的数据量非常大的时候,会将整个 Excel 的内容全部读出来放入到内存中,所以内存消耗非常严重,如果同时进行包含 ...
- 使用阿里 EasyExcel 读写 Excel 文件
首先 pom.xml 引入依赖,EasyExcel 版本更新快,不同版本 API 均有不同,有些已经废弃. <dependency><groupId>com.alibaba&l ...
- easyexcel读取表头_easyExcel 读写excel表格
easyExcel 读写excel表格 EasyExcel是一个基于Java的简单.省内存的读写Excel的开源项目.在尽可能节约内存的情况下支持读写百M的Excel. Java解析.生成Excel比 ...
最新文章
- 第五课-第三讲05_03_bash脚本编程之二 条件判断
- c++ 学习笔记 c++ 引用C库注意点:#ifdef __cplusplus 倒底是什么意思?
- canvas用2d渲染出3d的感觉
- Tomcat源码学习(7)-How Tomcat works(转)
- esp8266 php 接口,ESP8266_SDK基础(5)智能插座_完整项目代码
- JUnit5 TestSuite替代
- 擦窗机器人测试标准_擦窗机器人,我选择玻妞的三个理由!
- 我扒了 6730 个微信用户数据,得出了这些结论......
- PYTHON——TCPUDP:socketserver实现多人聊天
- android 壁纸服务,8.1 初识Android壁纸
- Matlab画图程序
- 【基础知识】【模块介绍】0.96寸OLED显示屏(SSD1306)基础命令和寻址方法
- php文章重复度检测,有哪些可以检测文章原创度的工具,避免文章重复度过高
- vs2013 update5离线升级包下载地址
- 瑞萨 boot相关指令 理解
- [week15] C - ZJM与纸条(选做)—— KMP算法
- 在基于ZYNQ MPSOC XCZU3CG自定义单板上运行DPU例程
- Python_OpenCV_实现模糊集合用于图像增强(对比度提升,空间滤波)
- EulerOS 2.0 SP5 - 华为欧拉(CentOS 7 华为版)下载
- 简单版四人扑克牌(python)