使用方法
导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>最新版本</version>
</dependency>出现 java.lang.NoSuchMethodError: 'void org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream.putArchiveEntry(org.apache.commons.compress.archivers.zip.ZipArchiveEntry)'
EasyExcel 依赖于比较新的 commons-io 版本,额外引入这个包或者 在 parent 的 dependencyManagement 里面加入
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<!-- 这个版本可以继续往上升 ,但是不要低于这个 -->
<version>2.15.0</version>
</dependency>监听器
/**
* @author fjzheng
* @version 1.0
* @date 2024/4/12 16:22
*/
@Slf4j
public class UserExcelListener extends AnalysisEventListener<User> {
/**
* 每隔100条处理下,然后清理list ,方便内存回收
*/
private static final int BATCH_COUNT = 100;
/**
* 缓存的数据
*/
private List<User> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
/**
*
* @param exception
* @param context
* @throws Exception
*/
@Override
public void onException(Exception exception, AnalysisContext context) throws Exception {
log.error("======>>>解析异常:", exception);
throw exception;
}
/**
* 当读取到一行数据时,会调用这个方法,并将读取到的数据以及上下文信息作为参数传入
* 可以在这个方法中对读取到的数据进行处理和操作,处理数据时要注意异常错误,保证读取数据的稳定性
* @param user
* @param context
*/
@Override
public void invoke(User user, AnalysisContext context) {
log.info("解析到一条数据:{}", user);
cachedDataList.add(user);
if (cachedDataList.size() >= BATCH_COUNT) {
// 处理缓存的数据,比如说入库。。。
// 然后清空
cachedDataList.clear();
}
}
/**
* 当每个sheet所有数据读取完毕后,会调用这个方法,可以在这个方法中进行一些收尾工作,如资源释放、数据汇总等。
* @param context
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
// 收尾工作,处理剩下的缓存数据。。。
log.info("sheet={} 所有数据解析完成!", context.readSheetHolder().getSheetName());
}
}
读
@SpringBootTest
@RunWith(SpringRunner.class)
@Slf4j
public class ExcelTest {
@Test
public void testExcelRead() {
String fileName = "/Users/shepherdmy/Desktop/test1.xlsx";
EasyExcel.read(fileName, User.class, new UserExcelListener()).sheet().doRead();
// 如果excel是多行表头比如说2行,需要设置行头数headRowNumber,默认不设置为1行表头,sheet不传默认读取第一个sheet
// EasyExcel.read(fileName, User.class, new UserExcelListener()).sheet().headRowNumber(2).doRead();
}
}写
数据生成
private List<DemoData> data() {
List<DemoData> list = ListUtils.newArrayList();
for (int i = 0; i < 10; i++) {
DemoData data = new DemoData();
data.setString("字符串" + i);
data.setDate(new Date());
data.setDoubleData(0.56);
list.add(data);
}
return list;
}String fileName = TestFileUtil.getPath() + "simpleWrite" + System.currentTimeMillis() + ".xlsx";
// 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
// 如果这里想使用03 则 传入excelType参数即可
EasyExcel.write(fileName, DemoData.class)
.sheet("模板")
.doWrite(data());常用注解
ExcelProperty
用于匹配excel和实体类的匹配,参数如下:
ExcelIgnore
默认所有字段都会和excel去匹配,加了这个注解会忽略该字段
ExcelIgnoreUnannotated
默认不加ExcelProperty 的注解的都会参与读写,加了不会参与读写
DateTimeFormat
日期转换,用String去接收excel日期格式的数据会调用这个注解,参数如下:
NumberFormat
数字转换,用String去接收excel数字格式的数据会调用这个注解。
踩坑点
导入
commons-io依赖easyexcel不要使用lombok,有冲突
Comments