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

 更新时间:2020年10月22日 14:38:49   作者:贾树丙  
这篇文章主要介绍了新版POI获取日期类型cell值过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

使用POI读取Excel值的同学,一定为日期类型抓狂过!

POI对单元格日期处理很弱,没有针对的类型,日期类型取出来的也是一个double值,所以同样作为数值类型。即使使用cell.setCellType(CellType.STRING) 也还是会返回一个数字

网上大部分的方法是:

cell.getCellType()

但是在新版的POI中,比如3.15版,这个写法已经被放弃使用了。由于项目需要在下不能调整jar包,只好硬着头皮去解决。

后来发现了一个方法:

cell.getCellStyle().getDataFormatString() 可以判断单元格的格式类型,如下图

于是便可以使用如下方法判断:

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的值,是个日期。

如上图,这个日期【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;
  }

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

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

相关文章

  • java实现KFC点餐小程序

    java实现KFC点餐小程序

    这篇文章主要为大家详细介绍了java实现KFC点餐系统小程序,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • 关于SpringBoot mysql数据库时区问题

    关于SpringBoot mysql数据库时区问题

    在后端开发过程中经常会遇到几个时区设置问题,今天分几种情况给大家介绍SpringBoot mysql数据库时区问题,感兴趣的朋友跟随小编一起看看吧
    2021-06-06
  • Java中的线程安全集合CopyOnWriteArrayList解析

    Java中的线程安全集合CopyOnWriteArrayList解析

    这篇文章主要介绍了Java中的线程安全CopyOnWriteArrayList解析,CopyOnWriteArrayList是ArrayList的线程安全版本,从他的名字可以推测,CopyOnWriteArrayList是在有写操作的时候会copy一份数据,然后写完再设置成新的数据,需要的朋友可以参考下
    2023-12-12
  • SpringMVC @ResponseBody 415错误处理方式

    SpringMVC @ResponseBody 415错误处理方式

    这篇文章主要介绍了SpringMVC @ResponseBody 415错误处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 使用Apache Ignite实现Java数据网格

    使用Apache Ignite实现Java数据网格

    今天我们来探讨如何使用Apache Ignite来实现Java数据网格,Apache Ignite是一个高性能的内存计算平台,它提供了分布式缓存、数据网格和计算功能,可以显著提高大规模应用的数据处理性能,感兴趣的小伙伴跟着小编一起来看看吧
    2024-08-08
  • 简单了解如何在spring中使用RabbitMQ

    简单了解如何在spring中使用RabbitMQ

    这篇文章主要介绍了简单了解如何在spring中使用RabbitMQ,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 浅析java程序中hibernate的应用总结

    浅析java程序中hibernate的应用总结

    hibernate可以理解为是一个中间件它负责把java程序的sql语句接收过来发送到数据库,而数据库返回来的信息hibernate接收之后直接生成一个对象传给java
    2013-07-07
  • 详解 Java HashMap 实现原理

    详解 Java HashMap 实现原理

    这篇文章主要介绍了详解 Java HashMap 实现原理的相关资料,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-03-03
  • SpringBoot+ThreadLocal+AbstractRoutingDataSource实现动态切换数据源

    SpringBoot+ThreadLocal+AbstractRoutingDataSource实现动态切换数据源

    最近在做业务需求时,需要从不同的数据库中获取数据然后写入到当前数据库中,因此涉及到切换数据源问题,所以本文采用ThreadLocal+AbstractRoutingDataSource来模拟实现dynamic-datasource-spring-boot-starter中线程数据源切换,需要的朋友可以参考下
    2023-08-08
  • 解决安装mysqlclient的时候出现Microsoft Visual C++ 14.0 is required报错

    解决安装mysqlclient的时候出现Microsoft Visual C++ 14.0 is required报错

    这篇文章主要介绍了解决安装mysqlclient的时候出现Microsoft Visual C++ 14.0 is required报错问题,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-11-11

最新评论