Java EasyExcel读写excel如何解决poi读取大文件内存溢出问题

 更新时间:2024年06月17日 10:48:44   作者:编程经验分享  
这篇文章主要介绍了Java EasyExcel读写excel如何解决poi读取大文件内存溢出问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

问题

以前项目使用 poi 读写 excel,但是 excel 中的数据量太大的话,用 poi 读取时就会导致 OOM 异常,这是因为 poi 在读取数据时,是将全部数据一次性都加载到内存中。

如何解决

使用EasyExcel,以下是使用示例。

使用示例

pom

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.1.3</version>
        </dependency>

监听器

public class ProductListener extends AnalysisEventListener<Product> {

    private static final int BATCH_COUNT = 1000;

    private final List<Product> list = new ArrayList<>();

    private int totalCount;

    public ProductListener() {}

    @Override
    public void invoke(Product product, AnalysisContext analysisContext) {
        list.add(product);
        if(list.size() >= BATCH_COUNT){
            saveData();
            list.clear();
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        saveData();
        System.out.printf("数据同步完成,总数量为:%s%n",totalCount);
    }


    public void saveData(){
        if(!list.isEmpty()){
            for (Product product : list) {
                insertIgnore(product);
            }
        }
    }

    public void insertIgnore(Product product) {
        try {
            // 执行数据库操作
            System.out.println(product.getName());
            ++totalCount;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

实体类

public class Product {

    private Long id;

    @ExcelProperty("name")
    private String name;

    @ExcelProperty("quantity")
    private Long quantity;

    @ExcelProperty("desc")
    private String desc;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getQuantity() {
        return quantity;
    }

    public void setQuantity(Long quantity) {
        this.quantity = quantity;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }
}

读写方法

public class MyEasyExcel {

    public static void read(String filePath) {

        try (InputStream inputStream = Files.newInputStream(Paths.get(filePath))) {
            EasyExcel.read(inputStream, Product.class, new ProductListener())
                    .sheet()
                    .doRead();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void write(List<Product> data, String filePath) {

        try (OutputStream outputStream = Files.newOutputStream(Paths.get(filePath))) {
            ExcelWriterBuilder writerBuilder = EasyExcel.write(outputStream, Product.class);
            writerBuilder.sheet("Data").doWrite(data);
        } catch (Exception e) {
            // 处理异常
        }
    }
}

测试类

class MyEasyExcelTest {

    @Test
    void read() {
        String filePath = "C:\\Users\\XXX\\Desktop\\excel.xlsx";
        MyEasyExcel.read(filePath);
    }

    @Test
    void write() {
        List<Product> products = new ArrayList<>();
        Product product = new Product();
        product.setId(1L);
        product.setName("qwe");
        product.setDesc("abc");
        product.setQuantity(1342L);
        products.add(product);

        String filePath = "C:\\Users\\XXX\\Desktop\\excel.xlsx";

        MyEasyExcel.write(products, filePath);
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring Boot如何利用拦截器加缓存完成接口防刷操作

    Spring Boot如何利用拦截器加缓存完成接口防刷操作

    流的需求出现在许多常见的场景中,下面这篇文章主要给大家介绍了关于Spring Boot如何利用拦截器加缓存完成接口防刷操作的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-02-02
  • SpringBoot集成Redis—使用RedisRepositories详解

    SpringBoot集成Redis—使用RedisRepositories详解

    这篇文章主要介绍了SpringBoot集成Redis—使用RedisRepositories详解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Java 中文字符按Unicode排序的实现方法

    Java 中文字符按Unicode排序的实现方法

    这篇文章主要介绍了Java 中文字符按Unicode排序的实现方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-10-10
  • JavaFx Tooltip悬浮提示使用及自定义代码详解

    JavaFx Tooltip悬浮提示使用及自定义代码详解

    本篇是基于TornadoFx框架对Tooltip组件进行讲解,使用Kotlin语言,和传统Java使用有所区别,本章节包括对tooltip的样式定制化以及指定窗口显示,对JavaFx Tooltip悬浮提示使用及自定义相关知识感兴趣的朋友一起看看吧
    2021-12-12
  • Spring boot学习教程之快速入门篇

    Spring boot学习教程之快速入门篇

    这篇文章主要给大家介绍了关于Spring boot的相关资料,本文属于基础入门教程,对各位学习Spring boot的新手们具有一定的参考学习价值,,要的朋友们下面来一起看看吧。
    2017-04-04
  • 使用spring aop统一处理异常和打印日志方式

    使用spring aop统一处理异常和打印日志方式

    这篇文章主要介绍了使用spring aop统一处理异常和打印日志方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • SpringBoot整合aop面向切面编程过程解析

    SpringBoot整合aop面向切面编程过程解析

    这篇文章主要介绍了SpringBoot整合aop面向切面编程过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • JDK19新特性使用实例详解

    JDK19新特性使用实例详解

    这篇文章主要为大家介绍了JDK19新特性使用实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • spring中的DI步骤详解

    spring中的DI步骤详解

    本文主要介绍了bean的装配实现过程,通常对于简单数据类型数据初始主要在获得对象后,使用setter方法完成,所谓的装配主要是复杂数据类型的依赖注入,感兴趣的朋友一起看看吧
    2023-11-11
  • Java多线程饥饿与公平介绍及代码示例

    Java多线程饥饿与公平介绍及代码示例

    这篇文章主要介绍了Java多线程饥饿与公平介绍及代码示例,分析饥饿产生的原因以及相关实例,然后就在java中实现公平性问题做了详细解析,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11

最新评论