Excel导入导出

不固定列Excel导入导出

一、介绍

  使用做多的开源框架主要有三类:

  • apache poi: poi是使用最广的一种导入导出框架,但是缺点也很明显,导出大量数据的时候,容易oom(内存不足、内存溢出)。
  • easypoi:  easypoi的底层也是基于apache poi进行深度开发的,他主要的特点就是将更多重复的工作,全部简单化,避免编写重复的代码,最显著的特点就是导出的支持非常丰富。
  • easyexcel: easyexcel是阿里巴巴开源的一款Excel解析工具,底层逻辑也是基于apache poi进行二次开发的,目前的应用也非常广。

  总的来说,easypoi和easyexcel都是基于apache poi 进行二次开发的。

  不同点:

  1. easypoi在读写数据的时候,优先是先将数据写入内存,因此读写性能非常高,这种操作平时使用的时候不会出现什么问题,但是当数据量很大的时候,会出现oom,当然它也提供sax模式一行一行解析,需要自己根据当前场景来实现。
  2. easyexcel默认基于sax模式一行一行解析,明显降低了内存,不会出现oom情况,程序有过高并发场景的验证,因此整体运行比较稳定,相对于easypoi来说,读写性能稍慢。
  3. easypoi的api非常丰富,easyexcel功能的支持,比较简单。(api应用程序接口)

    SAX(用于处理XML事件驱动的推模型),全称Simple API for XML,既是一种接口,也是一种软件包。它是一种XML解析的替代方法。SAX不同于DOM解析,它逐行扫描文档,一边扫描一边解析。由于应用程序只是在读取数据时检查数据,因此不需要将数据存储在内存中,这对于大型文档的解析是个巨大优势。

  easyexcel框架的使用

二、程序实例

  2.1、添加依赖包


<!--Excel导入导出依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
<version>1.7.2</version>
</dependency>
 

  2.2、导出Excel

  easyExcel的导出支持两种方式,一种是通过实体类注解方式生成文件,另一种是通过动态参数化生成文件。

  2.2.1、实体类注解方式生成文件

  实体类注解方式生成文件,操作非常简单,只需要在对应的属性字段上添加@ExcelProperty注解,然后填写列名,配置就完成了,示例代码如下:

  实体类:

 
public class UserEntity {
@ExcelProperty(value = "姓名")
private String name;

@ExcelProperty(value = "年龄")
private int age;

@DateTimeFormat("yyyy-MM-dd HH:mm:ss")
@ExcelProperty(value = "操作时间")
private Date time;

//get、set封装字段...
}
 

  main方法:

 
public class Text {
public static void main(String[] args) throws FileNotFoundException {
List<UserEntity> dataList=new ArrayList<>();
for (int i=0;i<10;i++){
UserEntity user=new UserEntity();
user.setName("张三"+i);
user.setAge(20+i);
user.setTime(new Date(System.currentTimeMillis()+i));
dataList.add(user);
}
//定义文件输出的位置
FileOutputStream ops=new FileOutputStream(new File("D:/easyexcel.xlsx"));
EasyExcel.write(ops,UserEntity.class).sheet("用户信息").doWrite(dataList);
}
}
 

  运行程序,打开文件.显示内容:

  

   2.2.2、动态参数化生成文件

  动态参数化生成文件,这种方式用的较多,基于它,可以封装一个公共的导出工具类:

   pom.xml配置:

 
  <dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>easyexcel</artifactId>
  <version>2.2.8</version>
  </dependency>
  <dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.11</version>
  <scope>test</scope>
  </dependency>
  <dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-nop</artifactId>
  <version>1.7.2</version>
  </dependency>
  <dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.17</version>
  </dependency>
  <!-- https://mvnrepository.com/artifact/com.google.common/google-collect -->
  <dependency><!--Lists工具类-->
  <groupId>com.google.common</groupId>
  <artifactId>google-collect</artifactId>
  <version>0.5</version>
  </dependency>
 

   main方法:

 
