1.概述
easyexcel是阿里开源的,用于解析、生成Excel的框架。
2.写excel
public <T> void writeExcel(String fileName, List<T> data, String sheetName) {
if (null == data || data.isEmpty()) {
return;
}
try {
String path = "testWrite.xlsx";
EasyExcel.write(path, data.get(0).getClass()) // 设置路径和传入的数据类型
.sheet(sheetName) // 设置sheet名称
.doWrite(data);
} catch (Exception e) {
log.info(e.getMessage());
}
}
3.读excel
注意:
easyexcel在进行读操作时需利用监听器设置读取规则。默认从第1行开始读,可用headRowNumber()
方法设置开始读取的行数。
实例:
下面展示在不确定excel格式时,逐行将excel读成Map<Integer, String>
的方式;如果知道excel的格式,可以创建一个实体类,来保存每一行数据。
public class Main {
public static void main(String[] args) {
// 1.设置excel路径
String path = "C:\\Users\\11462\\Desktop\\测试excel\\testRead.xlsx";
// 2.个性化定制监听器
ExcelReadListener excelReadListener = new ExcelReadListener();
// 3.读取excel
EasyExcel.read(path, excelReadListener)
.headRowNumber(0) // 设置从excel第0行开始读,默认是从第1行开始读
.sheet() // 默认读取第一个sheet,也可以添加参数设置要读取的sheet
.doRead();
}
}
// 监听器实现
class ExcelReadListener extends AnalysisEventListener<Map<Integer, String>> {
private final List<Map<Integer, String>> cachedList = new ArrayList<>();
/**
* 每解析到excel中的一行数据,就会调用invoke()方法
* 由于是流式读取,故需要实现该方法来保存读到的有用数据
*/
@Override
public void invoke(final Map<Integer, String> data, final AnalysisContext context) {
// 将读取到的excel行数据添加到缓存
cachedList.add(data);
}
/**
* 所有数据解析完成之后会调用该方法
*/
@Override
public void doAfterAllAnalysed(final AnalysisContext analysisContext) {
// 对缓存中的数据进行处理,逐行逐列打印excel中的数据
for (int row=1; row < cachedList.size()-1; row++) { // 默认是从excel中的第一行读取数据
Map<Integer, String> map = cachedList.get(row);
if (null != map) {
for (Entry<Integer, String> entry: map.entrySet()) {
if (null != entry.getValue()) {
int column = entry.getKey();
System.out.println("第"+row+"行,"+"第"+column+"列数据:"+entry.getValue());
}
}
}
}
}
}
4.监听器 ReadListener和AnalysisEventListener
ReadListener
是easyexcel中的监听器接口。在进行读操作时,需要实现该接口,接口中的方法如下。
public interface ReadListener<T> extends Listener {
/**
* 读取异常下会调用本接口
* 抛出异常则停止读取;如果这里不抛出异常则继续读取下一行
*/
void onException(Exception var1, AnalysisContext var2) throws Exception;
/**
* 该方法可以一行行获取表头
*/
void invokeHead(Map<Integer, CellData> var1, AnalysisContext var2);
/**
* 每解析到excel中的一行数据,就会调用invoke()方法
* 由于是流式读取,故需要实现该方法来保存读到的有用数据
*/
void invoke(T var1, AnalysisContext var2);
/**
* 读取额外信息(批注、超链接、合并单元格信息读取)
* 由于是流式读取,没法在读取到单元格数据的时候直接读取到额外信息,所以只能最后通知哪些单元格有哪些额外信息
*/
void extra(CellExtra var1, AnalysisContext var2);
/**
* 所有数据解析完成之后会调用该方法
*/
void doAfterAllAnalysed(AnalysisContext var1);
boolean hasNext(AnalysisContext var1);
}
AnalysisEventListener已经实现了ReadListener接口中的部分方法。从源码可知,在读操作时也可以继承该类,则只需要实现ReadListener中的invoke()和doAfterAllAnalysed()
public abstract class AnalysisEventListener<T> implements ReadListener<T> {
public AnalysisEventListener() {
}
public void invokeHead(Map<Integer, CellData> headMap, AnalysisContext context) {
this.invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context);
}
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
}
public void extra(CellExtra extra, AnalysisContext context) {
}
public void onException(Exception exception, AnalysisContext context) throws Exception {
throw exception;
}
public boolean hasNext(AnalysisContext context) {
return true;
}
}
5.ExcelReaderSheetBuilder 和 ExcelWriterBuilder
ExcelReaderSheetBuilder:读excel时的操作类。
ExcelWriterBuilder:写excel时的操作类。
6.性能对比
Apache POI和阿里巴巴的Easyexcel都是比较主流的excel操作框架。easyexcel使用更便捷和节省内存。
easyexcel和poi对比