专栏首页高爽的专栏POI读取Excel常见问题

POI读取Excel常见问题

       最近在做一个将excel导入到报表中的功能,使用了POI来实现,发现POI使用有诸多不便之处,先记录下来,以后可能考虑使用Openxml。

       1. 数值类型处理

       通过POI取出的数值默认都是double,即使excel单元格中存的是1,取出来的值也是1.0,这就造成了一些问题,如果数据库字段是int,那么就会wrong data type,所以需要对数值类型处理。

Cell cell = null;// 单元格
Object inputValue = null;// 单元格值
if (!isEmpty(cell) && cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
	long longVal = Math.round(cell.getNumericCellValue());
	if (Double.parseDouble(longVal + ".0") == doubleVal)
		inputValue = longVal;
	else
		inputValue = doubleVal;
}

       这么处理后,单元格中的小数没有变化,如果是整数,也会取到整数。

       2. 日期类型处理

       很遗憾,POI对单元格日期处理很弱,没有针对的类型,日期类型取出来的也是一个double值,所以同样作为数值类型。

Cell cell = null;// 单元格
Object inputValue = null;// 单元格值
if (!isEmpty(cell) && cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
    if (DateUtil.isCellDateFormatted(c))// 判断单元格是否属于日期格式
	    inputValue = cell.getDateCellValue();//java.util.Date类型
}

       可以判断得到的Date是日期时间、日期还是时间,可以通过cell.getCellStyle().getDataFormat()来判断,这个返回值没有一个常量值来对应,我本机是excel2013,测试结果是日期时间(yyyy-MM-dd HH:mm:ss) - 22,日期(yyyy-MM-dd) - 14,时间(HH:mm:ss) - 21,年月(yyyy-MM) - 17,时分(HH:mm) - 20,月日(MM-dd) - 58,有了这个,可以根据数据库字段类型,处理之后再入库,相当不方便。

       另外,如果单元格数据格式是自定义的日期格式,那么通过DateUtil.isCellDateFormatted(cell)判断不出来,而且该单元格还是一个数值单元格,返回一个double值,这里比较2。针对这种方式,有两种解决方案,第一种,重写DateUtil.isCellDateFormatted(cell)方法,开源的都有源码;第二种,cell.getCellStyle().getDataFormatString()来判断,这个方法会返回格式字符串,通过这个字符串去匹配,再处理。

       3. 数据有效性

       很奇怪,POI能生成数据有效性(下拉列表),却得不到,或者说我没找到方法去得到,蛋疼。

       附单元格数据类型:

常量

说明

取值

Cell.CELL_TYPE_NUMERIC

数值类型

cell.getNumericCellValue()或cell.getDateCellValue()

Cell.CELL_TYPE_STRING

字符串类型

cell.getStringCellValue()或cell.toString()

Cell.CELL_TYPE_BOOLEAN

布尔类型

cell.getBooleanCellValue()

Cell.CELL_TYPE_FORMULA

表达式类型

cell.getCellFormula()

Cell.CELL_TYPE_ERROR

异常类型不知道何时算异常

cell.getErrorCellValue()

Cell.CELL_TYPE_BLANK

空,不知道何时算空

空就不要取值了吧

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • IE中iframe跨域访问

    1      什么叫跨域?        指在A系统(第一方)中通过URL直接调用B系统(第三方),并且两个系统分别部署在不同的域内,简单的理解就是访问这两个系...

    高爽
  • 求编辑距离

    版权声明:本博客所有的原创文章,作者皆保留版权。 ...

    高爽
  • 策略模式

    概述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。 UML ? 实现 Strate...

    高爽
  • UITableView性能提升和优化(第

    在重用cell之后,你可以再一次测试滚动性能。从表格3-3可以看出,在你正确重用cell之后,性能提升了一倍。

    py3study
  • Swift 2.0 自定义cell和不同风格的cell

          昨天我们写了使用系统的cell怎样创建tableView,今天我们再细分一下,就是不同风格的cell,我们怎写代码。先自己创建一个cell,继承于U...

    Mr.RisingSun
  • Cell V2详解

    注: 本文之前已经在腾讯云tstack上发布过了https://cloud.tencent.com/developer/article/1473057,这里自己...

    jiang
  • UITableViewCell系列之(三)卡片式列表

    VV木公子
  • 在iOS中怎样创建可展开的Table View?(上)

    几乎所有的app都有一个共同特征,它们向用户提供了多个视图控制器来导航和工作.这些视图控制器可以用在很多方面,例如,简单地显示某种信息在屏幕上,或者从用户的输入...

    hrscy
  • 处于UITableView中心线cell的处理

    且行且珍惜_iOS
  • iOS 9 Storyboard 教程(一下)

    你可以直接从storyboard编辑器中,使用原型cell你可以很容易的为你的tableViewCell设计一套自定义的布局.

    hrscy

扫码关注云+社区

领取腾讯云代金券