//动态参数化生成文件
public class ParameterText {
public static void main(String[] args) throws FileNotFoundException {
//定义表头
List<List<String>> headList=new ArrayList<>();
headList.add(Lists.newArrayList("姓名"));
headList.add(Lists.newArrayList("年龄"));
headList.add(Lists.newArrayList("操作时间"));

//定义数据体
List<List<Object>> dataList=new ArrayList<>();
for (int i = 0; i < 10; i++) {
List<Object> data=new ArrayList<>();
data.add("张三"+i);
data.add(20+i);
data.add(new Date(System.currentTimeMillis()+i));
dataList.add(data);
}
//定义文件输出路径
FileOutputStream fops=new FileOutputStream("D:/easyexcel1.xlsx");
EasyExcel.write(fops).head(headList).sheet("信息").doWrite(dataList);
}
}
 

   运行结果,与上面一致:

    

 

   2.2.3、生成复杂的表头

     

 

     2.2.3.1、实体类添加注解的方法:

 
public class UserHeader {
  @ExcelProperty(value = "班级")
  private String className;

  @ExcelProperty({"学生信息","姓名"})
  private String name;

  @ExcelProperty({"学生信息","年龄"})
  private int age;

  @DateTimeFormat("yyyy-MM-dd HH:mm:ss")
  @ExcelProperty({"学生信息","入学时间"})
  private Date time;
    //get和set封装字段...
  }
 

   【其中{"学生信息","姓名"}表示:在当前列,插入多行数据,第一行是学生信息,第二行是姓名,这样就形成多级表头。】

   main方法:

//复杂表头//实体注解方法
  public class ComplexHeaderNote {
  public static void main(String[] args) throws FileNotFoundException {
  List<UserHeader> userList=new ArrayList<>();
  for (int i = 0; i < 10; i++) {
  UserHeader user=new UserHeader();
  user.setClassName("一年级~"+i+"班");
  user.setName("李四"+i);
  user.setAge(5+i);
  user.setTime(new Date(System.currentTimeMillis()+i));
  userList.add(user);
  }
  //定义文件输出的位置
  FileOutputStream ops=new FileOutputStream(new File("D:/easyexcel.xlsx"));
  EasyExcel.write(ops, UserHeader.class).sheet("复杂表头信息").doWrite(userList);
  }
  }
 

     2.2.3.2、动态参数化生成复杂表头

      代码:

 
