最近做了一个批量上传订单的功能,支持excel模板下载,excel数据上传。在对excel上传的数据做校验的时候发现一个问题:excel被解析的时候总是在解析完“非空数据行”的后面的末尾行便停止解析。这就导致我后面的特定字段的非空验证出现了问题,直接上代码吧。
/** * 验证小平台和线下手工单Excel是否填写有误 * @param importPlatformAndOfflineOrders * @return */ private Set<String> platformAndOfflineOrdersValidate(List<ImportPlatformAndOfflineOrder> importPlatformAndOfflineOrders,MultipartFile file) throws Exception{ //创建异常集合 final Set<String> exceptionSet = new HashSet<>(); //构建表头Title String [] titles = this.offLineTitles; try{ //从用户获取的表头 List<String> excelTitles = getPlatformAndOfflineTitles(file); //首先判断来源于用户的Excel表头和模板表头长度是否一致 if(excelTitles.size()==titles.length){ boolean isAllEqual = false; List<String> equalList = new ArrayList(); boolean isEqual = false; for (int num = 0;num<excelTitles.size();num++) { isEqual = excelTitles.get(num).equals(titles[num])?true:false; if(isEqual){ equalList.add("ok"); }else { equalList.add("error"); } } if(!equalList.contains("error")){ isAllEqual = true; } //其次判断来源于用户的Excel表头和模板表头内容是否一致 if(isAllEqual){ //判断导入数据是否为空 if (importPlatformAndOfflineOrders.isEmpty() || importPlatformAndOfflineOrders.size() <= 0) { exceptionSet.add("import datas is null,导入的数据为空"); }else { for (int i = 0; i < importPlatformAndOfflineOrders.size()-1; i++){ final ImportPlatformAndOfflineOrder importPlatformAndOfflineOrder = importPlatformAndOfflineOrders.get(i); List<ImportPlatformAndOfflineOrderEntry> entryList = importPlatformAndOfflineOrder.getOrderEntries(); final String platformOrderCode = importPlatformAndOfflineOrder.getPlatformOrderCode(); //验证平台单号是否为空 if(StringUtils.isEmpty(platformOrderCode)){ exceptionSet.add("platformOrderCode 必填,请填写!"); }else { //判断Excel中platformCode 是否有重复 List<String> platformCodeList = new ArrayList<>(); Set<String> platformCodeSet = new HashSet<>(); for (int no =0;no<importPlatformAndOfflineOrders.size();no++){ ImportPlatformAndOfflineOrder importPlatformAndOfflineOrderAno = importPlatformAndOfflineOrders.get(no); String platformSingleCode= importPlatformAndOfflineOrderAno.getPlatformOrderCode(); if(!StringUtils.isEmpty(platformSingleCode)){ platformCodeList.add(platformSingleCode); platformCodeSet.add(platformSingleCode); } } if(platformCodeList.size()==platformCodeSet.size()){ //验证订单是否存在 OrderModel orderModel = beforeshipOrderDao.findOrderByPlatformCode(platformOrderCode); if(orderModel==null){ //验证店铺 final String saleStore = importPlatformAndOfflineOrder.getSaleStore(); if(StringUtils.isEmpty(saleStore)){ exceptionSet.add("saleStore 必填,请填写!"); }else{ UserModel user = userService.getCurrentUser(); List<String> storeList = PermissionUtils.getCurrentSaleStores(user); if(!storeList.contains(saleStore)){ exceptionSet.add("saleStore 不存在,请重新填写!错误值为:"+saleStore); } } //验证最晚发货时间是否为空 final Date lateDeliveryTime = importPlatformAndOfflineOrder.getLateDeliveryTime(); if(lateDeliveryTime==null){ exceptionSet.add("lateDeliveryTime 必填,请填写!"); } //验证买家名称是否为空 final String buyerName = importPlatformAndOfflineOrder.getBuyerName(); if(StringUtils.isEmpty(buyerName)){ exceptionSet.add("buyerName 必填,请填写!"); } //验证买家id是否为空 final String buyerID = importPlatformAndOfflineOrder.getBuyerID(); if(StringUtils.isEmpty(buyerID)){ exceptionSet.add("buyerID 必填,请填写!"); } //验证支付方式是否合法 final String paymentType = importPlatformAndOfflineOrder.getPaymentType(); final String bank = "Bank"; final String paypal = "paypal"; if(!StringUtils.isEmpty(paymentType)){ if(bank.equals(paymentType) || paypal.equals(paymentType)){ }else { exceptionSet.add("paymentType 填写错误(Bank/paypal)!"+paymentType); } } //验证收件人是否为空 final String consigneeName = importPlatformAndOfflineOrder.getConsigneeName(); if(StringUtils.isEmpty(consigneeName)){ exceptionSet.add("consigneeName 必填,请填写!"); } //验证电话号码是否为空 final String phone = importPlatformAndOfflineOrder.getPhone(); if(StringUtils.isEmpty(phone)){ exceptionSet.add("phone 必填,请填写!"); } //验证国家是否为空 final String country = importPlatformAndOfflineOrder.getCountry(); if(StringUtils.isEmpty(country)){ exceptionSet.add("country 必填,请填写!"); } //验证市是否为空 final String city = importPlatformAndOfflineOrder.getCity(); if(StringUtils.isEmpty(city)){ exceptionSet.add("city 必填,请填写!"); } ImportPlatformAndOfflineOrderEntry entryModel = entryList.get(0); //验证baseCode1是否为空 final String baseCode1 = entryModel.getBaseCode(); if(StringUtils.isEmpty(baseCode1)){ exceptionSet.add("baseCode1 必填,请填写!"); }else { BeforeshipBaseproductModel bpModel = productDataHandleService.getBaseProductByCode(baseCode1); if(bpModel==null){ exceptionSet.add("系统缺少BaseCode:"+baseCode1); }else { //验证表中BaseCode所在仓库与收货国家是否匹配 SearchResult<CountryModel> countries= beforeshipPmService.getMarketableCountry(bpModel); List<String> countryNames = new ArrayList<>(); for (int y = 0; y < countries.getTotalCount(); y++) { if (countries != null) { String countryName = countries.getResult().get(y).getIsocode(); countryNames.add(countryName); } } if(!countryNames.contains(country)){ exceptionSet.add("BaseCode所在可售卖国家与收货国家不匹配,不匹配的BaseCode是:"+entryModel.getBaseCode()); } } } //验证订单行BaseCode for(int z = 1;z< entryList.size();z++){ String baseCode = entryList.get(z).getBaseCode(); if(!StringUtils.isEmpty(baseCode)){ BeforeshipBaseproductModel bpModel = productDataHandleService.getBaseProductByCode(baseCode); if(bpModel==null){ exceptionSet.add("系统缺少BaseCode:"+baseCode); } } } //验证邮编是否为空 final String zipCode = importPlatformAndOfflineOrder.getZipCode(); if(StringUtils.isEmpty(zipCode)){ exceptionSet.add("zipCode 必填,请填写!"); } //验证地址是否为空 final String address1 = importPlatformAndOfflineOrder.getAddress1(); if(StringUtils.isEmpty(address1)){ exceptionSet.add("address1 必填,请填写!"); } //验证qty1是否为空 final String qty1 = entryModel.getQty(); if(StringUtils.isEmpty(qty1)){ exceptionSet.add("Qty1 必填,请填写!"); }else if(!isNumeric(qty1)){ exceptionSet.add("Qty1 必须是非负整数!错误值为:"+qty1); break; }else if(Integer.valueOf(qty1)<0){ exceptionSet.add("Qty1 必须是非负整数!错误值为:"+qty1); } //验证price1是否为空 final String price1 = entryModel.getPrice(); if(StringUtils.isEmpty(price1)){ exceptionSet.add("Price1 必填,请填写!"); }else if(!isNumeric(price1)){ exceptionSet.add("Price1 必须是正数!错误值为:"+price1); break; }else if(Double.valueOf(price1)<=0){ exceptionSet.add("Price1 必须是正数!错误值为:"+price1); } }else { exceptionSet.add("该订单已创建!请核对单号:"+platformOrderCode); } }else { exceptionSet.add("platformOrderCode 有重复,请核对!"); } } } } }else { exceptionSet.add("模板表头不可修改,重新下载模板!"); } }else { exceptionSet.add("模板表头不可修改,重新下载模板!"); } }catch (Exception e){ e.printStackTrace(); }finally { return exceptionSet; } }
上面是我对其中一个模板excel数据的验证,为了避免对空行做验证,其实一个非常“脑残”的方法就能搞定。就是对解析到的excel行少验证一行。说脑残是因为当时我对poi解析excel的原理缺乏足够的认知。在经过调试之后才发现这个问题,这样就可以轻松解决了。不过excel有个很恶心的问题,就是你在excel 中填入数据如果选中单元格的数据直接删除,它还是会被解析到。除非你在左边序号处选中一整行删除才可以。这个问题暂时没有好的解决方案。还有,时间格式的问题:excel时间如果输入“2018-02-23”23:23:23”,它会变成“2018/02/23 23:23”这样的时间格式,用户很头疼。于是我将时间格式规定为:“2018.02.23”23:23:23”这样的时间格式就不会跳来跳去。