Excel導入時,日期格式的判斷 isCellDateFormatted(Cell cell)不成功原因

在文件excel文件上傳之後,進行單個單元格的值進行處理以及驗證。

對單元格的處理如下:

public Object getCellValue(Cell cell) {
		Object value = null;
		DecimalFormat df = new DecimalFormat("0"); // 格式化爲整數
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 日期格式化
		switch (cell.getCellType()) {
			case Cell.CELL_TYPE_STRING:
				value = cell.getStringCellValue();
				break;
			case Cell.CELL_TYPE_NUMERIC:
				String dataFormat = cell.getCellStyle().getDataFormatString();	// 單元格格式
				boolean isDate = DateUtil.isCellDateFormatted(cell);
				if ("General".equals(dataFormat)) {
					value = df.format(cell.getNumericCellValue());
				} else if (isDate) {
					value = sdf.format(cell.getDateCellValue());
				} else {
					value = cell.getNumericCellValue();
				}
				break;
			case Cell.CELL_TYPE_BOOLEAN:
				value = cell.getBooleanCellValue();
				break;
			case Cell.CELL_TYPE_BLANK:
				value = "";
				break;
			default:
				break;
		}
		return value;
	}

可是我在使用的過程中,excel導入的日期格式無法進行判斷,因爲很多導入excel的人要求設置的是日期格式,而日期格式導入到java後臺之後呈現的是一個5、6位數字的形式。

DateUtil提供了一個isCellDateFormatted(Cell cell)的方法進行判斷excel該單元格的值是否爲日期格式,返回值爲布爾類型。

DateUtil.isCellDateFormatted(cell);

通常以上就可以進行判斷了,可是我自己在使用的過程中發現判斷不準確,一直返回的false。

查看源碼之後才發現,原來它裏面並沒有對漢字進行替換,只是對如下的斜槓以及短橫線等進行替換。所以在設置日期格式爲2019年1月18日這種格式的時候,工具判斷會出現問題。

fs = fs.replaceAll("\\\\-", "-");

fs = fs.replaceAll("\\\\,", ",");

fs = fs.replaceAll("\\\\.", ".");

fs = fs.replaceAll("\\\\ ", " ");

fs = fs.replaceAll(";@", "");

fs = fs.replaceAll("^\\[\\$\\-.*?\\]", "");

fs = fs.replaceAll("^\\[[a-zA-Z]+\\]", "");

解決辦法有二:

1、直接修改jar包(修改了之後,對以後項目的遷移以及轉換可能有點影響)

2、copy需要的代碼,手動創建一個工具類進行判斷。

這裏貼上我自己修改後的工具類:

public static boolean isCellDateFormatted(Cell cell)
	  {
	    if (cell == null) return false;
	    boolean bDate = false;

	    double d = cell.getNumericCellValue();
	    if (isValidExcelDate(d)) {
	      CellStyle style = cell.getCellStyle();
	      if (style == null) return false;
	      int i = style.getDataFormat();
	      String f = style.getDataFormatString();
	      bDate = isADateFormat(i, f);
	    }
	    return bDate;
	  }
	
	public static boolean isADateFormat(int formatIndex, String formatString)
	  {
	    if (isInternalDateFormat(formatIndex)) {
	      return true;
	    }

	    if ((formatString == null) || (formatString.length() == 0)) {
	      return false;
	    }

	    String fs = formatString;
            //下面這一行是自己手動添加的 以支持漢字格式wingzing
	    fs = fs.replaceAll("[\"|\']","").replaceAll("[年|月|日|時|分|秒|毫秒|微秒]", "");  
	    
	    fs = fs.replaceAll("\\\\-", "-");

	    fs = fs.replaceAll("\\\\,", ",");

	    fs = fs.replaceAll("\\\\.", ".");

	    fs = fs.replaceAll("\\\\ ", " ");

	    fs = fs.replaceAll(";@", "");

	    fs = fs.replaceAll("^\\[\\$\\-.*?\\]", "");

	    fs = fs.replaceAll("^\\[[a-zA-Z]+\\]", "");

	    return (fs.matches("^[yYmMdDhHsS\\-/,. :]+[ampAMP/]*$"));
	  }
	
	public static boolean isInternalDateFormat(int format)
	  {
	    switch (format) { case 14:
	    case 15:
	    case 16:
	    case 17:
	    case 18:
	    case 19:
	    case 20:
	    case 21:
	    case 22:
	    case 45:
	    case 46:
	    case 47:
	      return true;
	    case 23:
	    case 24:
	    case 25:
	    case 26:
	    case 27:
	    case 28:
	    case 29:
	    case 30:
	    case 31:
	    case 32:
	    case 33:
	    case 34:
	    case 35:
	    case 36:
	    case 37:
	    case 38:
	    case 39:
	    case 40:
	    case 41:
	    case 42:
	    case 43:
	    case 44: } return false;
	  }
	
	  public static boolean isValidExcelDate(double value)
	  {
	    return (value > -4.940656458412465E-324D);
	  }

代碼都是從源碼copy出來後修改的,可以放心使用。

 

後記

遇到很多工具類不符合自己的預期以及網上人所說,可以嘗試閱讀一下源碼,找一下問題所在,這樣纔是解決問題以及提升自己能力的最好的選擇。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章