//动态参数化生成复杂表头
  public class ComplexHeaderParameter {
  public static void main(String[] args) throws FileNotFoundException {
  //定义多级表头
  List<List<String>> headList=new ArrayList<>();
  headList.add(Lists.newArrayList("班级"));
  headList.add(Lists.newArrayList("学生信息","姓名"));
  headList.add(Lists.newArrayList("学生信息","年龄"));
  headList.add(Lists.newArrayList("学生信息","入学时间"));
  //定义数据体
  List<List<Object>> dataList=new ArrayList<>();
  for (int i = 0; i < 10; i++) {
  List<Object> data=new ArrayList<>();
  data.add("一年级~"+i+"班");
  data.add("李四"+i);
  data.add(5+i);
  data.add(new Date(System.currentTimeMillis()+i));
  dataList.add(data);
  }
  //定义文件输出位置
  FileOutputStream fops=new FileOutputStream(new File("D:/easyexcel2.xlsx"));
  EasyExcel.write(fops).head(headList).sheet("用户信息").doWrite(dataList);
  }
  }
 

  2.2.4、自定义样式

  

 

     1.实体注解方法:

      在2.2.3生成复杂表头的基础上进行

      编写一个自定义样式的方法,然后在写入的时候注入进去。

      customStyle()方法:(放到main方法下面)

  /**
  * 自定义样式
  * @return
  */
  private static HorizontalCellStyleStrategy customStyle(){
  //表头的策略
  WriteCellStyle headWriteCellStyle=new WriteCellStyle();
  //背景颜色设置
  headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());//红色
  WriteFont headWriteFont=new WriteFont();
  headWriteFont.setFontHeightInPoints((short)20);
  headWriteCellStyle.setWriteFont(headWriteFont);
  //内容策略
  WriteCellStyle contentWriteCellStyle=new WriteCellStyle();
  //需要制定FillPatternType为FillPatternType.SOLID_FOREGROUND,不然无法显示背景颜色
  // 表头默认为FillPatternType,所以可以不指定
  contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
  //背景颜色设置
  contentWriteCellStyle.setFillForegroundColor(IndexedColors.YELLOW.getIndex());//黄色
  WriteFont contentWF=new WriteFont();
  //字体大小
  contentWF.setFontHeightInPoints((short)20);
  contentWriteCellStyle.setWriteFont(contentWF);

  //水平单元风格策略,表头的样式,内容的样式
  HorizontalCellStyleStrategy hcss=new HorizontalCellStyleStrategy(headWriteCellStyle,contentWriteCellStyle);
  System.out.println(hcss);
  return hcss;
  }
 

    main()方法中修改:  

    //定义文件输出的位置
    FileOutputStream fops=new FileOutputStream(new File("D:/easyexcel.xlsx"));
    //EasyExcel.write(fops, UserHeader.class).sheet("复杂表头信息").doWrite(userList);
    //通过registerWriterHandle方法,将自定义的样式类注入进去
    EasyExcel.write(fops,UserHeader.class).registerWriteHandler(customStyle()).sheet("用户信息").doWrite(userList);

    2.动态参数化方法

    编写一个自定义样式的方法:customStyle()方法:(放到main方法下面)

    main()方法中修改: 

    //定义文件输出位置
    FileOutputStream fops=new FileOutputStream(new File("D:/easyexcel2.xlsx"));
    //EasyExcel.write(fops).head(headList).sheet("用户信息").doWrite(dataList);
    //通过registerWriterHandle方法,将自定义的样式类注入进去
    EasyExcel.write(fops).registerWriteHandler(customStyle()).head(headList).sheet("用户信息").doWrite(dataList);

  2.3、导入Excel

  easyexcel 的导入同样也支持两种方式:一种是通过实体类注解方式来读取文件,另一种是通过动态监听器读取文件。

  2.3.1、实体类注解方法来读取文件(普通表头读取)

    读取的Excel表头需要与实体类一一对应:

    

   实体类:UserReadEntity 

    通过注解方式来读取,既可以指定列的下表,也可以通过列名来映射,但是两者智能取一个。

//读取实体类
    public class UserReadEntity {
    @ExcelProperty(value = "姓名")
    private String name;
      //强制读取第三个,这里不建议index和name同时用,要么一个对象只用index,要么一个对象只用name去匹配
        @ExcelProperty(index = 1)
    private int age;

    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")
    @ExcelProperty(value = "操作时间")
    private Date time;
  //get与set方法封装...
    }

    pom.xml导入:fastjson
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>fastjson</artifactId>
  <version>1.2.76</version>
  </dependency>
    main方法:
  //读取Excel文件
  public class ReadNote {
  public static void main(String[] args) throws FileNotFoundException {
  //同步读取文件内容
  FileInputStream fis=new FileInputStream(new File("D:/easyexcel1.xlsx"));
  List<UserReadEntity> list= EasyExcel.read(fis).head(UserReadEntity.class).sheet().doReadSync();
  System.out.println(JSON.toJSONString(list));
  }
  }

    运行结果:

  [{"age":20,"name":"张三0","time":1618988915000},{"age":21,"name":"张三1","time":1618988915000},{"age":22,"name":"张三2","time":1618988915000},{"age":23,"name":"张三3","time":1618988915000},{"age":24,"name":"张三4","time":1618988915000},{"age":25,"name":"张三5","time":1618988915000},{"age":26,"name":"张三6","time":1618988915000},{"age":27,"name":"张三7","time":1618988915000},{"age":28,"name":"张三8","time":1618988915000},{"age":29,"name":"张三9","time":1618988915000}]

  2.3.2、动态监听器读取文件

  动态监听器读取文件,与注解的方式有一个明显的区别是重新写一个实现类,来监听easyexcel一行一行解析出来的数据,然后将数据封装出来,基于此,可以编写一套动态的导入工具类,示例代码:

  Listener监听器实现类:UserDataListener 


