欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

新版POI获取日期类型cell值过程图解

程序员文章站 2022-03-08 10:05:32
使用poi读取excel值的同学,一定为日期类型抓狂过!poi对单元格日期处理很弱,没有针对的类型,日期类型取出来的也是一个double值,所以同样作为数值类型。即使使用cell.setcelltyp...

使用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;
  }

同学们慢慢理解吧,代码虽然挫了一点,也不能保证完全正确,但至少这种情况下是可以使用的。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。