最近做了一个批量上传订单的功能,支持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”这样的时间格式就不会跳来跳去。