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

看完本文,你一定会有所收获 一、介绍 在上篇文章中,我们简单的介绍了excel导入导出技术实践方案,就目前而已,使用最多的开源框架主要有以下三类,分别是: apachepoi:poi是使用最广的一种导入导出框架,但是缺点也很明显,导出大数据量的时候,容易oomeasypoi:easypoi的底层也是基于apachepoi进行深度开发的,它主要的特点就是将更多重复的工作,全部简单化,避免编写重复的代…

Java不固定列excel导入导出

看了文中,你一定会有些获得

一、详细介绍

在上一篇文章中,大家简便的讲解了 excel 导入导出技术性实践活动计划方案,就现阶段罢了,应用较多的开源框架关键有下面三类,分别是:

  • apache poi:poi是应用较广的一种导入导出架构,可是缺陷也很显著,导出来大数据量的情况下,非常容易oom
  • easypoi: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);
}

运作程序流程,打开文件內容結果!

Java不固定列excel导入导出

2.2.2、动态性主要参数化生成文档

动态性主要参数化生成文档,这类方法我采用的比较多,根据它,我们可以封装形式一个公共性的导出来java工具,在后面会直接详细介绍给大伙儿,实例编码如下所示:

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

运作程序流程,打开文件內容,結果与上边一致!

Java不固定列excel导入导出

2.2.3、繁杂表头的转化成

许多情况下人们必须导出来的文档,表头比较复杂,例如,大家想导出来如下图那样一个繁杂表头,应当怎么完成呢?

Java不固定列excel导入导出

如果你是应用在实体类上加上注释方法转化成文档,那麼可以借助以下方法来完成:

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、自定款式

在具体运用全过程中,大家也许还要对于文档做一下款式自定,例如你要把表头设定为鲜红色,內容设定为翠绿色,列宽、行宽都增加,应当怎么完成呢?

Java不固定列excel导入导出

实际操作也非常简单,撰写一个自定款式类,随后在载入的情况下引入进来。

/**
 * 自定款式
 * @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 文档为例子!

Java不固定列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 一行一行分析出的数据信息,随后将数据信息封装形式出去,根据此,我们可以撰写一套动态性的导进java工具,详尽java工具会下边详细介绍到,实例编码如下所示:

/**
 * 建立一个窃听器,承继自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、繁杂表头载入

在具体的研发中,大家还会继续碰到繁杂表头的信息载入,以如下所示表头为例子,大家应当怎样载入呢?

Java不固定列excel导入导出

如果你是选用注释的方法导出来的文档,一样还可以根据注释方法来载入,例如上原文中,我们都是应用如下所示实体类转化成的文档,大家也可利用这一类读取文件!

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;
    }
}
/**
 * 撰写导进java工具
 */
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 的应用干了简易的详细介绍,尤其是动态性导出来导出,根据业务流程的必须,干了一个公共性的java工具,便捷后面开展快速开发,防止反复的工作!

自然,easyexcel 的作用还不只上边讲解的这些內容,也有根据模板开展excel的添充,web 端restful的导出来导出,操作方法大概都类似,实际可以参加官方网的文本文档,详细地址如下所示:https://www.yuque.com/easyexcel/doc/read#1bfaf593

最终,期待这篇文章对我们有些协助!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

(0)
上一篇 2022年5月2日 下午1:24
下一篇 2022年5月2日 下午1:26