//创建监听器,继承自AnalysisEventListener
  public class UserDataListener extends AnalysisEventListener<Map<Integer,String>> {
  //日志记录器
  private static final Logger log= LoggerFactory.getLogger(UserDataListener.class);
  //表头数据
  private List<Map<Integer,String>> headList=new ArrayList<>();
  //数据体
  private List<Map<Integer,String>> dataList=new ArrayList<>();
  //这里会一行一行的返回头
  @Override
  public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
  log.info("解析到一条头数据{}", JSON.toJSONString(headList));
  System.out.println("解析到头数据!");
  headList.add(headMap);
  }
  //这个每条数据解析都会来调用
  @Override
  public void invoke(Map<Integer, String> data, AnalysisContext context) {
  log.info("解析到一条数据:{}"+JSON.toJSONString(data));
  System.out.println("解析到一条数据:"+ JSON.toJSONString(data));
  dataList.add(data);
  }
  //所有数据解析完成了,都会来调用
  @Override
  public void doAfterAllAnalysed(AnalysisContext analysisContext) {
  log.info("所有数据解析完成!");
  System.out.println("所有数据解析完成");
  }
  public List<Map<Integer,String>> getHeadList(){
  return headList;
  }
  public List<Map<Integer,String>> getDataList(){
  return dataList;
  }
  }
 

  main方法:

  public class ReadListener {
  public static void main(String[] args) throws FileNotFoundException {
  FileInputStream inputStream=new FileInputStream(new File("D:/easyexcel1.xlsx"));
  //初始化监听器
  UserDataListener listener=new UserDataListener();
  //读取文件数据
  EasyExcel.read(inputStream,listener).sheet().doRead();
  System.out.println("表头:"+ JSONArray.toJSONString(listener.getHeadList()));
  System.out.println("数据体:"+JSONArray.toJSONString(listener.getDataList()));
  }
  }

   运行输出的结果: 

    

    表头:[{0:"姓名",1:"年龄",2:"操作时间"}]
    数据体:[{0:"张三0",1:"20",2:"2021-04-21 15:08:35"},{0:"张三1",1:"21",2:"2021-04-21 15:08:35"},{0:"张三2",1:"22",2:"2021-04-21 15:08:35"},{0:"张三3",1:"23",2:"2021-04-21 15:08:35"},{0:"张三4",1:"24",2:"2021-04-21 15:08:35"},{0:"张三5",1:"25",2:"2021-04-21 15:08:35"},{0:"张三6",1:"26",2:"2021-04-21 15:08:35"},{0:"张三7",1:"27",2:"2021-04-21 15:08:35"},{0:"张三8",1:"28",2:"2021-04-21 15:08:35"},{0:"张三9",1:"29",2:"2021-04-21 15:08:35"}]

  2.3.3、复杂表头读取

  

  1.如果采用注解的方式导出文件,同样也可以通过注解方式来读取,例如上面是用实体类生成的文件,也可以通过这个类读取文件!

    注解实体类

    

 

     main方法:


//读取复杂表头的文件
    public class ReadComplexHead {
    public static void main(String[] args) {
    List<UserHeader> list= EasyExcel.read("D:/easyexcel2.xlsx").head(UserHeader.class).sheet().doReadSync();
    System.out.println(JSONArray.toJSONString(list));
    }
    }
 

    运行结果:

  [{"age":5,"className":"一年级~0班","name":"李四0","time":1619423603000},{"age":6,"className":"一年级~1班","name":"李四1","time":1619423603000},{"age":7,"className":"一年级~2班","name":"李四2","time":1619423603000},{"age":8,"className":"一年级~3班","name":"李四3","time":1619423603000},{"age":9,"className":"一年级~4班","name":"李四4","time":1619423603000},{"age":10,"className":"一年级~5班","name":"李四5","time":1619423603000},{"age":11,"className":"一年级~6班","name":"李四6","time":1619423603000},{"age":12,"className":"一年级~7班","name":"李四7","time":1619423603000},{"age":13,"className":"一年级~8班","name":"李四8","time":1619423603000},{"age":14,"className":"一年级~9班","name":"李四9","time":1619423603000}]

  2.如果使用动态参数化生成文件,可以采用动态监听器的方法读取文件,在读取时需要指定所在行,实例代码:   

  
