|
|
|
package com.alibaba.easyexcel.test.demo.read;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
|
import org.junit.Ignore;
|
|
|
|
import org.junit.Test;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
import com.alibaba.easyexcel.test.util.TestFileUtil;
|
|
|
|
import com.alibaba.excel.EasyExcel;
|
|
|
|
import com.alibaba.excel.ExcelReader;
|
|
|
|
import com.alibaba.excel.annotation.ExcelProperty;
|
|
|
|
import com.alibaba.excel.annotation.format.DateTimeFormat;
|
|
|
|
import com.alibaba.excel.annotation.format.NumberFormat;
|
|
|
|
import com.alibaba.excel.converters.DefaultConverterLoader;
|
|
|
|
import com.alibaba.excel.read.metadata.ReadSheet;
|
|
|
|
import com.alibaba.fastjson.JSON;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 读的常见写法
|
|
|
|
*
|
|
|
|
* @author Jiaju Zhuang
|
|
|
|
*/
|
|
|
|
@Ignore
|
|
|
|
public class ReadTest {
|
|
|
|
private static final Logger LOGGER = LoggerFactory.getLogger(ReadTest.class);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 最简单的读
|
|
|
|
* <p>
|
|
|
|
* 1. 创建excel对应的实体对象 参照{@link DemoData}
|
|
|
|
* <p>
|
|
|
|
* 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
|
|
|
|
* <p>
|
|
|
|
* 3. 直接读即可
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void simpleRead() {
|
|
|
|
// 写法1:
|
|
|
|
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
|
|
|
|
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 文件流会自动关闭
|
|
|
|
EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet().doRead();
|
|
|
|
|
|
|
|
// 写法2:
|
|
|
|
fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
|
|
|
|
ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build();
|
|
|
|
ReadSheet readSheet = EasyExcel.readSheet(0).build();
|
|
|
|
excelReader.read(readSheet);
|
|
|
|
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
|
|
|
|
excelReader.finish();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 指定列的下标或者列名
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* 1. 创建excel对应的实体对象,并使用{@link ExcelProperty}注解. 参照{@link IndexOrNameData}
|
|
|
|
* <p>
|
|
|
|
* 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link IndexOrNameDataListener}
|
|
|
|
* <p>
|
|
|
|
* 3. 直接读即可
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void indexOrNameRead() {
|
|
|
|
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
|
|
|
|
// 这里默认读取第一个sheet
|
|
|
|
EasyExcel.read(fileName, IndexOrNameData.class, new IndexOrNameDataListener()).sheet().doRead();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 读多个sheet,这里注意一个sheet不能读取多次,多次读取需要重新读取文件
|
|
|
|
* <p>
|
|
|
|
* 1. 创建excel对应的实体对象 参照{@link DemoData}
|
|
|
|
* <p>
|
|
|
|
* 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
|
|
|
|
* <p>
|
|
|
|
* 3. 直接读即可
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void repeatedRead() {
|
|
|
|
// 方法1 如果 sheet1 sheet2 都是同一数据 监听器和头 都写到最外层
|
|
|
|
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
|
|
|
|
ExcelReader excelReader = EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).build();
|
|
|
|
ReadSheet readSheet1 = EasyExcel.readSheet(0).build();
|
|
|
|
ReadSheet readSheet2 = EasyExcel.readSheet(1).build();
|
|
|
|
excelReader.read(readSheet1);
|
|
|
|
excelReader.read(readSheet2);
|
|
|
|
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
|
|
|
|
excelReader.finish();
|
|
|
|
|
|
|
|
// 方法2 如果 sheet1 sheet2 数据不一致的话
|
|
|
|
fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
|
|
|
|
excelReader = EasyExcel.read(fileName).build();
|
|
|
|
// 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener
|
|
|
|
readSheet1 = EasyExcel.readSheet(0).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
|
|
|
|
readSheet2 = EasyExcel.readSheet(1).head(DemoData.class).registerReadListener(new DemoDataListener()).build();
|
|
|
|
excelReader.read(readSheet1);
|
|
|
|
excelReader.read(readSheet2);
|
|
|
|
// 这里千万别忘记关闭,读的时候会创建临时文件,到时磁盘会崩的
|
|
|
|
excelReader.finish();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 日期、数字或者自定义格式转换
|
|
|
|
* <p>
|
|
|
|
* 默认读的转换器{@link DefaultConverterLoader#loadDefaultReadConverter()}
|
|
|
|
* <p>
|
|
|
|
* 1. 创建excel对应的实体对象 参照{@link ConverterData}.里面可以使用注解{@link DateTimeFormat}、{@link NumberFormat}或者自定义注解
|
|
|
|
* <p>
|
|
|
|
* 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link ConverterDataListener}
|
|
|
|
* <p>
|
|
|
|
* 3. 直接读即可
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void converterRead() {
|
|
|
|
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
|
|
|
|
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 然后千万别忘记 finish
|
|
|
|
EasyExcel.read(fileName, ConverterData.class, new ConverterDataListener())
|
|
|
|
// 这里注意 我们也可以registerConverter来指定自定义转换器, 但是这个转换变成全局了, 所有java为string,excel为string的都会用这个转换器。
|
|
|
|
// 如果就想单个字段使用请使用@ExcelProperty 指定converter
|
|
|
|
// .registerConverter(new CustomStringStringConverter())
|
|
|
|
// 读取sheet
|
|
|
|
.sheet().doRead();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 多行头
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* 1. 创建excel对应的实体对象 参照{@link DemoData}
|
|
|
|
* <p>
|
|
|
|
* 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoDataListener}
|
|
|
|
* <p>
|
|
|
|
* 3. 设置headRowNumber参数,然后读。 这里要注意headRowNumber如果不指定, 会根据你传入的class的{@link ExcelProperty#value()}里面的表头的数量来决定行数,
|
|
|
|
* 如果不传入class则默认为1.当然你指定了headRowNumber不管是否传入class都是以你传入的为准。
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void complexHeaderRead() {
|
|
|
|
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
|
|
|
|
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 然后千万别忘记 finish
|
|
|
|
EasyExcel.read(fileName, DemoData.class, new DemoDataListener()).sheet()
|
|
|
|
// 这里可以设置1,因为头就是一行。如果多行头,可以设置其他值。不传入也可以,因为默认会根据DemoData 来解析,他没有指定头,也就是默认1行
|
|
|
|
.headRowNumber(1).doRead();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 读取表头数据
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* 1. 创建excel对应的实体对象 参照{@link DemoData}
|
|
|
|
* <p>
|
|
|
|
* 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoHeadDataListener}
|
|
|
|
* <p>
|
|
|
|
* 3. 直接读即可
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void headerRead() {
|
|
|
|
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
|
|
|
|
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 然后千万别忘记 finish
|
|
|
|
EasyExcel.read(fileName, DemoData.class, new DemoHeadDataListener()).sheet().doRead();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 数据转换等异常处理
|
|
|
|
*
|
|
|
|
* <p>
|
|
|
|
* 1. 创建excel对应的实体对象 参照{@link DemoData}
|
|
|
|
* <p>
|
|
|
|
* 2. 由于默认异步读取excel,所以需要创建excel一行一行的回调监听器,参照{@link DemoHeadDataListener}
|
|
|
|
* <p>
|
|
|
|
* 3. 直接读即可
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void exceptionRead() {
|
|
|
|
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
|
|
|
|
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 然后千万别忘记 finish
|
|
|
|
EasyExcel.read(fileName, DemoData.class, new DemoHeadDataListener()).sheet().doRead();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 同步的返回,不推荐使用,如果数据量大会把数据放到内存里面
|
|
|
|
*/
|
|
|
|
@Test
|
|
|
|
public void synchronousRead() {
|
|
|
|
String fileName = TestFileUtil.getPath() + "demo" + File.separator + "demo.xlsx";
|
|
|
|
// 这里 需要指定读用哪个class去读,然后读取第一个sheet 同步读取会自动finish
|
|
|
|
List<Object> list = EasyExcel.read(fileName).head(DemoData.class).sheet().doReadSync();
|
|
|
|
for (Object obj : list) {
|
|
|
|
DemoData data = (DemoData)obj;
|
|
|
|
LOGGER.info("读取到数据:{}", JSON.toJSONString(data));
|
|
|
|
}
|
|
|
|
|
|
|
|
// 这里 也可以不指定class,返回一个list,然后读取第一个sheet 同步读取会自动finish
|
|
|
|
list = EasyExcel.read(fileName).sheet().doReadSync();
|
|
|
|
for (Object obj : list) {
|
|
|
|
// 返回每条数据的键值对 表示所在的列 和所在列的值
|
|
|
|
Map<Integer, String> data = (Map<Integer, String>)obj;
|
|
|
|
LOGGER.info("读取到数据:{}", JSON.toJSONString(data));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|