此文章以独家授权一下公众号 :
【新华前后端开发】
【脚本之家】
[TOC]
【 快速、简单避免OOM的java处理Excel工具 】 github上关于项目的介绍
poi使用userModel模式,这个模式的特点就是上手很容易。代码写起来很复杂。而且公用的地方很少。导致每次读写excel都需要重新编写。
EasyExcel使用SAX模式使得easyexcel可以节省内存。而且easyexcel解决了内存泄漏问题。如果想了解SAX模式开发那成本需要3~5天学习。
导出excel常用的几种方法
通过Java读写excel大概有以下几种:
poi、csv、jxl、jxls 、easyPoi 、easyExcel
根据性能他们的排序:
jxl 、 easyexcel 、 csv 、 poi 、 easypoi 、 jxls
easypoi
easyexcel
- easyexcel是重点对象。他基于注解的方式将以前POI的复杂的代码进模块抽离。我们基本上的需求只需要在excelproperty注解中就可以解决。
- easyexcel最大的特点就是解决了内存泄漏的问题。以上几种poi在导出excel的时候都受到了数据的影响.而且性能上还不是很好。easyexcel是POI系列产品的最佳之选
easyexcel名字非常的符合他的个性。他是真的很easy.下面我们来实现一个导出学生信息的代码
String fileName = EasyExcelTools.class.getResource("/").getPath() + "student" + System.currentTimeMillis() + ".xlsx"; ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(fileName, Student.class); //excelWriterBuilder.registerConverter(new SexConverter()).registerWriteHandler(new AgeRowHandler()).registerWriteHandler(new SexCellWriteHandler()); ExcelWriter excelWriter = excelWriterBuilder.build(); WriteSheet writeSheet = EasyExcel.writerSheet("中化安元").build(); try { excelWriter.write(ts, writeSheet); } catch (Exception e) { e.printStackTrace(); }finally { excelWriter.finish();student
public class Student { * 学生索引id @ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"学号"}) private String id; @ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"姓名"}) private String userName; * 用户昵称 @ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"昵称"}) @ExcelIgnore private String userNick; @ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"年龄"}) private Integer age; * 性别 true : 男 ; false : 女 @ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"性别"}) private boolean sex; @ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"生日"}) private Date birth; @ExcelProperty(value = {HeadConstant.FIRSTNAME,HeadConstant.SECONDNAME,"身高"}) private Double height;- 通过easyexcel导出我们只需要准备好数据,然后两行代码导出。
常用API
单元格样式
-
因为被封装了一层。如果easyexcel满足不了我们的话,我们可以通过workbook去具体操作单元格内容和样式。这种方法是万不得已在使用。就比如我们想改变单元格样式。easyexcel提供了开发接口CellWriteHandler。我们只需要实现这个接口并重写他的
beforeCellCreate
,afterCellCreate
,afterCellDispose
.其中afterCellDispose
方法是在单元格创建后销毁前的一个时机。这时候我们可以改变单元格内容。easyExcel提供了四种时间捕捉接口
CellWriteHandler
WorkbookWriteHandler
SheetWriteHandler
RowWriteHandler
合并单元格
- 在POI中我们实现合并单元格我们需要指定合并的范围。但是在easyexcel中我们只需要在ExcelProperty注解中加入表头的时候在对应位置加入相同的内容就会自动的合并单元格。
- 数据样式使我们Java开发中经常遇到的。比如说学生信息中的性别我们粗在数据库中大部分情况都是通过0、1来控制的。但是我们导出的时候肯定是不能直接展示01的。这个时候我们就需要数据样式了。说的在明白点就是数据格式转换。在easyexcel中提供了Converter接口。
convertToJavaData
: excel数据转换成Java对象
convertToExcelData
: Java对象转换成excel数据
多sheet设置
- 多sheet页实际上就是创建多个sheet。每个sheet有不同的编号。剩下的操作都是一样的。
单元格添加超链接
-
通过CellWriteHandler实现在
afterCellDispose
方法中实现
CreationHelper createHelper = writeSheetHolder.getSheet().getWorkbook().getCreationHelper();
Hyperlink hyperlink = createHelper.createHyperlink(HyperlinkType.URL);
hyperlink.setAddress("https://gitee.com/zxhTom");
cell.setHyperlink(hyperlink);
<dependency>
<groupId>net.sourceforge.javacsv</groupId>
<artifactId>javacsv</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.1.0-beta4</version>
</dependency>
notes
1900 windowing 1900年日期系统
1904 windowing 1904年日期系统
Excel for windows 使用1900
Excel2008 for mac 和之前版本 1904
excel 2016 for mac ; excel for mac 2011 1900
读写数据格式内置转换器
ModelBuildEventListener
- ModelBuildEventListener 默认的也是第一个数据监听器,主要功能就是将读取到的当前行数据转换成实体或者map
write
- FileUtils.createPoiFilesDirectory();
在初始化时创建临时缓存目录以避免POI并发写入错误