//读取复杂表头文件//动态参数化方法
  public class ReadComplexHeadListener {
  public static void main(String[] args) throws FileNotFoundException {
  FileInputStream inputStream=new FileInputStream(new File("D:/easyexcel2.xlsx"));
  //初始化监听器
  UserDataListener listener=new UserDataListener();
  EasyExcel.read(inputStream,listener).sheet().headRowNumber(2).doRead();
  System.out.println("表头:"+ JSONArray.toJSONString(listener.getHeadList()));
  System.out.println("数据体:"+JSONArray.toJSONString(listener.getDataList()));
  }
  }

  运行结果:
  

 


 三、动态导出导入工具类封装

  在实际开发中,不可能每来一个Excel导入导出需求就编写一个方法,而且很多业务需求都是动态导入导出,没办法基于实体类注解的方法来读取文件或者写入文件。
  基于动态参数化生成文件和动态监听器读取文件方法,可以单独封装一套动态导出导入工具类,省的每次重新编写。
  • 动态导出工具类 
/**
* 动态导出工具类
*/
public class DynamicEasyExcelExportUtils {
private static final Logger log= LoggerFactory.getLogger(DynamicEasyExcelExportUtils.class);
private static final String DEFAULT_SHEET_NAME="sheet1";

/**
* 动态生成导出模板(单表头)
* @param headColumns 列名称
* @return excel文件流
*/
public static byte[] exportTemplateExcelFile(List<String> headColumns) {
List<List<String>> excelHead= Lists.newArrayList();
headColumns.forEach(columnName ->{ excelHead.add(Lists.newArrayList(columnName));});
byte[] stream=createExcelFile(excelHead,new ArrayList<>());
return stream;
}

/**
* 动态生成模板(复杂表头)
* @param excelHead 列名称
* @return
*/
public static byte[] exportTemplateExcelFileCustomHead(List<List<String>> excelHead){
byte[] stream=createExcelFile(excelHead,new ArrayList<>());
return stream;
}

/**
* 动态导出文件
* @param headColumnMap 有序列头部
* @param dataList 数据体
* @return
*/
public static byte[] exportExcelFile(LinkedHashMap<String,String> headColumnMap, List<Map<String,Object>> dataList){
//获取列名称
List<List<String>> excelHead=new ArrayList<>();//获取列名称
if (MapUtils.isNotEmpty(headColumnMap)){
//key为匹配符,value为列名,如果多级列名
headColumnMap.entrySet().forEach(entry -> {
excelHead.add(Lists.newArrayList(entry.getValue().split(",")));
});
}
List<List<Object>> excelRows=new ArrayList<>();
if (MapUtils.isNotEmpty(headColumnMap) && CollectionUtils.isNotEmpty(dataList)){
for (Map<String,Object> dataMap : dataList){
List<Object> rows=new ArrayList<>();
headColumnMap.entrySet().forEach(headColumnEntry ->{
if (dataMap.containsKey(headColumnEntry.getKey())){
Object data=dataMap.get(headColumnEntry.getKey());
rows.add(data);
}
});
excelRows.add(rows);
}
}
byte[] stream=createExcelFile(excelHead,excelRows);
return stream;
}

/**
* 生成文件
* @param excelHead
* @param excelRows
* @return
*/
private static byte[] createExcelFile(List<List<String>> excelHead,List<List<Object>> excelRows){
try{
if (CollectionUtils.isNotEmpty(excelHead)){
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
EasyExcel.write(outputStream).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
.head(excelHead)
.sheet(DEFAULT_SHEET_NAME)
.doWrite(excelRows);
return outputStream.toByteArray();
}
}catch (Exception e){
log.error("动态生成Excel文件失败,headColumns:"+ JSONArray.toJSONString(excelHead)+",excelRows:"+JSONArray.toJSONString(excelRows),e);

}
return null;
}

/**
* 导出文件测试
* @param args
* @throws IOException
*/
private static void main(String[] args) throws IOException {
//导出包含数据内容的文件
LinkedHashMap<String,String> headColumnMap= Maps.newLinkedHashMap();
headColumnMap.put("class","班级");
headColumnMap.put("name","学生信息,姓名");
headColumnMap.put("sex","学生信息,性别");
List<Map<String,Object>> dataList=new ArrayList<>();
for (int i=0;i<5;i++){
Map<String,Object> dataMap=Maps.newHashMap();
dataMap.put("class","一年级");
dataMap.put("name","张三"+i);
dataMap.put("sex","男");
dataList.add(dataMap);
}
byte[] stream=exportExcelFile(headColumnMap,dataList);
FileOutputStream outputStream=new FileOutputStream(new File("D:/easyexcel1.xlsx"));
outputStream.write(stream);
outputStream.close();
}

}

 

  •  动态导入工具类
