hutool工具导入excel文件处理大文件解决OOM问题。

hutool 支持excel导入 导出 底层使用的是依赖是需要导入poi

由于项目中excel导入的列名不是固定,所以只能使用行来读,不需要定义实体类,缺点就是只能读一个sheet,经过测试大文件会出现oom,由于之前使用的ExcelUtil.getReader不支持读取大文件。第二个坑就是excel文件格式 xlsx这个才是正确,xls读大文件会出现不兼容日期的现象。下面科普一下。

.xls,文件存储格式实现原理是基于微软的ole db是微软com组件的一种实现,本质上也是一个微型数据库,由于微软的东西很多不开源,基本上也已经被淘汰,了解它的细节意义不大。
.xlsx ,文件存储格式实现是基于openXml和zip技术((用winrar可以打开看)。它的优点是简单存储、安全传输方便、处理数据简单。

原因是:读取excel全部内容到内存中,当文件内容几十万条 很显然会造成Jvm内存溢出。

ExcelReader reader = ExcelUtil.getReader(file.getInputStream());

解决方式使用:hutool提供的api readBySax可以支持去大文件,这是poi做出的优化。

new RowHandler() 需要重写他的方法

注意:在此说明其实使用的是 org.apache.poi**,hutool在底层调用是poi
 ExcelUtil.readBySax(file.getInputStream(), 0, new RowHandler() {
            @Override
            public void handle(int i, int i1, List<Object> list) {
            //list 此时的内容就是 excel一行的内容,
            //我理解是一行一行读 读完就释放,上面的方法是一口气读全部到内存
          Console.log("[{}] [{}] {}", i, i1, list);
            }
        });

1、上代码 + pom 依赖

 <!-- hutool 工具包 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>4.1.19</version>
        </dependency>

        <!-- poi exce表格导入导出 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

        <!-- poi需要使用 excel表格解析器 -->
        <dependency>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
            <version>2.11.0</version>
        </dependency>

代码

package com.excel.batch.excelBatchController;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.sax.handler.RowHandler;
import org.springframework.web.bind.annotation.PostMapping;
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: 宋忠瑾
 * @Description: excel 导入实现 文件格式 xlsx
 * @Date: Create in 17:14 2021/8/31
 */
@RestController
public class Test {

    /**
     * 仅限小文件读取
     */
    @PostMapping("/excel1")
    public void importOneExcel(@RequestParam(name = "file") MultipartFile file) throws IOException {
        ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
        //1、读取Excel中所有行和列,都用列表表示 可以指定从哪行开始读 默认从0开始读
        List<List<Object>> read = reader.read(1);

        //2、读取为Map列表,默认第一行为标题行,Map中的key为标题,value为标题对应的单元格值。
        List<Map<String,Object>> readAll = reader.readAll();

        //3、读取为Bean列表,Bean中的字段名为标题,字段值为标题对应的单元格值。
        List<Object> all = reader.readAll(Object.class);

        System.out.println("read = " + read);
    }

    /**
     * 支持大文件读取
     * @Description excel表格批量 大文件
     * @Method  importExcel 导入excel
     * @Author  宋忠瑾
     * @Date   2021/8/31 17:36
     * @param file excel
     * @return void 无返回
     */
    @PostMapping("/excel")
    public void importBatchExcel(@RequestParam(name = "file") MultipartFile file) throws IOException {
        ExcelUtil.readBySax(file.getInputStream(), 0, new RowHandler() {
            @Override
            public void handle(int i, int i1, List<Object> list) {
                System.out.println(list);
            }
        });
    }

}

测试

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值