1. 程式人生 > 程式設計 >新版POI獲取日期型別cell值過程圖解

新版POI獲取日期型別cell值過程圖解

使用POI讀取Excel值的同學,一定為日期型別抓狂過!

POI對單元格日期處理很弱,沒有針對的型別,日期型別取出來的也是一個double值,所以同樣作為數值型別。即使使用cell.setCellType(CellType.STRING) 也還是會返回一個數字

網上大部分的方法是:

cell.getCellType()

但是在新版的POI中,比如3.15版,這個寫法已經被放棄使用了。由於專案需要在下不能調整jar包,只好硬著頭皮去解決。

新版POI獲取日期型別cell值過程圖解

後來發現了一個方法:

cell.getCellStyle().getDataFormatString() 可以判斷單元格的格式型別,如下圖

新版POI獲取日期型別cell值過程圖解

於是便可以使用如下方法判斷:

if("yyyy/mm;@".equals(cell.getCellStyle().getDataFormatString()) || "m/d/yy".equals(cell.getCellStyle().getDataFormatString())
    || "yy/m/d".equals(cell.getCellStyle().getDataFormatString()) || "mm/dd/yy".equals(cell.getCellStyle().getDataFormatString())
    || "dd-mmm-yy".equals(cell.getCellStyle().getDataFormatString())|| "yyyy/m/d".equals(cell.getCellStyle().getDataFormatString())){
  return new SimpleDateFormat("yyyy/MM/dd").format(cell.getDateCellValue());
}

使用這個方法判斷的格式有限,如果能夠限定單元格格式的話,這樣是足夠解決的。

但我的專案坑爹的是Excel中的日期格式也是不固定的,還需要另謀出路。

在除錯的時候發現,明明就顯示著這個cell的值,是個日期。

新版POI獲取日期型別cell值過程圖解

如上圖,這個日期【31-一月-2005】並不在這個cell下的某一個子元素裡,至少我找了很久是沒找到。只能使用cell.toString() 得到

最後我的解決辦法是:首先使用了cell.getCellStyle().getDataFormatString()判斷,如果能得到就返回“yyyy/MM/dd”格式的日期。如果得不到,最後都返回cell.toString()。這樣至少不會返回一個數字了,也不知道對其他型別的單元格有沒有影響,目前跑了幾張表沒有報錯

這種解決辦法當然是不好的,肯定是有一種好的方法我沒找到,如果哪位大俠找到了,煩請告知一聲,在下拜謝了!

到最後果然還是找我麻煩了,【31-一月-2005】格式不行,必須轉成“yyyy/MM/dd”格式。

然後想,要不寫個正則表示式,通過判斷字串的方式,來判斷出這種日期型別。坑爹了,正則不會寫。。。。。。。明明感覺很簡單的,就是不對

再然後,耍小聰明,改成通過使用java中的字串分割一點點判斷,先放程式碼:

/**
   * 分多種格式解析單元格的值
   *
   * @param cell 單元格
   * @return 單元格的值
   */
  public static String convertCellToString(Cell cell){
    //如果為null會丟擲異常,應當返回空字串
    if (cell == null)
      return "";

    //POI對單元格日期處理很弱,沒有針對的型別,日期型別取出來的也是一個double值,所以同樣作為數值型別
    //解決日期2006/11/02格式讀入後出錯的問題,POI讀取後變成“02-十一月-2006”格式
    if(cell.toString().contains("-") && checkDate(cell.toString())){
      String ans = "";
      try {
        ans = new SimpleDateFormat("yyyy/MM/dd").format(cell.getDateCellValue());
      } catch (Exception e) {
        ans = cell.toString();
      }
      return ans;
    }

    cell.setCellType(CellType.STRING);
    return cell.getStringCellValue();
  }

  /**
   * 判斷是否是“02-十一月-2006”格式的日期型別
   */
  private static boolean checkDate(String str){
    String[] dataArr =str.split("-");
    try {
      if(dataArr.length == 3){
        int x = Integer.parseInt(dataArr[0]);
        String y = dataArr[1];
        int z = Integer.parseInt(dataArr[2]);
        if(x>0 && x<32 && z>0 && z< 10000 && y.endsWith("月")){
          return true;
        }
      }
    } catch (Exception e) {
      return false;
    }
    return false;
  }

同學們慢慢理解吧,程式碼雖然挫了一點,也不能保證完全正確,但至少這種情況下是可以使用的。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。