需求:前端上传excel文档,服务端将数据取出来去重插入数据库.记录一下实现过程.
Apache POI是Apache软件基金会的开源项目,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。excel就是Microsoft Office格式文档,第一步就是在pom.xml中加载poi包.
注:以下两个jar包的版本必须相同,否则会报错
<!-- 导入导出Microsoft Office格式文档 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
2,导入完之后打开springboot的配置文件properties.yml,设置文件上传的限制,不然springboot的默认最大的文件是1Mb.
servlet:
multipart:
max-file-size: 50MB # 设置单个文件最大内存
max-request-size: 50MB # 设置所有文件最大内存
3,前期准备工作已经做好,开始写代码读取文件数据
1)在entity包下创建实体类,我这里创建的是ImportDO.java.这里的具体参数就不写了.
2)service/ImportService.java
public interface ImportService extends IService<ImportDO> {
//新增导入记录
ResultUtil insertImport(ImportDO importDO) throws Exception;
}
3)实现类
service/impl/ImportServiceImpl.java
@Override //重载service包
@Transactional //实现事务回滚,这里可以不用写.如果要用记得在入口处添加注解@EnableTransactionManagement //开启声明式事务
public ResultUtil insertImport(ImportDO importDO) throws Exception {
MultipartFile file = importDO.getExcelFile();
System.out.println(file);
if(file == null){
throw new UploadException("A1024", "文件不能为空!");
}
String fileName = file.getOriginalFilename();
//将excel上传,这里注释掉上传,因为一个文件不能被读取两次.如果这里需要上传,需将文件复制一份.
//String filePath = UploadUtil.uploadExcel(file);
String filePath="";
// jk_import表中
ImportDO importNewDate = new ImportDO();
importNewDate.setCreateTime(LocalDateTime.now());
importNewDate.setUpdateTime(importNewDate.getCreateTime());
//上传的excel文件路径
importNewDate.setFailNum(0);// 暂定为0,预约记录成功后再update
importMapper.insert(importNewDate);
Long importId = importNewDate.getId();
//获取excel中数据
// 一个文件不能被读取两次
InputStream inputStream = file.getInputStream();
// 创建Excel工作薄
Workbook work = this.getWorkbook(inputStream, fileName);
if (null == work) {
throw new UploadException("A1023","Excel工作薄内容为空!");
}
Row row = null;
Sheet sheet = work.getSheetAt(0);
Integer succNum = 0;// 数据正确条数
Integer failNum = 0;// 数据错误条数
Integer repeatNum = 0;// 数据错误条数
List appointRecordList = new ArrayList();
for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) {
row = sheet.getRow(j);
if (row == null || row.getFirstCellNum() == j) {
continue;
}
Map<String,Object> importData = new HashMap<String, Object>();
// 单位信息
importData.put("is_company",1);
importData.put("company",importDO.getCompany());
// 第一列 姓名 (必填)
String name = row.getCell(0).getStringCellValue();
importData.put("name",name);
// 第二列 性别(必填)
String genderStr = row.getCell(1).getStringCellValue();
Integer gender = 1;
if("男".equals(genderStr)) {
gender = 1;
}
if("女".equals(genderStr)) {
gender = 2;
}
importData.put("gender",gender);
// 第五列 身份证号(必填)
Cell cellIdcard = row.getCell(2);
cellIdcard.setCellType(CellType.STRING);// 将NUMERIC转为String
String idCard = cellIdcard.getStringCellValue();
importData.put("idCard",idCard);
//去重,鉴别单位名称和身份证号是否已经存在
AppointRecordDO findData = new AppointRecordDO();
findData.setCompany(importDO.getCompany());
findData.setIdCard(idCard);
ResultUtil findAppointRecord = appointRecordService.findAppointRecord(findData, 1, 1);
if(findAppointRecord.getCode() == 200) { // 已经存在
//错误数据+1
failNum ++;
//重复数据+1
repeatNum ++;
}
if(findAppointRecord.getCode() != 200){ // 不存在
// 第四列 手机号(必填)
Cell cellMobile = row.getCell(3);
cellMobile.setCellType(CellType.STRING);// 将NUMERIC转为String
String mobile = cellMobile.getStringCellValue();
importData.put("mobile",mobile);
if(name.isEmpty() || genderStr.isEmpty() idCard.isEmpty()){
failNum ++;
} else {
succNum ++;
}
LocalDateTime curr_time = LocalDateTime.now();
importData.put("createTime",curr_time);
// 将结果集拼接到list中
appointRecordList.add(importData);
}
}
work.close();// 关闭
//succNum大于1才返回importId,小于1删除插入记录信息
if(succNum >= 1){
// 将Excel数据插入appoint_record表中
appointRecordService.saveBatch(appointRecordList,appointRecordList.size());
// 成功返回
Map<String, Object> data = new HashMap<>();
data.put("succNum",succNum);
data.put("failNum",failNum);
return ResultUtil.returnRight(data);
} else {
importMapper.deleteById(importId);
// 成功返回
Map<String, Object> data = new HashMap<>();
data.put("succNum",succNum);
data.put("failNum",failNum);
return ResultUtil.returnRight(data,-1,"操作失败:成功条数为0");
}
}
/**
* 判断文件格式
* @param inStr
* @param fileName
* @return
* @throws Exception
*/
public Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
Workbook workbook = null;
String fileType = fileName.substring(fileName.lastIndexOf("."));
if (".xls".equals(fileType)) {
workbook = new HSSFWorkbook(inStr);
} else if (".xlsx".equals(fileType)) {
workbook = new XSSFWorkbook(inStr);
} else {
throw new UploadException("A1022","请上传excel文件!");
}
return workbook;
}
4)controller/ImportController.java
我的逻辑都在service层完成,这样controller看起来干净整洁
@ResponseBody
@PostMapping("/add")
public ResultUtil addAdmins(ImportDO importDO) throws Exception {
return importService.insertImport(importDO);
}
4.postman测试
importExcel.png
大功告成,当然实现过程会遇见很多错,耐心一点,都会解决的.
网友评论