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

目录

问题

如何解决

使用示例

pom

监听器

实体类

读写方法

测试类


问题

以前项目使用 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);
    }
}

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值