自己动手实现一个Excel导出公共组件!!!!文章主要分为以下几个部分来说明:
1、明确目标
2、技术预研
3、技术方案选型与方案设计
4、技术实施
下面是实现一个Excel导出模块的目标:
-
通过自定义注解解析需要导出的Excel格式
-
支持自定义日期显示格式
-
支持是否显示自增列
-
支持约定的属性的枚举转换(比如YWG->已完工)
-
少量数据直接导出(5000条内)
-
对于大数据量支持分页导出(支持全量数据导出,百万级)
-
超大规模数据导出(千万级的数据量)
目标明确后就可以开始进行进行技术预研,对比了当前比较流行的三种开源Excel导出技术的特点:
-
JXL
-
效率低,操作简单
-
能够修饰单元格属性,格式支持不如POI强大
-
-
FastExcel
-
采用纯java开发的excel文件读写组件,支持Excel 97-2003文件格式
-
内存消耗小
-
只读取字符信息,诸如颜色/字体等属性都不支持
-
-
POI
-
效率高,操作相对复杂
-
支持公式,宏,图像,图表
-
支持修饰单元格属性;支持字体,数字,日期操作
-
3.8版本的POI出来了SXSSFWorkbook,可以支持大数据量的操作,但只支持xlsx格式
-
Excel导出方式的调研:
-
直接导出.xls(单表支持65532行)或者.xlsx(单表支持1048576行)后缀的excel文件
-
导出.txt文件
-
导出.csv文件
-
导出.xml文件
技术选型:
综合之前的开源技术分析以及导出方式分析,结合自己的业务场景,直接导出Excel是比较好的选择(用户可以直接打开)。开源技术中,JXL可以直接排除,因为效率低;FastExcel其实还不错,内存消耗又小,但是不支持复杂的操作,扩展性不佳;而POI不仅效率高,且支持各种操作(便于未来未知的扩展需求,比如需要导出表格、图像呢?),同时也支持大数据量的操作,非常合适。Excel2007已经普及了,不存在打开的障碍。
技术方案设计:
-
采用POI作为操作Excel的第三方库
-
自定义注解,有列号,列名,日期格式化,枚举类型,自增序列
-
注解解析,解析Excel导出的列和对应的字段
-
数据解析,根据注解解析结果去解析每一行数据
-
导出
-
若数据量少(<5000条),直接全量导出
-
若数据量大(范围[5000,1048576)),需要分批解析数据然后导出
-
若数据量超大,超过了Excel2007的表行数限制(1048576),采用导出多份Excel或者多张sheet的方式
-
定义一个自定义注解,主要包含以下几个属性(序列号,列名,日期格式,枚举名称,是否自增)
package com.shulin.winter.annotions;
import java.lang.annotation.*;
/**
* Excel导出注解
* Created by shulin on 16/12/25.
*/
@Target({ ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExlOut {
/**
* 列序号,比如第1列是姓名,第2列是电话号码,第3列是地址
*
* @return
*/
int colSeq();
/**
* 列名
*
* @return
*/
String colName();
/**
* 日期类型格式化
*
* @return
*/
String dateFormat() default "yyyy-MM-dd HH:mm:SS";
/**
* 枚举的名称
*
* @return
*/
String enumName() default "";
/**
* 是否有自增序列
*
* @return
*/
boolean autoIncrement() default false;
}
有了这个注解,接下来就是定义注解的解析工作,我们需要将一个使用了这个注解的类的注解表示的相关导出信息解析出来,比如需要导出哪几列,谁前谁后,列名是什么,是否有自增序列,是否需要进行枚举转化等。
在此之前我们先定义一个解析结果类来保存注解解析后的结果:
package com.shulin.winter.annotions;
import lombok.Getter;
import lombok.Setter;
/**
* 解析注解后的对象