使用下面几个方法

/**
     * Excel 导入 数据源本地文件,不返回校验结果 导入 字 段类型 Integer,Long,Double,Date,String,Boolean
     * 
     * @param file
     * @param pojoClass
     * @param params
     * @return
     */
    public static <T> List<T> importExcel(File file, Class<?> pojoClass, ImportParams params) {
        FileInputStream in = null;
        try {
            in = new FileInputStream(file);
            return new ExcelImportService().importExcelByIs(in, pojoClass, params, false).getList();
        } catch (ExcelImportException e) {
            throw new ExcelImportException(e.getType(), e);
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            throw new ExcelImportException(e.getMessage(), e);
        } finally {
            IOUtils.closeQuietly(in);
        }
    }

    /**
     * Excel 导入 数据源IO流,不返回校验结果 导入 字段类型 Integer,Long,Double,Date,String,Boolean
     * 
     * @param inputstream
     * @param pojoClass
     * @param params
     * @return
     * @throws Exception
     */
    public static <T> List<T> importExcel(InputStream inputstream, Class<?> pojoClass,
                                          ImportParams params) throws Exception {
        return new ExcelImportService().importExcelByIs(inputstream, pojoClass, params, false).getList();
    }
    /**
     * @param entity    表格标题属性
     * @param pojoClass Excel对象Class
     * @param dataSet   Excel对象数据List
     */
    public static Workbook exportExcel(ExportParams entity, Class<?> pojoClass,
                                       Collection<?> dataSet) {
        Workbook workbook = getWorkbook(entity.getType(), dataSet.size());
        new ExcelExportService().createSheet(workbook, entity, pojoClass, dataSet);
        return workbook;
    }

###1.6.2 对象不固定的导入导出
导出使用自己构造ExcelExportEntity,导入的话对象改成map就可以了

/**
     * 根据Map创建对应的Excel
     *
     * @param entity     表格标题属性
     * @param entityList Map对象列表
     * @param dataSet    Excel对象数据List
     */
    public static Workbook exportExcel(ExportParams entity, List<ExcelExportEntity> entityList,
                                       Collection<?> dataSet) {
        Workbook workbook = getWorkbook(entity.getType(), dataSet.size());
        ;
        new ExcelExportService().createSheetForMap(workbook, entity, entityList, dataSet);
        return workbook;
    }

导入还是上面方法,entity选择map就可以了,展示下map转Key,方便下一步处理

    public class MapImportHandler extends ExcelDataHandlerDefaultImpl<Map<String, Object>> {

        @Override
        public void setMapValue(Map<String, Object> map, String originKey, Object value) {
            if (value instanceof Double) {
                map.put(getRealKey(originKey), PoiPublicUtil.doubleToString((Double) value));
            } else {
                map.put(getRealKey(originKey), value != null ? value.toString() : null);
            }
        }

        private String getRealKey(String originKey) {
            if (originKey.equals("姓名")) {
                return "name";
            }
            if (originKey.equals("身份证")) {
                return "sfz";
            }
            if (originKey.equals("班主任寄语")) {
                return "content";
            }
            if (originKey.equals("学科")) {
                return "subjectName";
            }
            if (originKey.equals("学科成绩")) {
                return "subjectScore";
            }
            if (originKey.equals("子学科")) {
                return "childSubjectName";
            }
            if (originKey.equals("子学科成绩")) {
                return "childSubjectScore";
            }
            return originKey;
        }
    }

###1.6.3 量稍微有点大10W内
依然建议上面的写法,但不建议使用校验,可以加入下面参数加快时间,但是因为是一次返回可能量还是有点大,不支持一对多

 /**
     * 是否并行计算
     */
    private boolean             concurrentTask = false;

写出基本上不用改,10W以上会自己使用SXSSFWorkbook,不支持图片了等其他一些特性,速度回快一些可以使用USE_SXSSF_LIMIT这个参数调教

###1.6.4 更大量的读取,或者需要校验等时间稍长,或者频繁导入容易内存溢出
那就使用sax吧,这个更加高效,低内存但是支持较少

