【JAVA】poi 解析 Excel 表格--批量导入数据
目录
- 简要概述 😵
- 学习开始 😘
- 完结撒花 😍
1.简要概述 😵
授人以鱼不如授人以渔,学习这个我也是花了很多时间查询资料和学习,此文章仅代表个人的看法和立场,若有错误请评论指出交流,为了照顾新手也能看懂教程,所有教程会有的啰嗦
目前市场上流行的对于 excel 处理的框架大致有两种:poi 和 jxl。对于这两种框架,我们可以做一个简单的对比:
- 开发团队:poi 是 Apache 旗下的一个开源项目,由 Apache 官方维护,jxl 好像是一个个人维护的开源项目。
- 各自优点:poi 对公式支持较好,jxl 不算好 。jxl 提供对图片的支持(仅仅 PNG 格式),poi 不支持。(就这一条来看数据处理就该选 poi,而媒体类的处理就该选 jxl 了)
- 内存消耗:由于 jxl 在对资源回收利用方面做了相当的功课,在内存消耗上 jxl 是略胜于 poi 的。所以对于大数据量的软件导入来说,选择 jxl 是比较合算的,当然数据量小的基本没有差别。
- 运行速度: 估计是内存消耗多的缘故,poi 对于读写速度这一功能做的好像比 jxl 好了不少,并且支持压缩 excel。
总结:对比了这么多,对于自己项目该使用哪个框架,应该也十分明显了(当然这些也都是从网上搜集来的,不保证有错误的地方)。
tips:这里我记录一下 poi 的使用吧,都挺简单的,基本原理都是将 excel 表格数据提取出来组成一个 list。然后对应这个 list 自己去做循环对应自己数据表的数据就行了。需要说明的一点是如果是数字类型的话,读出来的数据一般都是以 double 类型返回给你的,比如你在 excel 里面写的是 100,读取出来的数据就是 100.0。这点比较烦人,当然自己做一下处理就好了。
2.学习开始 😘
poi 也有两个不同的 jar 包,分别是处理 excel2003 和 excel2007+ 的,对应的是 poi 和 poi-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 表格数据了,接下来无脑遍历出来写入对象即可,为了方便理解,我这假设表格数据为:
id | name | age |
---|---|---|
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 就可以看到:
每一张工作簿 Sheet 是由每一行 Row 组成,每一行 Row 是由每一列 Cell 组成
得知:Wrokbook>Sheet>Row>Cell✌
遂我们遍历出来代码即是:👇
//循环工作簿
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 批量添加即可
tips: 本博客具有一定时效性,看博客时请应先查看博客发布时间,若时间久远可能不适用!本博客仅由年华的个人学习心得写出,不具有权威教学,若有错误请评论指出!
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于