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>
    
  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 = "[email protected]", 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);
        }
    
    
    }
    
    
  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;
        }
    
    
    }
    

重点代码解析

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) {
    }
}
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;
    }
}

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

EasyExcel_第1张图片

ReadListener中有三个重要接口

invokeHead:解析标题头的数据

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

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

你可能感兴趣的:(中间件,excel,java)