• EasyExcel


    EasyExcel

    官方文档

    EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel (alibaba.com)

    优势

    Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及解压后存储都是在内存中完成的,内存消耗依然很大。一旦并发上来后一定会OOM或者JVM频繁的full gc.
    easyexcel重写了poi对07版Excel的解析,一个3M的excel用POI sax解析依然需要100M左右内存,改用easyexcel可以降低到几M,并且再大的excel也不会出现内存溢出;03版依赖POI的sax模式,在上层做了模型转换的封装,让使用者更加简单方便。

    代码示例

    关于Easyexcel | Easy Excel (alibaba.com)

    excel转json数据

    1. 引入easy excel依赖

              
              <dependency>
                  <groupId>com.alibabagroupId>
                  <artifactId>easyexcelartifactId>
                  <version>3.3.2version>
              dependency>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    2. 编写controller

      package com.junfeng.tool.controller;
      
      import com.alibaba.excel.EasyExcel;
      import com.alibaba.fastjson.JSON;
      import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
      import com.github.xiaoymin.knife4j.annotations.ApiSupport;
      import com.junfeng.tool.config.EasyExcelListener;
      import io.swagger.annotations.Api;
      import io.swagger.annotations.ApiOperation;
      import lombok.extern.slf4j.Slf4j;
      import org.springframework.web.bind.annotation.PostMapping;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.RestController;
      import org.springframework.web.multipart.MultipartFile;
      
      import java.io.IOException;
      import java.util.List;
      import java.util.Map;
      
      /***
       * @Author junfeng
       */
      @Api(tags = "excel")
      @ApiSupport(author = "1033110136@qq.com", order = 1)
      @RestController
      @RequestMapping("/api/excel")
      @Slf4j
      public class  ExcelController {
      
      
          @ApiOperationSupport(author = "junfeng")
          @ApiOperation(value = "excel转换json")
          @PostMapping("/upload")
          public Object upload(@RequestParam("file") MultipartFile file) throws IOException {
              // 读取Excel
              EasyExcel.read(file.getInputStream(), new EasyExcelListener()).sheet().headRowNumber(1).doRead();
      
              // 从监听中获取结果集
              List<Map<String, Object>> importList = EasyExcelListener.dataList;
              log.info("导入集合 list = {}", JSON.toJSON(importList));
      
              return JSON.toJSON(importList);
          }
      
      
      }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
    3. 监听器

      package com.junfeng.tool.config;
      
      import com.alibaba.excel.context.AnalysisContext;
      import com.alibaba.excel.event.AnalysisEventListener;
      import lombok.extern.slf4j.Slf4j;
      
      import java.util.ArrayList;
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;
      
      @Slf4j
      public class EasyExcelListener extends AnalysisEventListener<Map<String, Object>> {
      
          private Map<Integer, String> headMap;
      
          public static final List<Map<String, Object>> dataList = new ArrayList<>();
      
          @Override
          public void invoke(Map<String, Object> data, AnalysisContext context) {
              //把表头和值放入Map
              HashMap<String, Object> paramsMap = new HashMap<>();
              for (int i = 0; i < data.size(); i++) {
                  String key = headMap.get(i);
                  Object value = data.get(i);
                  //将表头作为map的key,每行每个单元格的数据作为map的value
                  paramsMap.put(key, value);
                  dataList.add(paramsMap);
              }
          }
      
          @Override
          public void doAfterAllAnalysed(AnalysisContext context) {
      
          }
      
          @Override
          public void invokeHeadMap(Map<Integer, String> head, AnalysisContext context) {
              headMap = head;
          }
      
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43

    重点代码解析

    public abstract class AnalysisEventListener implements ReadListener {
        public AnalysisEventListener() {
        }
    
        public void invokeHead(Map> headMap, AnalysisContext context) {
            this.invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context);
        }
    
        public void invokeHeadMap(Map headMap, AnalysisContext context) {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    public interface ReadListener<T> extends Listener {
        default void onException(Exception exception, AnalysisContext context) throws Exception {
            throw exception;
        }
    
        default void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        }
    
        void invoke(T var1, AnalysisContext var2);
    
        default void extra(CellExtra extra, AnalysisContext context) {
        }
    
        void doAfterAllAnalysed(AnalysisContext var1);
    
        default boolean hasNext(AnalysisContext context) {
            return true;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    如下图EasyExcelListener继承AnalysisEventListener实现接口ReadListener

    在这里插入图片描述

    ReadListener中有三个重要接口

    invokeHead:解析标题头的数据

    invoke:这个每一条数据解析都会来调用,这里可以将数据存到list集合里面,给外部调用。

    doAfterAllAnalysed:所有数据解析完成了 都会来调用,这里可以写保存数据库的逻辑

  • 相关阅读:
    Android里获取正在前端运行的Activity的包名
    Hash表实现原理
    408王道操作系统强化——存储管理及大题解构
    java关键字this使用详解
    React native Navigation传值跳转小白教程
    阿里云云原生一体化数仓—离线实时一体化新能力解读
    marquee.弹窗事件
    位运算(超详细)
    T1097 画矩形(信息学一本通C++)
    LQ0137 双向排序【模拟】
  • 原文地址:https://blog.csdn.net/qq_26347283/article/details/133899740