0
点赞
收藏
分享

微信扫一扫

hutool读取大excel(超过10M)文件

三次方 2022-01-21 阅读 57

hutool读取大excel(超过10M)文件的时候gc会溢出,超出限制,为了解决这个问题,自己编写一个类,以读取大文件

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.Console;
import cn.hutool.poi.excel.sax.Excel07SaxReader;
import cn.hutool.poi.excel.sax.handler.RowHandler;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MyBigExcelUtil {

    private static List<Object> headLine;
    private static List<Map<String, Object>> datas = new ArrayList<>();

    /**
     * @param pathAndName        文件路径
     * @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名称,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
     */
    public static List<Map<String, Object>> readBigExcel(String pathAndName, int idOrRidOrSheetName) {
        Console.log("【{}】 开始读取 ... ", pathAndName);
        Excel07SaxReader reader = new Excel07SaxReader(new MyRowHandler());
        reader.read(pathAndName, idOrRidOrSheetName);
        Console.log("【{}】 读取完成 ... ", pathAndName);
        return datas;
    }

    /**
     * @param pathAndName        文件路径
     * @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名称,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
     * @param beanType           类类型
     * @param fieldMapping       T类型对应的别名,即类类型对应的 excel 的关系
     * @param <T>                返回值为List<T>
     * @return
     */
    public static <T> List<T> read(String pathAndName, int idOrRidOrSheetName, Class<T> beanType, Map<String, String> fieldMapping) {
        readBigExcel(pathAndName, idOrRidOrSheetName);
        List<T> datalist = new ArrayList<>();
        CopyOptions copyOptions = CopyOptions.create();
        copyOptions.setFieldMapping(fieldMapping);
        for (Map<String, Object> data : datas) {
            datalist.add(BeanUtil.mapToBean(data, beanType, copyOptions));
        }
        return datalist;
    }

    /**
     * @param pathAndName        文件路径
     * @param idOrRidOrSheetName Excel中的sheet id或者rid编号或sheet名称,rid必须加rId前缀,例如rId1,如果为-1处理所有编号的sheet
     * @param beanType           类类型
     * @param <T>                返回值为List<T>
     * @return
     */
    public static <T> List<T> read(String pathAndName, int idOrRidOrSheetName, Class<T> beanType) {
        readBigExcel(pathAndName, idOrRidOrSheetName);
        List<T> datalist = new ArrayList<>();
        for (Map<String, Object> data : datas) {
            datalist.add(BeanUtil.mapToBean(data, beanType, CopyOptions.create()));
        }
        return datalist;
    }

    private static class MyRowHandler implements RowHandler {
        @Override
        public void handle(int sheetIndex, long rowIndex, List<Object> rowList) {
			//Console.log("[{}] [{}] {}", sheetIndex, rowIndex, rowList);
            if (rowIndex == 0) {
                headLine = rowList;
            } else {
                Map<String, Object> tMap = new HashMap<>(rowList.size());
                for (int i = 0; i < rowList.size(); i++) {
                    tMap.put(transStr(headLine.get(i)), rowList.get(i));
                }
                datas.add(tMap);
            }
        }
    }

    private static String transStr(Object obj) {
        return obj == null ? "" : obj.toString();
    }

}
举报

相关推荐

0 条评论