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

}

测试

hutool读取resource目录下的文件 hutool文件读写_poi