导入导出Excel数据在实际开发中很常见,之前一直使用POI,直到这次数据量庞大,POI占用内存的问题展露无遗,就尝试了easyExcel。EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。 提供的方法也足够正常使用,话不多说,直接上代码。
导入依赖
<!-- easyExcel --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>3.1.0</version> </dependency>
配置监听器
@Getter
@Setter
public class ExcelListener<T> extends AnalysisEventListener<T> {
private List<T> data = new ArrayList<>();
@Override
public void invoke(T object, AnalysisContext context) {
data.add(object);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
}
封装读写Excel文件方法
public class ExcelHelper {
public static <T> List<T> readExcel(String file, Class<T> head, String... sheetNames) {
List<T> list = new ArrayList<>();
for (String sheetName : sheetNames) {
list.addAll(readExcel(file, head, sheetName));
}
return list;
}
public static <T> List<T> readExcel(String file, Class<T> head, String sheetName) {
ExcelListener<T> listener = new ExcelListener<>();
EasyExcel.read(file, head, listener).readCache(new MapCache()).sheet(sheetName).doRead();
return listener.getData();
}
public static <T> List<T> readExcel(String file, Class<T> head, int sheet) {
ExcelListener<T> listener = new ExcelListener<>();
EasyExcel.read(file, head, listener).readCache(new MapCache()).sheet(sheet).doRead();
return listener.getData();
}
public static <T> List<T> readExcel(String file, Class<T> head, int sheet, int headRowNumber) {
ExcelListener<T> listener = new ExcelListener<>();
EasyExcel.read(file, head, listener).readCache(new MapCache()).sheet(sheet).headRowNumber(headRowNumber).doRead();
return listener.getData();
}
public static <T> void writeExcel(String file, List<List<String>> head, String sheetName, List<T> list) {
EasyExcel.write(file).sheet(sheetName).head(head).doWrite(list);
}
@SuppressWarnings("rawtypes")
public static <T> void writeExcel(String file, Class head, String sheetName, List<T> list) {
EasyExcel.write(file).sheet(sheetName).head(head).doWrite(list);
}
}
上文中使用的变量名翻译一下基本就是它的意义,head为Excel对应的实体类,headRowNumber为从第几行开始读取信息。有时候Excel会有多级表头,而我们想要的中间的数据,就可以使用headRowNumber设置读取开始行。
实体类注解
easyExcel为我们提供了@ExcelProperty、@ExcelIgnore注解
使用方法如上图所示,@ExcelProperty对应我们Excel表格中列的名称,@ExcelIgnore表示在或写中忽略某一列,可以用来存放我们的主键信息,这两个注解就可以应对大多数情况。官方还提供了一些可以进行类型转换的注解。
/**
* converter属性定义自己的字符串转换器
*/
@ExcelProperty(converter = Converter.class)
private String string;
/**
* 这里用string 接收日期才能格式化
*/
@DateTimeFormat("yyyy年MM月dd日 HH时mm分ss秒")
private String date;
/**
* 转化为百分比的数字
*/
@NumberFormat("#.##%")
private String doubleData;
以上代码,复制后无需另外配置直接可以使用,需要者自取
当遇到读取数据excel与待写入excel不一致时,我们可以忽略某些列的写入,代码如下
参数:
filepath为待写入文件路径,targetClass为待写入的类信息,objectList为待写入数据
Set<String> excludeColumnFiledNames = new HashSet<String>();
if ("控制条件"){
//不写入Excel文件的列,传实体类中属性名
excludeColumnFiledNames.add("others");
}
// 这里 需要指定class去写,文件流会自动关闭
EasyExcel.write(filePath, targetClass).excludeColumnFiledNames(excludeColumnFiledNames).sheet("Sheet1")
.doWrite(objectList);