相关推荐

  • 创业成功故事分享,季琦的创业历程及感悟

    出身低微的农民大学生季琦,乡下小孩进城,生存和生活有太多困难,这些困难并没有压倒他。他靠自己的努力,一步一步走上成功路。 先来看季琦传奇创业故事 1966年10月出生; 1992年3月毕业于上海交通大学机械工程系机器人硕士专业; 1999年与梁建章、沈南鹏、范敏共同创建携程旅行网,出任总裁。2003年12月携程在纳斯达克上市,今天的市值将近60亿美元。 2002年创办如家连锁酒店,出任CEO。 2…

    2022年5月20日
    730
  • 2019版注册商标分类表,商标注册45类范围明细

    注册商标的时候都是要确定具体的产品或服务的,目前我国商标分类是用《类似商品和服务区分表–基于尼斯分类第十一版》2019年版这本分类书。这本分类表也是全球通用的分类表,商标分类总共有45个类别,1-34类是产品类、35-45类是服务类。这45个大类里面包含了各行各业,每个大类里面也有不同的小组。每个小组下面就有具体的产品(服务项目),这些项目有的会根据不同的国家会根据自己国内的称呼习惯会做变化。 …

    2022年6月1日
    890
  • 在线音频转成文字怎么实现,免费语音转文字软件分享

    我觉得开会不是最烦人的,最烦的是会后要整理会议记录给老板。虽然为了避免遗漏重要内容,我把老板的讲话都录下来。但核对长达1个多小时的录音文件内容,并不那么轻松,我要反复听好几遍才能记录成文字。 要是有一款工具可以把录音直接转换成文字内容就好了!隔壁的小姐姐听到我的抱怨,就给我推了一个APP录音转文字助手,我抱着试试看的心理,没想到会议记录整理难题立马迎刃而解。所以我忍不住来和大家分享这个办公神器。 …

    2022年6月9日
    1140
  • 商标网上申请流程,商标网上申请怎么拿到

    近期,据媒体报道,自2月1日起,将商标网上申请的接收时间由“08:00至16:30”延长为“08:00至20:00”,系统开放日为法定工作日、节假日。据媒体报道,我国注册商标过500万,北京注册商标数量全国第三,商标注册数量的上涨,一是由于商标注册官费的下调,二是网上商标注册便利的商标注册的程序,北京为了鼓励企业注册商标,规定认证北京市著名商标的企业最高可获50万元奖励,那么北京网上商标注册流程是…

    2022年7月2日
    1000
  • 共享充电宝的商业模式是否可行,共享充电宝盈利状况分析

    “看的懂的叫套路,看不懂的叫谋略”,顶尖高手,把它们叫谋略,研究它们,使用它们;普通的人,把它们叫套路,讨厌它们,排斥它们。我是老阚,如果你想了解更多的营销实例和生活套路,阅读本文前请点击上方关注我。 之前分享过一篇文章,讲到了一个新的共享风口,充电宝,很多小伙伴看了之后给我留言,让我具体再讲讲关于共享充电宝的一些事,那今天我们就来继续聊聊共享充电宝这个话题。10天赚了3个亿,是人傻钱多,还是又有…

    2022年6月1日
    670
  • 怎么创建小程序商店(6个免费制作微信小程序的平台)

    知晓程序 网址:https://minapp.com/miniapp/ 知晓程序,提供微信小程序开发资讯,解读微信小程序开发文档,制作微信小程序开发教程。国内第一家微信小程序商店/应用市场/应用商店。 微信小程序大全 网址:http://www.duba.com/wxapp/ 猎豹移动旗下小程序应用商店,及时收录各种分类的优秀小程序,提供最简单便捷的小程序导航及排名。 追格 网址:http://x…

    2022年6月1日
    920
  • viewsonic显示器怎么样(优派显示器开箱评测)

    为抢占更多电竞游戏玩家市场,今天ViewSonic(优派)发布了一款小尺寸电竞屏——XG240R,主打性价比,虽然只有24英寸1080p分辨率,但具有144Hz高刷新率,1ms急速相应,还支持AMDFreeSync“防撕裂”技术以及暗黑稳定器等功能,适合主流游戏玩家选择,尤其是FPS高速动态的游戏玩家。 XG240R定位电竞游戏级,因此外观设计格外用心,最大亮点是背后还集成RGB幻彩氛围灯,是目前…

    2022年10月23日
    430
  • 苹果投影到电脑上需要怎么弄,史上最详细教程

    在苹果的iPhone和iPad上有一个屏幕镜像功能,可以把iPhone或iPad上的屏幕实时投送到电脑屏幕上。在这里为大家介绍一下具体的操作方法。 投屏基本操作 首先在电脑上要安装一个用于屏幕镜像的软件。小编这里以自己一直使用的一款名为「AirServer」为例,为大家介绍下具体的操作方法。 如图所示,小编在Mac电脑上已经运行了可以让iPhone或iPad投屏的AirServer应用。 这里以i…

    2022年9月24日
    500
  • 澳门科技大学怎么样啊,听听一个在校大学生的真实回答

    又到了一年报志愿的时间,我把结论写在前面吧。科大性价比很低,仅适合家庭经济条件优越的,高考分数有一定欠缺的考生。 能上正儿八经211的,别来。家里砸锅卖铁供你在澳门省吃俭用的,别来。 说学校排名的,你们只需要回答我一个问题。为什么有且只有在那个所谓的两岸四地里面,澳大排名比科大低?澳大好还是科大好相信任何在澳门读过大学的人心里自有判断。 说好听点就是用高额研究资金吸引了一批知名教授学者。说难听点就…

    2022年9月28日
    450
  • 文网文是什么意思,其办理流程详解

    现如今,越来越多的游戏直播玩家凭借其精湛的游戏技术,在一些直播平台将游戏直播进行的有声有色,受很多普通玩家的追捧,王者荣耀,英雄联盟,绝地求生,这些游戏的高端操作让人欲罢不能,备受追捧,法师、刺客、射手等的游戏策略更是数不胜数。 我们也不难发现,网络游戏在人们的生活变得更加重要,现代生生活的各种压力使得很多在游戏中寻求放松,越来越多的游戏开发商发现了游戏的商机,不断有新的游戏被开发出来。游戏的增多…

    2022年6月1日
    770

发表回复

登录后才能评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信