简介:

EasyExcel类是一套基于Java的开源Excel解析工具类,可以快速完成Excel格式的导入导出,可以从Java实体类中直接设置表结构信息,方便快捷。

坐标依赖:EasyExcel 依赖

官方文档:地址

特点:

  1. 相较于其他处理工具,比较节省内存,因为它不是一次性的读取所有数据,而是以逐行读取数据的方式去处理Excel文件。

读Excel

实体类:

实体类作用:用于接收Excel表格数据的实体类。

实体类设置:通过在实体类属性上设置@ExcelProperty注解来指定当前属性对应的Excel字段。

@ExcelProperty(value = "字符串标题")   // 使用表头名称进行匹配
@ExcelProperty(index = 2)           // 使用 index 进行匹配

注:两者最好不要一起使用,可能会发生冲突,且当表头的名称重复时,再使用value的方式会导致只有一个字段能读取到数据,可以的话,最好使用 index 去读取数据。

监听器:

监听器作用:用于对读取到的Excel数据进行逐行处理,保留自己所需要的数据

监听器的分类:

  1. ReadListener 接口:一般情况下实现此接口就可以满足工作需要了。
  2. AnalysisEventListener 抽象类,它只是实现了ReadListener 接口中的部分方法,主要是在读取表头数据时可以继承此抽象类,其余差别不大。
@AllArgsConstructor
public class DemoDataListener extends AnalysisEventListener<TextReadObject> {
    /**
     * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收
     */
    private static final int BATCH_COUNT = 100;
		
		// 缓存的数据
		private List<TextReadObject> dataList;
    
		//读取表头的内容
    @Override
    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
        System.out.println("表头->"+headMap);
    }
    
		//一行一行读取excel中的内容,可在里面对行数据进行处理操作
    @Override
    public void invoke(TextReadObject data, AnalysisContext context) {
        dataList.add(data);
				// 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM
        if (dataList.size() >= BATCH_COUNT) {
            saveData();
            // 存储完成清理 list
            dataList= ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
        }
    }
    //读取完成之后执行的方法
    @Override
    public void doAfterAllAnalysed(AnalysisContext context) {
			// 这里也要保存数据,确保最后遗留的数据也存储到数据库
        saveData();
        log.info("所有数据解析完成!");
	}
	
	/**
   * 加上存储数据库
   */
    private void saveData() {
        log.info("{}条数据,开始存储数据库!", dataList.size());
        demoDAO.save(dataList);
        log.info("存储数据库成功!");
    }

}

测试类:

@Test
public void simpleRead() {
String fileName = "F:\\\\rdtext.xls";
    List<TextReadObject> dataList = new ArrayList<>();
    //每次会读取100条数据然后返回过来,直接调用使用数据就行
    EasyExcel.read(fileName, TextReadObject.class, new DemoDataListener(dataList))
            .sheet(0)//读取第一个sheet
            .headRowNumber(3) //跳过前三行表头内容,假如是简单表头则这句可省略
            .doRead();
    //若需要实现读取全部sheet,可以使用.doReadAll()代替.sheet(0).doRead()

}

写Excel

实体类:

实体类作用:用于向Excel表格中填充数据

实体类设置:也是通过在实体类属性上设置@ExcelProperty注解来指定写入的位置和表头名称,但写入时最好同时指定index 和 value ,这样可以指定确切的位置和表头字段名

@ExcelProperty(value = "字符串标题", index = 0)  // 同时指定表头和写入的列
private String string;
@ExcelProperty(value = "日期标题", index = 1)
private Date date;

测试类:

@Test
public void indexWrite() {
	String fileName = "F:\\\\wttext.xls";
	List<TextWriteObject> dataList;

	EasyExcel.write(fileName, TextWriteObject.class) // 指定要写入的实体类类名
                .sheet(0)   // 写入的表名
                .doWrite(dataList);   // 写入的数据
// 这里 需要指定写用哪个class去写,然后写到第一个sheet, 然后文件流会自动关闭

}

常用注解:

@ExcelIgnore:忽略实体类的指定字段,不将该字段转换成Excel,在属性字段上使用。

@ExcelIgnoreUnannotated:没有设置@ExcelProperty注解的字段都不转换,在类上使用。

@ColumnWidth(列宽):设置当前属性的列宽,可在属性和类上使用。

@ContentRowHeight(行高):设置当前的内容高度,可在类上使用。