当前位置:首页 > 生活百科

java实现excel导入(java批量导入excel数据)

栏目:生活百科日期:2025-02-03浏览:0

看完本文,你一定会有所收获

一、介绍

在上篇文章中,我们简单的介绍了 excel 导入导出技术实践方案,就目前而已,使用最多的开源框架主要有以下三类,分别是:

apache poi:poi是使用最广的一种导入导出框架,但是缺点也很明显,导出大数据量的时候,容易oomeasypoi:easypoi 的底层也是基于 apache poi 进行深度开发的,它主要的特点就是将更多重复的工作,全部简单化,避免编写重复的代码,最显著的特点就是导出的支持非常丰富easyexcel:easyexcel 是阿里巴巴开源的一款 excel 解析工具,底层逻辑也是基于 apache poi 进行二次开发的,目前的应用也非常广

总的来说,easypoi 和 easyexcel 都是基于apache poi进行二次开发的。

不同点在于:

1、easypoi 在读写数据的时候,优先是先将数据写入内存,因此读写性能非常高,这种操作平时使用的时候不会出现什么问题,但是当数据量很大的时候,会出现 oom,当然它也提供了 sax 模式一行一行解析,需要自己根据当前场景来实现。

2、easyexcel 默认基于 sax 模式一行一行解析,明显降低了内存,不会出现 oom 情况,程序有过高并发场景的验证,因此整体运行比较稳定,相对于 easypoi 来说,读写性能稍慢!

3、easypoi 的 api 非常丰富,easyexcel 功能的支持,比较简单。

就小编的实际使用情况来看,easypoi 相比 easyexcel 而言,有很多的优点,尤其是他的 api 非常丰富,但是在实际使用过程中,发现在导入几千条数据的时候,有时容易发生异常,尤其是当老板使用的时候,突然蹦出这么一个异常,这个时候是没办法容忍的。

但是当改用成 easyexcel 的时候,不会出现这个问题,因此如果你经常要导入的数据量非常大,那么我推荐你使用 easyexcel。

今天,我们就以 easyexcel 框架为例,结合实际开发案例,给大家详细介绍一下 easyexcel 的使用,再下篇文章中,我们再来介绍 easypoi,可能也有理解不到位的地方,欢迎网友们批评指出!

二、程序实例

2.1、添加依赖包

&<dependency&>    &<groupId&>com.alibaba&</groupId&>    &<artifactId&>easyexcel&</artifactId&>    &<version&>2.2.6&</version&>&</dependency&>

2.2、导出 excel

easyexcel 的导出支持两种方式,一种是通过实体类注解方式来生成文件,另一种是通过动态参数化生成文件。

2.2.1、实体类注解方式生成文件

实体类注解方式生成文件,操作非常简单,只需要在对应的属性字段上添加@ExcelProperty注解,然后填写列名,配置就完成了,示例代码如下:

