【JAVA】poi 解析 Excel 表格 -- 批量导入数据

1.简要概述 😵

授人以鱼不如授人以渔,学习这个我也是花了很多时间查询资料和学习,此文章仅代表个人的看法和立场,若有错误请评论指出交流,为了照顾新手也能看懂教程,所有教程会有的啰嗦

目前市场上流行的对于 excel 处理的框架大致有两种:poijxl。对于这两种框架,我们可以做一个简单的对比:

  1. 开发团队:poi 是 Apache 旗下的一个开源项目,由 Apache 官方维护,jxl 好像是一个个人维护的开源项目。
  2. 各自优点:poi 对公式支持较好,jxl 不算好 。jxl 提供对图片的支持(仅仅 PNG 格式),poi 不支持。(就这一条来看数据处理就该选 poi,而媒体类的处理就该选 jxl 了)
  3. 内存消耗:由于 jxl 在对资源回收利用方面做了相当的功课,在内存消耗上 jxl 是略胜于 poi 的。所以对于大数据量的软件导入来说,选择 jxl 是比较合算的,当然数据量小的基本没有差别。
  4. 运行速度: 估计是内存消耗多的缘故,poi 对于读写速度这一功能做的好像比 jxl 好了不少,并且支持压缩 excel。

总结:对比了这么多,对于自己项目该使用哪个框架,应该也十分明显了(当然这些也都是从网上搜集来的,不保证有错误的地方)。

tips:这里我记录一下 poi 的使用吧,都挺简单的,基本原理都是将 excel 表格数据提取出来组成一个 list。然后对应这个 list 自己去做循环对应自己数据表的数据就行了。需要说明的一点是如果是数字类型的话,读出来的数据一般都是以 double 类型返回给你的,比如你在 excel 里面写的是 100,读取出来的数据就是 100.0。这点比较烦人,当然自己做一下处理就好了。

 扫VX 领Java资料,前端,测试,python等等资料都有

2.学习开始 😘

poi 也有两个不同的 jar 包,分别是处理 excel2003 和 excel2007+ 的,对应的是 poipoi-ooxml。毕竟 poi-ooxml 是 poi 的升级版本,处理的单页数据量也是百万级别的,所以我们选择的也是 poi-ooxml。好了,下面就贴上代码吧,注释较多,就不多做啰嗦了。前提是引入包:

<!--引入poi-->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>3.17</version>
</dependency>

核心类&语法:

 
//读取文件流的方式写入Workbook对象中,此处file为导入的Excel文件
Workbook workbook = WorkbookFactory.create(file.getInputStream());

这样我们就拿到了 Excel 表格数据了,接下来无脑遍历出来写入对象即可,为了方便理解,我这假设表格数据为:

idnameage
1张三18
2李四24

遂我们的 entity 实体类就是:

 
@Data
public class User{
    private Long id
    private String name;
    private int age;
}

tips:上面代码中 @Data 是 lombok 的依赖,若没有请自行添加对应的 set、get 方法

接着说回 Workbook,我们先了解一下 Excel 表的结构再进行遍历,这样思路会清晰很多!Excel 表是由多个工作簿 Sheet 组成,我们打开 Excel 就可以看到:

gzb.png

274 x 244

每一张工作簿 Sheet 是由每一行 Row 组成,每一行 Row 是由每一列 Cell 组成

得知:Wrokbook>Sheet>Row>Cell

遂我们遍历出来代码即是:👇

 扫VX 领Java资料,前端,测试,python等等资料都有

//循环工作簿
for (int numSheet = 0; numSheet < workbook.getNumberOfSheets(); numSheet++) {
	Sheet hssfSheet = workbook.getSheetAt(numSheet);//每一个工作簿
	if (hssfSheet == null) {
        	continue;
        }
	List<User> lists=new ArrayList()<>;
	//循环行
	for (int rowNum = 0; rowNum <= hssfSheet.getLastRowNum(); rowNum++) {
		Row hssfRow = hssfSheet.getRow(rowNum);//每一行
		if (hssfRow== null) {
        		continue;
        	}
		User user=new User();
		//循环列
		for (int cellNum = 0; cellNum < hssfRow.getLastCellNum(); cellNum++) {
			Cell hssCell = hssfRow.getCell(cellNum);//每一列
			if (hssCell== null) {
        			continue;
        		}
			String cellVal = getCellVal(hssCell);
			//此处的getCellVal方法下面马上有讲到
			System.out.println("第"+numSheet+"张工作簿,第"+rowNum+"行,第"+cellNum+"列的数据为"+cellVal);
			user.setId(Double.valueOf(cellVal).longValue());
			user.setName(cellVal);
			user.setAge(Double.valueOf(cellVal).intValue());
		}
		lists.add(user);
	}
	System.out.println("第"+numSheet+"张工作簿的数据为"+lists);
}

因为每一列里面的数据类型是不一样的,所有我封装了一个 getCellVal 方法,将 cell 传递过去,返回对应值的字符串。代码贴上:👇

 
public static String getCellVal(Cell cel) {
        if(cel.getCellType() == Cell.CELL_TYPE_STRING) {
            return cel.getRichStringCellValue().getString();
        }
        if(cel.getCellType() == Cell.CELL_TYPE_NUMERIC) {
            return cel.getNumericCellValue() + "";
        }
        if(cel.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
            return cel.getBooleanCellValue() + "";
        }
        if(cel.getCellType() == Cell.CELL_TYPE_FORMULA) {
            return cel.getCellFormula() + "";
        }
        return cel.toString();
}

我们拿到了 list 数据之后就可以进行批量添加数据到数据库啦,我这里使用的是 mybatis 的方式,其他方式大同小异,自行研究。贴上代码:👇

 
<!--mapper-->
<insert id="addUserList" parameterType="java.util.List">
        insert into user
        (
        id,
        name,
        age
        )
        values
        <foreach collection="lists" item="item" index="index" separator=",">
            (
            #{item.id},
            #{item.name},
            #{item.age}
            )
        </foreach>
</insert>

//dao
int addUserList(@Param("lists")List<User> lists);

调用一下就能批量存入数据库啦

3.总结,撒花 😍

了解 poi 解析 Excel 格式 Wrokbook>Sheet>Row>Cell,利用 Mybatis 批量添加即可

 扫VX 领Java资料,前端,测试,python等等资料都有

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值