最近公司需求解析excel,一开始使用poi做的挺好的,后来直接上了几十万条数据的excel文件,内存直接溢出了,网上查到apache poi还提供了专门处理海量数据的方法,使用sax解析,果然用了内存使用率下降,但是不能解析xls文件,只能解析xlsx文件,所以把工具简单封装了一下,如果是xls的用传统方式解析,如果是xlsx的大文件,用sax,这样灵活一定,详见md文件

(建议前往github查看最新内容)

https://github.com/hellojamie/ebatis  下载项目源码

https://gitee.com/hellojamie/ebatis

Ebatis

用于解析excel表格内容到 java bean 目前支持xls、xlsx格式文件 对于大数据量文件自动使用sax方式解析,防止内存溢出

目录(记得看注意):

  1. 开始
  2. 扩展功能
  3. 注意

开始

因为经常有改动,需要手动打包发布

// Maven导入第三方poi依赖,或者直接把master pull下来发布到本地
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.9.1</version>
</dependency>

  

首先你需要创建好你的实体类,假设现在有这样一个excel表格需要解析

姓名 手机号 生日
王文娟 18888888888 1996-01-01
大美丽 16666666666 1996-01-01

首先你需要一个实体类 有几点要求,必须正确封装,包含get\set方法 属性上包含必要的Mapping注解,key属性填入与表格对应的名称,属性类型根据需要自己定义

package cc.ebatis.controller;

import java.io.File;

import cc.ebatis.bean.People;
import cc.ebatis.impl.Init;
import cc.ebatis.pojo.ActionContext; public class Test {
public static void main(String[] args) {
File file = new File("c://Users//Pei//Desktop//pei.xlsx");
Init<People> init = new Init<People>(file, People.class, false);
System.out.println("init===="+init);
ActionContext<People> act = init.start();
System.out.println("act===="+act);
} }

  

package cc.ebatis.bean;

import java.util.Date;

import cc.ebatis.annotation.Mapping;

public class People {
@Mapping(key = "姓名")
private String name; @Mapping(key = "手机号")
private String phone; @Mapping(key = "生日")
private Date birth; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getPhone() {
return phone;
} public void setPhone(String phone) {
this.phone = phone;
} public Date getBirth() {
return birth;
} public void setBirth(Date birth) {
this.birth = birth;
} @Override
public String toString() {
return "People [name=" + name + ", phone=" + phone + ", birth=" + birth + "]";
} }

  

  然后将你的文档以流的方式加载进来,通过以下代码开始解析

// Init接受一个InputStream对象,以及一个实体对象
// 调用start开始
// 通过ActionContext获取需要的信息
// 参数依次为-文件-实体class-是否去重
File file = new File("excel.xlsx");
Init<ExcelPojo> init = new Init<ExcelPojo>(file, ExcelPojo.class, false);
ActionContext<ExcelPojo> act = init.start();

  (注意:如果要去重的话请重写实体中的hashCode和equals方法,内部使用set来去重,false表示不去重) ActionContext中包含了所需要的所有信息,信息格式如下,这里以json的形式展示

{
  "sheets":[
    {
      "line":5,
"sheetName":"Sheet1",
"column":6,
"correctLine":5,
"blankLineSize":0,
"errorLineSize":0,
"repeatLineSize":0,
      "info":[
        {
          "date":1331481600000,
          "name":"王文娟",
          "phone":"15035214458"
        },
        {
          "date":1331481600000,
          "name":"大美丽",
          "phone":"14555874458"
        }
      ],
      "blankLine":[],
"errorLine":[],
"repeatLine":[]
    }
  ],
  "fileType":"XLSX",
"SheetSize":1,
"fileSizeByte":9138,
"useSax":true,
"distinct":false,
"result":true
}

  

属性名 含义
sheets sheet数组
line 解析当前sheet一共多少行数据,不算表头
sheetName sheet的名称
column 列数
info 实体对象数组,包含实体的列表,也就是行数据
correctLine 实际正确解析出的数量(行数)
blankLineSize 空行的数量
errorLineSize 错误行的数量,包括正则不通过被删除的
repeatLineSize 重复行的数量
fileType 文件类型
blankLine 空白行的行号-数组
errorLine 错误行的行号-数组
repeatLine 重复行的行号-数组
fileSizeByte 文件大小(字节)
useSax 是否使用了sax方式
distinct 是否去重
result 最后是否解析成功,如果中间出错则是false
sheetSize 文件中有几个sheet
useSax 是否使用sax解析,即是否解析的是xlsx文件
distinct 是否去重

使用ActionContext的getXXX方法获取上面的内容

扩展功能

@Mapping注解有三个非必选属性

  1.  
    @Mapping(key = "手机号", rex = "^[0-9]{11}$", delNull = true, length = 11)
  2.  
    private String phone;
属性名 含义 是否必填
key 填写与excel文件头的映射名称 必填
rex 填写解析内容时使用的正则表达式,如果不符合正则则不赋值 非必填
delNull 如果该属性为null的话,是否删除整条信息,默认false不删除 非必填
length 填写提取内容的最大长度,默认不限制 非必填

@LineNumber注解,获取当前记录是第几行,不算表头那行

  1.  
    @LineNumber
  2.  
    private Integer line;

@MappingSheetName注解,将sheet名称作为属性值添加

  1.  
    @MappingSheetName
  2.  
    private String type;