/**
     * Excel 通过SAX解析方法,适合大数据导入,不支持图片
     * 导入 数据源本地文件,不返回校验结果 导入 字 段类型 Integer,Long,Double,Date,String,Boolean
     * 
     * @param inputstream
     * @param pojoClass
     * @param params
     * @param handler
     */
    public static void importExcelBySax(InputStream inputstream, Class<?> pojoClass,
                                        ImportParams params, IReadHandler handler) {
        new SaxReadExcel().readExcel(inputstream, pojoClass, params, handler);
    }

不在处理完在回调,而是每处理一行就回答一次的方式方便大家更快的同步入库或者处理异常

    @Test
    public void test() {
        try {
            ImportParams params = new ImportParams();
            params.setTitleRows(1);
            params.setStartSheetIndex(1);
            long start = new Date().getTime();
            ExcelImportUtil.importExcelBySax(
                    new FileInputStream(
                            new File(FileUtilTest.getWebRootPath("import/saxtest.xlsx"))),
                    Map.class, params, 
                    // 这个是匿名类,不建议这样,最好还是自己实现一个类方便开发管理,泛型参数
                    new IReadHandler<Map>() {
                        @Override
                        public void handler(Map o) {
                            System.out.println(o);
                        }
                        // 所有数据执行完毕会调用这个类
                        @Override
                        public void doAfterAll() {
                            System.out.println("全部执行完毕了--------------------------------");
                        }
                    });
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

针对大数据量推荐方式是如下,每隔一段处理一次,cpu和内存都可以稳定在一定的范围内

new IReadHandler<Map>() {

    private List list = new ArrayList();
    @Override
    public void handler(Map o) {
        list.add(o);
        if(list.size == 1000){
            handlerData();
        }
    }
    // 所有数据执行完毕会调用这个类
    @Override
    public void doAfterAll() {
        handlerData();
    }

    private void handlerData(){
        //sava 或者其他操作
        save(list);
        list.clear();
    }
});

###1.6.5 更加大量的数据,百万级以上
使用csv把,这个靠谱的多,百万级读取数据也相当的快,内存也不高

    /**
     * Csv 导入流适合大数据导入
     * 导入 数据源IO流,不返回校验结果 导入 字段类型 Integer,Long,Double,Date,String,Boolean
     *
     * @param inputstream
     * @param pojoClass
     * @param params
     * @return
     */
    public static <T> List<T> importCsv(InputStream inputstream, Class<?> pojoClass,
                                        CsvImportParams params) {
        return new CsvImportService().readExcel(inputstream, pojoClass, params, null);
    }

    /**
     * Csv 导入流适合大数据导入
     * 导入 数据源IO流,不返回校验结果 导入 字段类型 Integer,Long,Double,Date,String,Boolean
     *
     * @param inputstream
     * @param pojoClass
     * @param params
     * @return
     */
    public static void importCsv(InputStream inputstream, Class<?> pojoClass,
                                        CsvImportParams params, IReadHandler readHandler) {
        new CsvImportService().readExcel(inputstream, pojoClass, params, readHandler);
    }

    /**
     * @param params    表格标题属性
     * @param pojoClass Excel对象Class
     * @param dataSet   Excel对象数据List
     */
    public static void exportCsv(CsvExportParams params, Class<?> pojoClass,
                                 Collection<?> dataSet, OutputStream outputStream) {
        new CsvExportService().createCsv(outputStream, params, pojoClass, dataSet);
    }

    /**
     * 根据Map创建对应的Excel
     *
     * @param params     表格标题属性
     * @param entityList Map对象列表
     * @param dataSet    Excel对象数据List
     */
    public static void exportCsv(CsvExportParams params, List<ExcelExportEntity> entityList,
                                 Collection<?> dataSet, OutputStream outputStream) {
        new CsvExportService().createCsvOfList(outputStream, params, entityList, dataSet);
    }

###1.6.6 模板适合在什么环境

- 样式比较复杂
- excel格式也复杂
- 多个excel拼接
- 懒得自己写代码
作者:悟耘信息  创建时间:2020-04-08 15:49
 更新时间:2022-09-04 22:15