public class UserEntity {    @ExcelProperty(value = "姓名")    private String name;    @ExcelProperty(value = "年龄")    private int age;    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")    @ExcelProperty(value = "操作时间")    private Date time;  //set、get...}
public static void main(String&[] args) throws FileNotFoundException {    List&<UserEntity&> dataList = new ArrayList&<&>();    for (int i = 0; i &< 10; i++) {        UserEntity userEntity = new UserEntity();        userEntity.setName("张三" + i);        userEntity.setAge(20 + i);        userEntity.setTime(new Date(System.currentTimeMillis() + i));        dataList.add(userEntity);    } //定义文件输出位置    FileOutputStream outputStream = new FileOutputStream(new File("/Users/panzhi/Documents/easyexcel-export-user1.xlsx"));    EasyExcel.write(outputStream, UserEntity.class).sheet("用户信息").doWrite(dataList);}

运行程序,打开文件内容结果!

2.2.2、动态参数化生成文件

动态参数化生成文件,这种方式小编使用的比较多,基于它,我们可以封装一个公共的导出工具类,在后面会单独介绍给大家,示例代码如下:

public static void main(String&[] args) throws FileNotFoundException {    //定义表头    List&<List&<String&>&> headList = new ArrayList&<&>();    headList.add(Lists.newArrayList("姓名"));    headList.add(Lists.newArrayList("年龄"));    headList.add(Lists.newArrayList("操作时间"));    //定义数据体    List&<List&<Object&>&> dataList = new ArrayList&<&>();    for (int i = 0; i &< 10; i++) {        List&<Object&> data = new ArrayList&<&>();        data.add("张三" + i);        data.add(20 + i);        data.add(new Date(System.currentTimeMillis() + i));        dataList.add(data);    }    //定义文件输出位置    FileOutputStream outputStream = new FileOutputStream(new File("/Users/panzhi/Documents/easyexcel-export-user2.xlsx"));    EasyExcel.write(outputStream).head(headList).sheet("用户信息").doWrite(dataList);}

运行程序,打开文件内容,结果与上面一致!

2.2.3、复杂表头的生成

很多时候我们需要导出的文件,表头比较复杂,例如,我们想导出如下图这样一个复杂表头,应该如何实现呢?

如果你是使用在实体类上添加注解方式生成文件,那么可以通过如下方式来实现:

public class UserEntity {    @ExcelProperty(value = "班级")    private String className;    @ExcelProperty({"学生信息", "姓名"})    private String name;    @ExcelProperty({"学生信息", "年龄"})    private int age;    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")    @ExcelProperty({"学生信息", "入学时间"})    private Date time;  //set、get...}

其中{&“学生信息&”, &“姓名&”}这种表达式,表示在当前列,插入多行数据,第一行插入的是学生信息名称,第二行,插入的是姓名名称,因此形成多级表头!

如果你是使用的动态参数化生成文件,操作也同样类似,示例代码如下:

public static void main(String&[] args) throws FileNotFoundException {    //定义多级表头    List&<List&<String&>&> headList = new ArrayList&<&>();    headList.add(Lists.newArrayList("班级"));    headList.add(Lists.newArrayList("学生信息", "姓名"));    headList.add(Lists.newArrayList("学生信息","年龄"));    headList.add(Lists.newArrayList("学生信息","入学时间"));    //定义数据体    List&<List&<Object&>&> dataList = new ArrayList&<&>();    for (int i = 0; i &< 10; i++) {        List&<Object&> data = new ArrayList&<&>();        data.add("一年级~1班");        data.add("张三" + i);        data.add(20 + i);        data.add(new Date(System.currentTimeMillis() + i));        dataList.add(data);    }    //定义文件输出位置    FileOutputStream outputStream = new FileOutputStream(new File("/Users/panzhi/Documents/easyexcel-export-user3.xlsx"));    EasyExcel.write(outputStream).head(headList).sheet("用户信息").doWrite(dataList);}

其中Lists.newArrayList(&“学生信息&”, &“姓名&”)表达的意思跟上面一样,在当前列下插入多行,类似于:

List&<String&> list = new ArrayList&<&>();list.add("学生信息");list.add("姓名");

Lists.newArrayList编程来自于guava工具包!

2.2.4、自定义样式

在实际使用过程中,我们可能还需要针对文件做一下样式自定义,例如你想把表头设置为红色,内容设置为绿色,列宽、行宽都加大,应该如何实现呢?

操作也很简单,编写一个自定义样式类,然后在写入的时候注入进去。

/** * 自定义样式 * @return */private static HorizontalCellStyleStrategy customerStyle(){    // 头的策略    WriteCellStyle headWriteCellStyle = new WriteCellStyle();    // 背景设置为红色    headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());    WriteFont headWriteFont = new WriteFont();    headWriteFont.setFontHeightInPoints((short)20);    headWriteCellStyle.setWriteFont(headWriteFont);    // 内容的策略    WriteCellStyle contentWriteCellStyle = new WriteCellStyle();    // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定    contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);    // 背景绿色    contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());    WriteFont contentWriteFont = new WriteFont();    // 字体大小    contentWriteFont.setFontHeightInPoints((short)20);    contentWriteCellStyle.setWriteFont(contentWriteFont);    // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现    HorizontalCellStyleStrategy horizontalCellStyleStrategy =            new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);    return horizontalCellStyleStrategy;}

在写入的时候,将其注入,例如下面的动态导出:

//通过registerWriteHandler方法,将自定义的样式类注入进去EasyExcel.write(outputStream).registerWriteHandler(customerStyle()).head(headList).sheet("用户信息").doWrite(dataList);

2.3、导入 excel

easyexcel 的导入同样也支持两种方式,和上面一样,一种是通过实体类注解方式来读取文件,另一种是通过动态监听器读取文件。

2.3.1、实体类注解方式来读取文件

实体类注解方式来读取文件时,要读取的 excel 表头需要与实体类一一对应,以下面的 excel 文件为例!

通过注解方式来读取,既可以指定列的下表,也可以通过列名来映射,但是两者只能取一个。

/** * 读取实体类 */public class UserReadEntity {    @ExcelProperty(value = "姓名")    private String name;    /**     * 强制读取第三个 这里不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配     */    @ExcelProperty(index = 1)    private int age;    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")    @ExcelProperty(value = "操作时间")    private Date time;    //set、get...}
public static void main(String&[] args) throws FileNotFoundException { //同步读取文件内容    FileInputStream inputStream = new FileInputStream(new File("/Users/panzhi/Documents/easyexcel-user1.xls"));    List&<UserReadEntity&> list = EasyExcel.read(inputStream).head(UserReadEntity.class).sheet().doReadSync();    System.out.println(JSONArray.toJSONString(list));}

运行程序,输出结果如下:

&[{"age":20,"name":"张三0","time":1616920360000},{"age":21,"name":"张三1","time":1616920360000},{"age":22,"name":"张三2","time":1616920360000},{"age":23,"name":"张三3","time":1616920360000},{"age":24,"name":"张三4","time":1616920360000},{"age":25,"name":"张三5","time":1616920360000},{"age":26,"name":"张三6","time":1616920360000},{"age":27,"name":"张三7","time":1616920360000},{"age":28,"name":"张三8","time":1616920360000},{"age":29,"name":"张三9","time":1616920360000}]

2.3.2、动态监听器读取文件

动态监听器读取文件,与上面的方式有一个明显的区别是,我们需要重新写一个实现类,来监听 easyexcel 一行一行解析出来的数据,然后将数据封装出来,基于此,我们可以编写一套动态的导入工具类,详细工具类会下面介绍到,示例代码如下:

/** * 创建一个监听器,继承自AnalysisEventListener */public class UserDataListener extends AnalysisEventListener&<Map&<Integer, String&>&> {    private static final Logger LOGGER = LoggerFactory.getLogger(UserDataListener.class);    /**     * 表头数据     */    private List&<Map&<Integer, String&>&> headList = new ArrayList&<&>();    /**     * 数据体     */    private List&<Map&<Integer, String&>&> dataList = new ArrayList&<&>();    /**     * 这里会一行行的返回头     *     * @param headMap     * @param context     */    @Override    public void invokeHeadMap(Map&<Integer, String&> headMap, AnalysisContext context) {        LOGGER.info("解析到一条头数据:{}", JSON.toJSONString(headMap));        headList.add(headMap);    }    /**     * 这个每一条数据解析都会来调用     *     * @param data     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}     * @param context     */    @Override    public void invoke(Map&<Integer, String&> data, AnalysisContext context) {        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));        dataList.add(data);    }    /**     * 所有数据解析完成了 都会来调用     *     * @param context     */    @Override    public void doAfterAllAnalysed(AnalysisContext context) {        LOGGER.info("所有数据解析完成!");    }    public List&<Map&<Integer, String&>&> getHeadList() {        return headList;    }    public List&<Map&<Integer, String&>&> getDataList() {        return dataList;    }}
public static void main(String&[] args) throws FileNotFoundException {    FileInputStream inputStream = new FileInputStream(new File("/Users/panzhi/Documents/easyexcel-user1.xls"));    //初始化一个监听器    UserDataListener userDataListener = new UserDataListener();    //读取文件数据    EasyExcel.read(inputStream, userDataListener).sheet().doRead();    System.out.println("表头:" + JSONArray.toJSONString(userDataListener.getHeadList()));    System.out.println("数据体:" + JSONArray.toJSONString(userDataListener.getDataList()));}

运行程序,输出结果如下:

表头:&[{0:"姓名",1:"年龄",2:"操作时间"}]数据体:&[{0:"张三0",1:"20",2:"2021-03-28 16:32:40"},{0:"张三1",1:"21",2:"2021-03-28 16:32:40"},{0:"张三2",1:"22",2:"2021-03-28 16:32:40"},{0:"张三3",1:"23",2:"2021-03-28 16:32:40"},{0:"张三4",1:"24",2:"2021-03-28 16:32:40"},{0:"张三5",1:"25",2:"2021-03-28 16:32:40"},{0:"张三6",1:"26",2:"2021-03-28 16:32:40"},{0:"张三7",1:"27",2:"2021-03-28 16:32:40"},{0:"张三8",1:"28",2:"2021-03-28 16:32:40"},{0:"张三9",1:"29",2:"2021-03-28 16:32:40"}]

其中key表示列下表!

2.3.3、复杂表头读取

在实际的开发中,我们还会遇到复杂表头的数据读取,以如下表头为例,我们应该如何读取呢?

如果你是采用注解的方式导出的文件,同样也可以通过注解方式来读取,例如上文中,我们是使用如下实体类生成的文件,我们也可通过这个类读取文件!

public class UserEntity {    @ExcelProperty(value = "班级")    private String className;    @ExcelProperty({"学生信息", "姓名"})    private String name;    @ExcelProperty({"学生信息", "年龄"})    private int age;    @DateTimeFormat("yyyy-MM-dd HH:mm:ss")    @ExcelProperty({"学生信息", "入学时间"})    private Date time;  //set、get}
//读取文件List&<UserEntity&> list = EasyExcel.read(filePath).head(UserEntity.class).sheet().doReadSync();System.out.println(JSONArray.toJSONString(list));

读取结果如下:

&[{"age":20,"className":"一年级~1班","name":"张三0","time":1618719961000},{"age":21,"className":"一年级~1班","name":"张三1","time":1618719961000},{"age":22,"className":"一年级~1班","name":"张三2","time":1618719961000},{"age":23,"className":"一年级~1班","name":"张三3","time":1618719961000},{"age":24,"className":"一年级~1班","name":"张三4","time":1618719961000},{"age":25,"className":"一年级~1班","name":"张三5","time":1618719961000},{"age":26,"className":"一年级~1班","name":"张三6","time":1618719961000},{"age":27,"className":"一年级~1班","name":"张三7","time":1618719961000},{"age":28,"className":"一年级~1班","name":"张三8","time":1618719961000},{"age":29,"className":"一年级~1班","name":"张三9","time":1618719961000}]

如果你是使用动态参数化来生成文件,那么这个时候可以采用动态监听器的方式来读取文件,在读取的时候需要指定数据所在行,示例代码如下:

public static void main(String&[] args) throws FileNotFoundException {    FileInputStream inputStream = new FileInputStream(new File("/Users/panzhi/Documents/easyexcel-export-user4.xlsx"));    //初始化一个监听器    UserDataListener userDataListener = new UserDataListener();    //读取文件数据,指定数据所在行使用headRowNumber方法    EasyExcel.read(inputStream, userDataListener).sheet().headRowNumber(2).doRead();    System.out.println("表头:" + JSONArray.toJSONString(userDataListener.getHeadList()));    System.out.println("数据体:" + JSONArray.toJSONString(userDataListener.getDataList()));}

读取结果如下:

表头:&[{0:"班级",1:"学生信息",2:"学生信息",3:"学生信息"},{0:"班级",1:"姓名",2:"年龄",3:"入学时间"}]数据体:&[{0:"一年级~1班",1:"张三0",2:"20",3:"2021-04-18 12:26:01"},{0:"一年级~1班",1:"张三1",2:"21",3:"2021-04-18 12:26:01"},{0:"一年级~1班",1:"张三2",2:"22",3:"2021-04-18 12:26:01"},{0:"一年级~1班",1:"张三3",2:"23",3:"2021-04-18 12:26:01"},{0:"一年级~1班",1:"张三4",2:"24",3:"2021-04-18 12:26:01"},{0:"一年级~1班",1:"张三5",2:"25",3:"2021-04-18 12:26:01"},{0:"一年级~1班",1:"张三6",2:"26",3:"2021-04-18 12:26:01"},{0:"一年级~1班",1:"张三7",2:"27",3:"2021-04-18 12:26:01"},{0:"一年级~1班",1:"张三8",2:"28",3:"2021-04-18 12:26:01"},{0:"一年级~1班",1:"张三9",2:"29",3:"2021-04-18 12:26:01"}]

三、动态导出导入工具类封装

在实际使用开发中,我们不可能每来一个 excel 导入导出需求,就编写一个方法,而且很多业务需求都是动态导入导出,没办法基于实体类注解的方式来读取文件或者写入文件

因此,基于动态参数化生成文件和动态监听器读取文件方法,我们可以单独封装一套动态导出导出工具类,省的我们每次都需要重新编写大量重复工作,以下就是小编我在实际使用过程,封装出来的工具类,在此分享给大家!

动态导出工具类

public class DynamicEasyExcelExportUtils {    private static final Logger log = LoggerFactory.getLogger(DynamicEasyExcelExportUtils.class);    private static final String DEFAULT_SHEET_NAME = "sheet1";    /**     * 动态生成导出模版(单表头)     * @param headColumns 列名称     * @return            excel文件流     */    public static byte&[] exportTemplateExcelFile(List&<String&> headColumns){        List&<List&<String&>&> excelHead = Lists.newArrayList();        headColumns.forEach(columnName -&> { excelHead.add(Lists.newArrayList(columnName)); });        byte&[] stream = createExcelFile(excelHead, new ArrayList&<&>());        return stream;    }    /**     * 动态生成模版(复杂表头)     * @param excelHead   列名称     * @return     */    public static byte&[] exportTemplateExcelFileCustomHead(List&<List&<String&>&> excelHead){        byte&[] stream = createExcelFile(excelHead, new ArrayList&<&>());        return stream;    }    /**     * 动态导出文件     * @param headColumnMap  有序列头部     * @param dataList       数据体     * @return     */    public static byte&[] exportExcelFile(LinkedHashMap&<String, String&> headColumnMap, List&<Map&<String, Object&>&> dataList){        //获取列名称        List&<List&<String&>&> excelHead = new ArrayList&<&>();        if(MapUtils.isNotEmpty(headColumnMap)){            //key为匹配符,value为列名,如果多级列名用逗号隔开            headColumnMap.entrySet().forEach(entry -&> {                excelHead.add(Lists.newArrayList(entry.getValue().split(",")));            });        }        List&<List&<Object&>&> excelRows = new ArrayList&<&>();        if(MapUtils.isNotEmpty(headColumnMap) &&&& CollectionUtils.isNotEmpty(dataList)){            for (Map&<String, Object&> dataMap : dataList) {                List&<Object&> rows = new ArrayList&<&>();                headColumnMap.entrySet().forEach(headColumnEntry -&> {                    if(dataMap.containsKey(headColumnEntry.getKey())){                        Object data = dataMap.get(headColumnEntry.getKey());                        rows.add(data);                    }                });                excelRows.add(rows);            }        }        byte&[] stream = createExcelFile(excelHead, excelRows);        return stream;    }    /**     * 生成文件     * @param excelHead     * @param excelRows     * @return     */    private static byte&[] createExcelFile(List&<List&<String&>&> excelHead, List&<List&<Object&>&> excelRows){        try {            if(CollectionUtils.isNotEmpty(excelHead)){                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();                EasyExcel.write(outputStream).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())                        .head(excelHead)                        .sheet(DEFAULT_SHEET_NAME)                        .doWrite(excelRows);                return outputStream.toByteArray();            }        } catch (Exception e) {            log.error("动态生成excel文件失败,headColumns:" + JSONArray.toJSONString(excelHead) + ",excelRows:" + JSONArray.toJSONString(excelRows), e);        }        return null;    }    /**     * 导出文件测试     * @param args     * @throws IOException     */    public static void main(String&[] args) throws IOException {        //导出包含数据内容的文件        LinkedHashMap&<String, String&> headColumnMap = Maps.newLinkedHashMap();        headColumnMap.put("className","班级");        headColumnMap.put("name","学生信息,姓名");        headColumnMap.put("sex","学生信息,性别");        List&<Map&<String, Object&>&> dataList = new ArrayList&<&>();        for (int i = 0; i &< 5; i++) {            Map&<String, Object&> dataMap = Maps.newHashMap();            dataMap.put("className", "一年级");            dataMap.put("name", "张三" + i);            dataMap.put("sex", "男");            dataList.add(dataMap);        }        byte&[] stream = exportExcelFile(headColumnMap, dataList);        FileOutputStream outputStream = new FileOutputStream(new File("/Users/panzhi/Documents/easyexcel-export-user5.xlsx"));        outputStream.write(stream);        outputStream.close();    }}

动态导入工具类

/** * 创建一个监听器 */public class DynamicEasyExcelListener extends AnalysisEventListener&<Map&<Integer, String&>&> {    private static final Logger LOGGER = LoggerFactory.getLogger(UserDataListener.class);    /**     * 表头数据(存储所有的表头数据)     */    private List&<Map&<Integer, String&>&> headList = new ArrayList&<&>();    /**     * 数据体     */    private List&<Map&<Integer, String&>&> dataList = new ArrayList&<&>();    /**     * 这里会一行行的返回头     *     * @param headMap     * @param context     */    @Override    public void invokeHeadMap(Map&<Integer, String&> headMap, AnalysisContext context) {        LOGGER.info("解析到一条头数据:{}", JSON.toJSONString(headMap));        //存储全部表头数据        headList.add(headMap);    }    /**     * 这个每一条数据解析都会来调用     *     * @param data     *            one row value. Is is same as {@link AnalysisContext#readRowHolder()}     * @param context     */    @Override    public void invoke(Map&<Integer, String&> data, AnalysisContext context) {        LOGGER.info("解析到一条数据:{}", JSON.toJSONString(data));        dataList.add(data);    }    /**     * 所有数据解析完成了 都会来调用     *     * @param context     */    @Override    public void doAfterAllAnalysed(AnalysisContext context) {        // 这里也要保存数据,确保最后遗留的数据也存储到数据库        LOGGER.info("所有数据解析完成!");    }    public List&<Map&<Integer, String&>&> getHeadList() {        return headList;    }    public List&<Map&<Integer, String&>&> getDataList() {        return dataList;    }}
/** * 编写导入工具类 */public class DynamicEasyExcelImportUtils {    /**     * 动态获取全部列和数据体,默认从第一行开始解析数据     * @param stream     * @return     */    public static List&<Map&<String,String&>&> parseExcelToView(byte&[] stream) {        return parseExcelToView(stream, 1);    }    /**     * 动态获取全部列和数据体     * @param stream           excel文件流     * @param parseRowNumber   指定读取行     * @return     */    public static List&<Map&<String,String&>&> parseExcelToView(byte&[] stream, Integer parseRowNumber) {        DynamicEasyExcelListener readListener = new DynamicEasyExcelListener();        EasyExcelFactory.read(new ByteArrayInputStream(stream)).registerReadListener(readListener).headRowNumber(parseRowNumber).sheet(0).doRead();        List&<Map&<Integer, String&>&> headList = readListener.getHeadList();        if(CollectionUtils.isEmpty(headList)){            throw new RuntimeException("Excel未包含表头");        }        List&<Map&<Integer, String&>&> dataList = readListener.getDataList();        if(CollectionUtils.isEmpty(dataList)){            throw new RuntimeException("Excel未包含数据");        }        //获取头部,取最后一次解析的列头数据        Map&<Integer, String&> excelHeadIdxNameMap = headList.get(headList.size() -1);        //封装数据体        List&<Map&<String,String&>&> excelDataList = Lists.newArrayList();        for (Map&<Integer, String&> dataRow : dataList) {            Map&<String,String&> rowData = new LinkedHashMap&<&>();            excelHeadIdxNameMap.entrySet().forEach(columnHead -&> {                rowData.put(columnHead.getValue(), dataRow.get(columnHead.getKey()));            });            excelDataList.add(rowData);        }        return excelDataList;    }    /**     * 文件导入测试     * @param args     * @throws IOException     */    public static void main(String&[] args) throws IOException {        FileInputStream inputStream = new FileInputStream(new File("/Users/panzhi/Documents/easyexcel-export-user5.xlsx"));        byte&[] stream = IoUtils.toByteArray(inputStream);        List&<Map&<String,String&>&> dataList = parseExcelToView(stream, 2);        System.out.println(JSONArray.toJSONString(dataList));        inputStream.close();    }}

为了方便后续的操作流程,在解析数据的时候,会将列名作为key!

四、总结

本文主要以实际使用场景为例,对 easyexcel 的使用做了简单的介绍,尤其是动态导出导出,基于业务的需要,做了一个公共的工具类,方便后续进行快速开发,避免重复的劳动!

当然,easyexcel 的功能还不只上面介绍的那些内容,还有基于模版进行excel的填充,web 端restful的导出导出,使用方法大致都差不多,具体可以参与官方的文档,地址如下:https://www.yuque.com/easyexcel/doc/read#1bfaf593

最后,希望本文对大家有所帮助!

“java实现excel导入(java批量导入excel数据)” 的相关文章

如何预防ddos攻击,网站防ddos攻击有效措施

DDoS可以说在互联网界大名鼎鼎,也可以直言说是臭名昭著,随着DDoS攻击的范围越来越广泛,网站的安全也就变得更加重要。我们在预防DDoS攻击前,可以先来了解一...

家用投影仪排行榜,2019家用投影仪评测

在大家的印象里,开会所用到的投影仪场景是什么样的呢?嗯,首先,就是寻找各种线材,接驳,繁琐调试,拔了又插,插了又试。不仅麻烦,而且还严重影响了工作效率,比如苹果...

天梭机械表怎么样(五千以内档次最高的一款机械表)

天梭1853年诞生于手表制造业的摇篮——瑞士,属于瑞士中档手表之一。凭借在传统中不断创新的精神,如今,天梭表的已遍布全球五大洲超过150多个国家,并屡次获得国际...

2020电脑音箱什么牌子最好(2020年口碑最好的3款电脑音

无论你是在看电影,听音乐,还是在玩游戏,对于音效来说都是非常重要的,一款好音效的音箱能给你带来享受,所以消费者对于桌面音箱的要求越来越高,其实现在的高品质桌面音...

品牌公关具体要做些什么,品牌公关入门指南

品牌是一个企业的软实力体现,对于企业的市场竞争力起着非常大的作用,创建品牌是每个企业都重视的一步。品牌是一个企业发展的灵魂,它可以为企业带来长远的增值和溢价。作...

儿童手表排名(十大儿童手表品牌最值入手一款测评)

为了可以随时确定孩子的位置,及时与孩子联系,也是出于为孩子的安全着想,越来越多的家长会给孩子佩戴儿童电话手表,不过面对市面上各式各样的儿童手表,很多家长都不知道...

如何做品牌运营与推广(解说品牌推广运营新攻略)

如何通过品牌运营推广提高企业的品牌形象推广?【发软文用TM媒介】假如一家公司建立了自己的品牌,并且非常重视品牌形象,那么就需要进行品牌运作推广,品牌运作推广是一...

如何计算增长率百分比(今年和去年比增长率计算方法)

甘肃公务员考试公共笔试科目为《行政职业能力测验》和《申论》两科,其中行政职业能力测试主要测查与公务员职业密切相关的、适合客观化纸笔测验方式进行考查的基本素质和...

屏保软件哪个好(自己做锁屏壁纸的软件)

机哥不得不说,现在手机出厂自带的壁纸,都蛮有意思的。像小米MIUI12的超级壁纸,用一套动画打通了锁屏和主屏幕,可以在这些界面里无缝切换。而vivoOrigin...

如何搜索微信文章,快速搜索微信文章的方法

有时候在微信公众号上看到感兴趣的文章,等哪天突然想起来却又找不到的时候,最是急死人,那么微信公众号怎么找文章,微信公众号内容搜索方法有哪些?拓途数据带你一起去了...