需求:使用excel订单模板录入客户订单的订单明细,web端导入excel后,将验证excel中必填的字段,报错信息需整合后全部同时显示在提示框中。例如:第几行商品名不存在,第几行客户不为空。
分析合理性:
- 假如发现一个错误,马上反馈给用户,然后这张表中有10个错误,用户需要导入10次,才能成功,这样做用户体验不是那么友好。
- 但是如果将错误信息一并显示出来,那么客户将全部错误改正后就能一次导入成功。
使用poi框架和POIUtils解析excel数据(本模板表字段全是String格式)
问题:getLastRowNum 能否拿到真实的sheet中行数size吗?excel中可能会出现这些情况?
- row = sheet.getRow(i) row == null (空行)
- 旧的数据或数据格式,使用delete键删除后,row不会等于null,解析的结果是空字符串或其它(这是个坑)
从而导致 size = getLastRowNum 最终可能会失真,如何过滤掉不要的数据行,获取到真实的行号并将错误信息行反馈给用户,是接下来需要做的。
思路:将循环遍历取得sheet中全部数据存入list
- 如果row = null ,也会创建一个map,将对应的字段全部置为空字符串
- 如果row可能是上面2的情况,excel表中对应的内容会都是空字符串或其它,这时同样存入map中
- 正常数据也存入map中
- 遍历的同时,将行号row同时放入这个map(重要);
然后需要根据需求删除不符合的行,假如一条真实数据需要(客户名,商品名,重量),那么需删除这3个条件为空的数据行,剩下真实有用的数据。
private Map<String, Object> analysisExcelToList(MultipartFile multipartFile) throws Exception {
Workbook workbook = WorkbookFactory.create(multipartFile.getInputStream());
Sheet sheet = workbook.getSheetAt(0);
// getLastRowNum 拿到的可能不是真实的表size大小,有可能单元格清除内容后保留的单元格也会记录size大小
int size = sheet.getLastRowNum();
List<Map<String, String>> list = new ArrayList<>(size);
Row buyerRow = sheet.getRow(1);
// 获取客户名和订单类型
String buyerName = POIUtils.getStringCellValue(buyerRow.getCell(1));
String orderType = POIUtils.getStringCellValue(buyerRow.getCell(3));
for (int i = 3; i <= size; i++) {
Map map = new HashMap<>();
Row row = sheet.getRow(i);
// 若执行到行为空,将填充空数据(delete 删除的空行会保留格式,row不会等于null)
if (row == null) {
map.put("smallByrName", "");
map.put("pdtAlias", "");
map.put("weight", "");
map.put("remark", "");
continue;
}
map.put("smallByrName", POIUtils.getStringCellValue(row.getCell(1)));
map.put("pdtAlias", POIUtils.getStringCellValue(row.getCell(2)));
map.put("weight", POIUtils.getStringCellValue(row.getCell(3)));
map.put("remark", POIUtils.getStringCellValue(row.getCell(4)));
map.put("row", String.valueOf(i + 1));
list.add(map);
}
// 删除空行(二级订单:smallByrName、pdtAlias、weight 三个参数同时为空)
list.removeIf(e -> StringUtils.isBlank(e.get("smallByrName")) && StringUtils.isBlank(e.get("pdtAlias")) && StringUtils.isBlank(e.get("weight")));
Map<String, Object> map = new HashMap<>();
map.put("buyerName", buyerName);
map.put("orderType", orderType);
map.put("list", list);
return map;
}
最后需要验证每一条数据的内容是否符合需求(可能某字段为空,可能某字段在数据库中没有),不符合需求的行,map中都有一个行号row,可以将错误信息加入到errorList中,最终经过处理,反馈提示用户。
excel.png promt.png
网友评论