java实现批量导入Excel表格数据到数据库
作者:Ytcker 发布时间:2024-01-19 13:16:58
标签:java,批量导入,Excel
本文是基于Apache poi类实现的批量导入读取Excel文件,所以要先引入Apache poi的依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.1</version>
</dependency>
在引入依赖之后,我们就可以开始进行操作了,首先,导入Excel数据,我们要先能够读取Excel每一行每一列的内容,只有读取到内容了,才可以将内容存入数组,最后实现插入数据库。所以我们要先读取Excel表格的数据,我的项目是springboot,我在service定义了一个读取方法,然后在impl里面进行实现,具体代码为
public class ImportOrderDTO {
private String filePath;
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
}
/**
* 读取导入数据 excel 内容
*
* @param importOrderDTO 导入参数
* @param rootPath 根路径
* @return result
*/
public static final String SEPA = File.separator;//这是下面用到的常量,自己放好位置
private List<User> readExcel(ImportOrderDTO importOrderDTO, String rootPath) {
List<User> excelContent = new ArrayList<>();
try {
InputStream inputStream = new FileInputStream(rootPath + SEPA + importOrderDTO.getFilePath());
XSSFWorkbook wb = new XSSFWorkbook(inputStream);
//遍历所有表,只支持xlsx,xls的是H的类
XSSFSheet xssfSheet = wb.getSheetAt(0);
int lastRowNum = xssfSheet.getLastRowNum();
for (int i = 0; i <= lastRowNum; i++) {
// 通过下标获取行
XSSFRow row = xssfSheet.getRow(i);
// 从行中获取数据
if (row.getRowNum() == 0) {
continue;
}
//第一列为空就跳出
if (row.getCell(0) == null) {
continue;
}
/**
* getNumericCellValue() 获取数字
* getStringCellValue 获取String,设置表格类型为String,可以避免很多问题
*/
row.getCell(0).setCellType(CellType.STRING);
row.getCell(1).setCellType(CellType.STRING);
row.getCell(3).setCellType(CellType.STRING);
row.getCell(5).setCellType(CellType.STRING);
//UserInformPO是我自己定义的数据类,你们导入需要哪些数据就封装哪些,这就不用多讲了吧
UserInformPO userInformPO = new UserInformPO();
userInformPO.setAccount(row.getCell(0).getStringCellValue());
userInformPO.setIdCard(row.getCell(1).getStringCellValue());
userInformPO.setAvatar(row.getCell(2).getStringCellValue());
userInformPO.setNickname(row.getCell(3).getStringCellValue());
userInformPO.setSex(row.getCell(4).getStringCellValue());
String salt = EncryptUtils.createSalt();
userInformPO.setSalt(salt);
//职业类别
userInformPO.setIntegral(0);
userInformPO.setVipLevel(0);
userInformPO.setIsEnabled(0);
userInformPO.setDelFlag(0);
//然后将po转到我的实体类entity里面并将实体类加入到数组,方便正式执行批量导入的时候可以用,一些没有的类是我自己定义的加密的(规范)
User user = new User();
if (userInformPO.getSex().equals(SexEnum.MAN.getText())) {
user.setSex(SexEnum.MAN.getValue());
} else {
user.setSex(SexEnum.WOMAN.getValue());
}
user.setAccount(userInformPO.getAccount());
user.setIdCard(userInformPO.getIdCard());
user.setAvatar(userInformPO.getAvatar());
user.setNickname(userInformPO.getNickname());
user.setPassword(userInformPO.getPassword());
user.setSalt(userInformPO.getSalt());
user.setIntegral(userInformPO.getIntegral());
user.setVipLevel(userInformPO.getVipLevel());
user.setDepartmentId(31);
user.setIsEnabled(userInformPO.getIsEnabled());
user.setDelFlag(userInformPO.getDelFlag());
user.setUpdateTime(new Timestamp(System.currentTimeMillis()));
user.setCreateTime(new Timestamp(System.currentTimeMillis()));
//加入到数组中并且该方法返回该数组
excelContent.add(user);
}
} catch (FileNotFoundException e) {
throw new ServerException("文件不存在");
} catch (IOException e) {
System.out.println(e);
throw new ServerException("读取文件失败");
}
return excelContent;
}
在上面写完读取Excel表单数据后,就可以开始写插入数据库的方法了,我用的是mybatis plus ,方法直接写到下面,大家不会陌生,返回方法是我封装的类,大家用自己项目的稍加修改就可以
public Result importUserWithExcel(ImportOrderDTO importOrderDTO, String rootPath) {
try {
//调用上面的方法,读取前端传过来的参数和文件路径
List<User> excelContent = readExcel(importOrderDTO, rootPath);
if (excelContent.isEmpty()) {
return ResultUtil.error("数据为空");
}
//下面都是一些逻辑处理,大家一定看得懂就不多说了
List<User> userList = userMapper.selectList(new EntityWrapper<User>());
List<User> sameList = new ArrayList<>();
List<User> differentList = new ArrayList<>();
for (User excelStudent : excelContent) {
//数据不同
boolean flag = true;
for (User user : userList) {
if (user.getAccount().equals(excelStudent.getAccount())) {
//相同的数据
flag = false;
sameList.add(excelStudent);
}
}
if (flag) {
//如果导入的数据与上面判断的条件相等了,就执行插入操作
differentList.add(excelStudent);
userMapper.insert(excelStudent);
}
}
if (differentList.size() == 0) {
//判断如果导入的数据跟当前的数据一致的话
return ResultUtil.error("导入数据与当前数据一致!");
}
return ResultUtil.successWithMessage("数据导入成功");
} catch (Exception e) {
System.out.println(e);
return ResultUtil.error("数据导入失败,请检查导入文件格式与模板文件是否相同!");
}
}
service层方法写完了,接着就是controller了,直接上代码,工具类在下面
@PostMapping(value = "/importExcel")
public Result importExcel(HttpServletRequest request, @RequestBody ImportOrderDTO importOrderDTO) {
String rootPath = ExcelUtils.getRootPath(request);
System.out.println(importOrderDTO.getFilePath());
return userService.importUserWithExcel(importOrderDTO, rootPath);
}
这是获取根路径的工具类
public class ExcelUtils {
/**
* 获取上传根路径
*
* @param request 请求信息
* @return string
*/
public static String getRootPath(HttpServletRequest request) {
return request.getSession().getServletContext().getRealPath(UtilConstant.UPLOAD_PATH);
}
public static Workbook getWorkbook(String excelType) {
try {
return WorkbookFactory.create(!ExcelTypeEnum.XLS.getVal().equals(excelType));
} catch (IOException e) {
throw new ServerException("创建excel文件失败", e);
}
}
/**
* 创建表
*
* @param wb 目标文件
* @param sheetName 表名
* @param sheetTitle 表头
* @return sheet
*/
public static Sheet createSheet(Workbook wb, String sheetName, String[] sheetTitle) {
Sheet sheet = wb.createSheet(sheetName);
Row row = sheet.createRow(0);
for (int i = 0; i < sheetTitle.length; i++) {
row.createCell(i).setCellValue(sheetTitle[i]);
}
return sheet;
}
/**
* 创建单元格.
*
* @param row 行
* @param column 列
* @param value 值
*/
public static void createCell(Row row, int column, String value) {
Cell cell = row.createCell(column);
cell.setCellValue(value);
}
}
来源:https://blog.csdn.net/weixin_43250266/article/details/107684036
0
投稿
猜你喜欢
- 本文实例讲述了Python装饰器(decorator)定义与用法。分享给大家供大家参考,具体如下:什么是装饰器(decorator)简单来说
- 本文总结了一些简单基本的输出格式化形式,下面话不多说了,来看看详细的介绍吧。一、打印字符串>>> print "
- 本文记录django中如何使用celery完成异步任务。Celery 是一个简单、灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一
- 假设你已经做好了如下配置和尝试在Extensions中安装好了Remote -SSH添加了你要访问的服务器ip地址等信息,并拥有了一个con
- 本文实例讲述了JS基于设计模式中的单例模式(Singleton)实现封装对数据增删改查功能。分享给大家供大家参考,具体如下:单例模式单例模式
- 两个三维矩阵的乘法怎样计算呢?我通过实验发现,tensorflow把前面的维度当成是batch,对最后两维进行普通的矩阵乘法。也就是说,最后
- 利用Chrome或Firefox保存的Har文件http/https请求,可用于遍历字典提交From表单.少说废话直接上代码Github地址
- 今天学习Python的时候,需要安装一个第三方库,Python Imaging Library,是Python下面一个非常强大的处理图像的工
- 定时任务:1、 线程睡眠函数 sleep() ——粗暴!一直占有 CPU 资源,导致后续操作无法执行2、 threading.Timer(1
- 前言help(argparse)查看说明文档,“argparse - Command-line parsing libr
- 在我们想要对不同变量进行判断的时候,会分析其中的之间的联系。这种理念同样也被用在实例生活中,最常见到的是做一个地理的热力图。很多人对画热力图
- 前情回顾在上一篇中,我们通过配置基本的信息,已经让我们的项目能够正常的跑起来了。但是,这里还没有涉及到 AJAX 请求接口的内容。vue 本
- 故障状况:php网站连接mysql失败,但在命令行下通过mysql命令可登录并正常操作。解决方案:1、命令行下登录mysql,执行以下命令:
- 一、前言为方便描述教程例子,这里给出mysql表结构定义和golang结构体定义。下面是教程用到的foods表结构定义:CREATE TAB
- 笔者在运行 import tensorflow as tf时出现下面的错误,但在运行import tensorflow时没有出错。>&
- 随着网络的普及,基于网络的应用也越来越多。网络数据库就是其中之一。通过一台或几台服务器可以为很多客户提供服务,这种方式给人们带来了很多方便,
- 前言CSRF全称Cross-site request forgery(跨站请求伪造),是一种网络的攻击方式,也被称为“One Click A
- 之前写了一篇flask开发环境搭建,今天继续,进行一个实战小项目-blog系统。blog系统很简单,只有一个页面,然后麻雀虽小五脏俱全。这里
- 一、相关代码数据库配置类 MongoDBConn.py#encoding=utf-8'''Mongo Conn连接类
- JDBC基础入门概念JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java