/**
* 创建一个监听器
* 动态导入工具类
*/
public class DynamicEasyExcelListener extends AnalysisEventListener<Map<Integer,String>> {
private static final Logger log= LoggerFactory.getLogger(UserDataListener.class);
//表头数据(存储所有的表头数据)
private List<Map<Integer,String>> headList=new ArrayList<>();
//数据体
private List<Map<Integer,String>> dataList=new ArrayList<>();


public List<Map<Integer,String>> getHeadList(){
return headList;
}

public List<Map<Integer,String>> getDataList(){
return dataList;
}

/**
* 一行行的返回头
* @param headMap
* @param context
*/
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
log.info("解析到一条头部数据:{}"+JSON.toJSONString(headMap));
//存储全部表头数据
headList.add(headMap);
}

/**
* 每一条数据解析都会调用
* @param data
* @param context
*/
@Override
public void invoke(Map<Integer, String> data, AnalysisContext context) {
log.info("解析到一条数据:{}",JSON.toJSONString(data));
dataList.add(data);
}

/**
* 所有数据解析完成后都会调用
* @param analysisContext
*/
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
//这里也要保存数据,确保最后遗留的数据也存储到数据库
log.info("所有数据解析完成!");
}
}
/**
* 导入工具类
*/
public class DynamicEasyExcelImportUtils {
/**
* 动态获取全部列和数据体,默认从第一行开始解析数据
* @param stream
* @return
*/
public static List<Map<String,String>> parseExcelToView(byte[] stream){
return parseExcelToView(stream,1);
}

/**
* 动态获取全部列和数据体
* @param stream Excel文件流
* @param parseRowNumber 指定读取行
* @return
*/
public static List<Map<String, String>> parseExcelToView(byte[] stream, Integer parseRowNumber) {
DynamicEasyExcelListener readListener=new DynamicEasyExcelListener();
EasyExcelFactory.read(new ByteArrayInputStream(stream)).registerReadListener(readListener).headRowNumber(parseRowNumber).sheet(0).doRead();
List<Map<Integer,String>> headList=readListener.getHeadList();
if (CollectionUtils.isEmpty(headList)){
throw new RuntimeException("Excel未包含表头");
}
List<Map<Integer,String>> dataList=readListener.getDataList();
if (CollectionUtils.isEmpty(dataList)){
System.out.println("Excel未包含数据!!");
}
//获取头部,取最后一次解析的列头数据
Map<Integer,String> excelHeadIdxNameMap=headList.get(headList.size()-1);
//封装数据体
List<Map<String,String>> excelDataList= Lists.newArrayList();
for (Map<Integer,String> dataRow : dataList) {
Map<String,String> rowData=new LinkedHashMap<>();
excelHeadIdxNameMap.entrySet().forEach(columnHead ->{
rowData.put(columnHead.getValue(),dataRow.get(columnHead.getKey()));
});
excelDataList.add(rowData);
}

return excelDataList;
}

/**
* 文件导入测试
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
FileInputStream inputStream=new FileInputStream(new File("D:/easyexcel1.xlsx"));
byte[] stream= IOUtils.toByteArray(inputStream);
List<Map<String,String>> dataList=parseExcelToView(stream,2);
System.out.println(JSONArray.toJSONString(dataList));
inputStream.close();
}
}

四、总结

  以上是对easyexcel的简单使用,对动态导出导入基于业务的需要,做了一个公共的工具类,方便后续的使用!

  easyexcel的功能还有很多,还有基于模板进行Excel填充,具体可以参考官方的文档:

  https://www.yuque.com/easyexcel/doc/read#1bfaf593

 

 

posted @ 2021-04-20 17:10  Luckyfairy  阅读(26)  评论(0编辑  收藏  举报