注意

  • 解析xlsx大文件的时候,POI本身会占据较大内存,例如100W行15列,POI自身将消耗400M+的内存,加上解析出来的内容会大于这个值,以100W为例大概需要700M+内存
  • 实体中请使用包装类,不支持int等类型,请使用Integer
  • 列与列之间不能包含表头为空的列,即不能有空列将信息隔开,如果有,以空列前一列为末尾解析
  • excel文件请使用第一行表头,其余行信息的标准格式,如果有合并单元格情况,可能会解析失败(可以包含空行和空单元格,会自动过滤,但必须有表头)
  • 实体类的属性不严格要求与列的数量一致,根据需要添加映射注解即可
  • 实体类 的属性和表头的顺序没有严格要求,只要key匹配即可
  • 如果需要去重,请重写实体的hashCode和equals方法,内部使用HashSet方式去重,重写时请注意
  • 最后是否解析成功请以result属性为准

java解析导入excel表格转为实体类javabean,根据实体类中的中文名称的更多相关文章

  1. Java解析导入Excel文件后台代码实现

    使用MultipartFile上传Excel文件后端代码实现:(springmvc下的spring-webmvc (MultipartFile )上传) 由于POST一个包含文件上传的Form会以mu ...

  2. 在java poi导入Excel通用工具类示例详解

    转: 在java poi导入Excel通用工具类示例详解 更新时间:2017年09月10日 14:21:36   作者:daochuwenziyao   我要评论   这篇文章主要给大家介绍了关于在j ...

  3. java数据库导入excel数据

    导入数据会将表格分为xls和xlsx两种格式,网上有很多案例 1.excel数据表中的数据不全,数据库中又是必填选项:---从sql语句入手:判断有无 来改变语句 //设置可有可无 字段 加一个必有字 ...

  4. VLOOKUP函数将一个excel表格的数据匹配到另一个表中

    sklearn实战-乳腺癌细胞数据挖掘(博主亲自录制视频) https://study.163.com/course/introduction.htm?courseId=1005269003& ...

  5. 使用Excel表格的记录单功能轻松处理工作表中数据的方法

    使用Excel表格的记录单功能轻松处理工作表中数据的方法 记录单是将一条记录分别存储在同一行的几个单元格中,在同一列中分别存储所有记录的相似信息段.使用记录单功能可以轻松地对工作表中的数据进行查看.查 ...

  6. java导入Excel表格数据

    首先导入Excel数据需要几样东西 第一需要两个依赖包,这里直接是在pom注入依赖 <!--excel--> <dependency> <groupId>org.a ...

  7. 使用SqlBulkCopy类实现导入excel表格

    前言: 上篇博客介绍了SqlBulkCopy类批量操作数据库的相关操作,最后提到了可以使用这个类实现excel文件导入数据库,接下来我做简单介绍. 首先说一下思路: 把excel中的数据读出来并放入到 ...

  8. 在java中实现数据导入excel表格中

    1.首先前端代码如下: 一个导出按钮:<input id="export" class="btn btn-primary" type="butt ...

  9. java之导入excel

    接口: /** * * Description: 导入excel表 * @param map * @param request * @param session * @return * @author ...

随机推荐

  1. 如何有效恢复误删的HDFS文件

    HDFS是大数据领域比较知名的分布式存储系统,作为大数据相关从业人员,每天处理HDFS上的文件数据是常规操作.这就容易带来一个问题,实际操作中对重要数据文件的误删,那么如何恢复这些文件,就显得尤为重要 ...

  2. golang 自学系列(四)——debug for vscode

    golang 自学系列(四)--(调试)VSCode For Debug 这里如何装 vscode 我就不说了 这里如何在 vscode 正常写代码我也不说了 在能正常用 vscode 写 go 语言 ...

  3. NDK&JNI开发总结

    NDK&JNI开发总结 简介 附个不错的博客 https://www.jianshu.com/p/87ce6f565d37 在Android Framework中,需要提供一种媒介或 桥梁,将 ...

  4. vue--axios分装

    封装: import axios from 'axios' axios.defaults.baseURL="http://127.0.0.1:8000/" axios.defaul ...

  5. Python中判断字符串是否为数字、字母、标识符、浮点数、大小写、可打印的方法

    1.判断s是否都是大写字母:s.isupper(): 2.判断s是否都是小写字母:s.islower(): 3.判断s中的每个单词首字母是否都是大写字母且其他位置无大写字母:s.istitle(),要 ...

  6. 云服务器AWD平台搭建

    开学后实验室来了几个新同学,在线上CTF方面大家一直在持续学习,但AWD模式的CTF我们练习并不多,所以准备搭建一个AWD平台用于实验室成员的线下赛攻防练习. 最开始的是防灾科技大学的线下AWD靶场: ...

  7. [BJDCTF2020]Cookie is so stable && [GWCTF 2019]枯燥的抽奖

    [BJDCTF2020]Cookie is so stable 进入环境后看到有hint,点击之后查看源代码 提示我们cookie有线索 flag页面是: 需要输入一个username,或许这道题目是 ...

  8. DVWA SQL Injection LOW

    最近在学习SQL注入,初出茅庐,就从dvwa开始吧 sql注入可以通过sqlmap工具实现,为了更好地了解原理,这里主要是手工注入 注入的一般流程为: 1,找到注入点,此步骤可通过工具 2,判断注入类 ...

  9. typora字体与字体颜色

    字体 基本格式:\字体信息{内容} 罗马体\rm \rm{罗马体abc}>>\(\rm{罗马体abc}\) 意大利体\it \it{意大利体}>>\(\it{意大利体}\) 等 ...

  10. 学习笔记:Link Cut Tree

    模板题 原理 类似树链剖分对重儿子/长儿子剖分,Link Cut Tree 也做的是类似的链剖分. 每个节点选出 \(0 / 1\) 个儿子作为实儿子,剩下是虚儿子.对应的边是实边/虚边,虚实时可以进 ...