当前位置:网站首页>【无标题】
【无标题】
2022-04-23 06:45:00 【代码的代】
Java 导入复杂的excel表数据到数据库
看下要导入到数据库的excel表数据有多复杂?直接上图!

如果要导入到数据库就要解析成我需要的样子,如下图所示。

经过对比,不拿发现我们就需要对图一的excel进行解析,直接上代码!
controller层
@PostMapping("/xfkylImport")
@ApiOperation(value = "导入复杂的excel表数据")
public R<Boolean> xfkylImport(@ApiParam(value = "文件对象") @RequestBody MultipartFile file) {
Boolean aBoolean = importTableService.xfkylImport(file);
return R.OK(aBoolean);
}
service层
/** * 导入复杂的excel表数据 * * @param file 文件 * @return 结果 */
public Boolean xfkylImport(MultipartFile file) {
//查询编码表:excel没有单位编号 ,所以只能先查编码表,后面把编码表的单位编号塞到要导入的对应的表数据中
List<IcDwbmk> icDwbmks = icDwbmkService.listAll();
Workbook workbook;
try {
//根据file创建excel
workbook = WorkbookFactory.create(file.getInputStream());
} catch (Exception e) {
throw new CustomException("导入失败,请检查导入模板是否正确");
}
//获取第一个sheet页
Sheet xssSheet0 = workbook.getSheetAt(0);
//获取第一行和最后一行
int rows1 = xssSheet0.getFirstRowNum();
int rows2 = xssSheet0.getLastRowNum();
//创建临时对象接收参数用
List<IcDreportXfkylVo> entities = new ArrayList<>();
List<String> str = new ArrayList<>();
// 一下操作开始:j代表excel的行,k代表excel的列
//循环遍历:舍弃第一行表头数据
for (int j = rows1 + 1; j <= rows2; j++) {
//创建临时对象
IcDreportXfkylVo excelVo = new IcDreportXfkylVo();
//获取当前行
Row row3 = xssSheet0.getRow(j);
//当前行没数据直接结束此次循环
if (null == row3) continue;
//遍历行所有的列
int firstCellNum = row3.getFirstCellNum();
int lastCellNum = row3.getLastCellNum();
//循环列数:舍弃第一列,这里根据业务需求 lastCellNum - 2 操作
for (int k = firstCellNum + 1; k < lastCellNum - 2; k++) {
//获取单元格的值,不管是否合并的单元格,都可以获取
String value = getSheelValue(xssSheet0, j, k);
//列数据为空,结束此次循环
if (StrUtil.isBlank(value)) continue;
//解析excel中的日期值,并存入集合中
if (j == 1 && k == 1) {
//日期格式化
Date date = Convert.toDate(value);
String datee = DateUtil.format(date, "yyyy-MM-dd");
str.add(datee);
}
//舍弃这两列
if (k == 10 || k > 17) continue;
// =========== 条件满足直接结束循环 start(根据实际需求来)===========
if ("数据日期".equals(value)) continue;
if ("测试类别一".equals(value)) continue;
if ("测试类别二".equals(value)) continue;
if (j < 4) continue;
if (j == 5) continue;
if (j > 12) continue;
// =========== 条件满足直接结束循环 end(根据实际需求来)===========
//获取第一列的单位名称与编码表中的名称相匹配,如果相同就取出编码表中的单位编号
if (k == 1) {
//有一个名称对应不上,手动进行改名。
if ("某某公司1".equals(value)) {
value = "某某公司2";
}
//取出每个单位对应的编号
String finalValue = value;
String s = icDwbmks.stream().filter(a -> finalValue.contains(a.getDwmc())).map(IcDwbmk::getDwbh).collect(Collectors.joining());
excelVo.setDwbh(s);
excelVo.setDwmc(value.replace("某某公司2", "某某公司1"));
}
try {
if (StringUtils.isNumeric(value)) {
//把当前列的值赋值给对应的属性字段,每一列对应的值 并以list的形式存储
if (k == 2) excelVo.setSjlx1(Integer.valueOf(value));
if (k == 3) excelVo.setSjlx2(Integer.valueOf(value));
if (k == 4) excelVo.setSjlx3(Integer.valueOf(value));
if (k == 5) excelVo.setSjlx4(Integer.valueOf(value));
if (k == 6) excelVo.setSjlx5(Integer.valueOf(value));
if (k == 7) excelVo.setSjlx6(Integer.valueOf(value));
if (k == 8) excelVo.setSjlx7(Integer.valueOf(value));
if (k == 9) excelVo.setSjlx8(Integer.valueOf(value));
if (k == 11) excelVo.setSjlx9(Integer.valueOf(value));
if (k == 12) excelVo.setSjlx10(Integer.valueOf(value));
if (k == 13) excelVo.setSjlx11(Integer.valueOf(value));
if (k == 14) excelVo.setSjlx12(Integer.valueOf(value));
if (k == 15) excelVo.setSjlx13(Integer.valueOf(value));
if (k == 16) excelVo.setSjlx14(Integer.valueOf(value));
}
} catch (Exception e) {
throw new CustomException("导入失败,请检查导入模板是否正确");
}
}
//j 每循环一次就会存入一次集合数据,这里面会有大量的空对象,后面要对空对象进行清空操作
entities.add(excelVo);
}
if (entities.size() > 0) {
// excel 解析完成:清空集合里面的空对象
entities.removeAll(Collections.singleton(new IcDreportXfkylVo()));
//遍历:把日期值赋值到数据中
for (IcDreportXfkylVo item :
entities) {
item.setDatee(str.get(0));
}
//手动捕捉异常
try {
//批量插入数据
Integer integer = icDreportXfkylMapper.insertBatch(entities);
if (integer > 0) {
return true;
}
} catch (Exception e) {
throw new CustomException("导入失败,请检查导入模板是否正确");
}
}
throw new CustomException("导入失败,请检查导入的excel表数据是否正确");
}
/** * 获取单元格内容,包括合并单元格的 * * @param sheet sheet表单 * @param row 当前行下标 * @param col 当前列下标 * @return 结果 */
public String getSheelValue(Sheet sheet, int row, int col) {
//获取合并区域的数量
int mergedRegions = sheet.getNumMergedRegions();
//遍历合并区域的数量
for (int i = 0; i < mergedRegions; i++) {
//指定索引处的合并区域
CellRangeAddress region = sheet.getMergedRegion(i);
//行开始下标
int firstRow = region.getFirstRow();
//行结束下标
int lastRow = region.getLastRow();
//列开始下标
int firstColumn = region.getFirstColumn();
//列结束下标
int lastColumn = region.getLastColumn();
if (row >= firstRow && row <= lastRow) {
if (col >= firstColumn && col <= lastColumn) {
Row fRow = sheet.getRow(firstRow);
Cell cell = fRow.getCell(firstColumn);
//所有内容已字符串形式处理
cell.setCellType(CellType.STRING);
//以字符串形式获取单元格的值
return cell.getStringCellValue();
}
}
}
Cell cell = sheet.getRow(row).getCell(col);
//所有内容已字符串形式处理
cell.setCellType(CellType.STRING);
return cell.getStringCellValue();
}
经过service层的解析,这里就已经成功完成了图二的效果,最终效果都在 “entities” 这个List集合中了,然后把这个集合数据批量插入到数据库就搞定了。
有类似需求的朋友,直接把我代码拷贝然后根据自己的需求改下,最后根据debug一步步的调试,最终就会成功的。
版权声明
本文为[代码的代]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_46044938/article/details/124315384
边栏推荐
- Série de pénétration Intranet: icmpsh du tunnel Intranet
- CTF-MISC学习之从开始到放弃
- Talking about distributed storage from ES, mongodb, redis and rocketmq
- Using lambda expression to solve the problem of C file name sorting (whether it is 100 or 11)
- Complete learning from scratch, machine learning and deep learning, including theory and code implementation, mainly using scikit and mxnet, and some practices (on kaggle)
- Dvwa 靶场练习记录
- Face to face summary 2
- How does Apache Hudi accelerate traditional batch mode?
- 三星,再次“西征”
- Expression related to month, year and day in SVG
猜你喜欢
随机推荐
爬虫学习笔记,学习爬虫,看本篇就够了
Mysql database backup and recovery under Linux (full + incremental)
Go语学习笔记 - Slice、Map | 从零开始Go语言
《内网安全攻防:渗透测试实战指南》读书笔记(八):权限维持分析及防御
Codeforces Round #784 (Div. 4)
Research on software security based on NLP (I)
Ctf-misc learning from start to give up
Feign源码分析
Summary of facial classics
Intranet penetration series: dnscat2 of Intranet tunnel
Asynchronous learning
Research on system and software security (I)
Learning records of some shooting ranges: sqli labs, upload labs, XSS
SAP GUI安全性
内网渗透系列:内网隧道之icmpsh
vivo,硬件安全的爱与雷霆
strcat()、strcpy()、strcmp()、strlen()
Research on system and software security (2)
DVWA靶场练习
访问数据库的时候出现错误 Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY.详解









