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依赖

    xml 复制代码
            <!-- easy excel -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>easyexcel</artifactId>
                <version>3.3.2</version>
            </dependency>
  2. 编写controller

    java 复制代码
    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);
        }
    
    
    }
  3. 监听器

    java 复制代码
    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<T> implements ReadListener<T> {
    public AnalysisEventListener() {
    }

    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        this.invokeHeadMap(ConverterUtils.convertToStringMap(headMap, context), context);
    }

    public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
    }
}
java 复制代码
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

ReadListener中有三个重要接口

invokeHead:解析标题头的数据

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

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

相关推荐
小满、2 分钟前
对象住哪里?——深入剖析 JVM 内存结构与对象分配机制
java·jvm·#java对象分配·#hotspot实现
How_doyou_do3 分钟前
模态框的两种管理思路
java·服务器·前端
m0_748248029 分钟前
C++ 异常处理全解析:从语法到设计哲学
java·c++·word
仟濹10 分钟前
IDEA 软件下载 + 安装 | 操作步骤
java·ide·intellij-idea
毕设源码-赖学姐20 分钟前
【开题答辩全过程】以 法院信访投诉平台为例,包含答辩的问题和答案
java·eclipse
依_旧32 分钟前
MySQL下载安装配置(超级超级入门级)
java·后端
淘源码d1 小时前
什么是医院随访系统?成熟在用的智慧随访系统源码
java·spring boot·后端·开源·源码·随访系统·随访系统框架
程序猿阿越1 小时前
Kafka源码(七)事务消息
java·后端·源码阅读
m0_748248021 小时前
C++20 协程:在 AI 推理引擎中的深度应用
java·c++·人工智能·c++20
笑我归无处1 小时前
强引用、软引用、弱引用、虚引用详解
java·开发语言·jvm