百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

坑啊,使用 POI 解析 Excel 要注意以下几点

toyiye 2024-09-02 02:18 5 浏览 0 评论

作者:khotyn
来源:https://blog.khotyn.com/blog/2013/03/01/apache-poi-notes/

最近在写一个解析 Excel 的程序,需要把从前端上传上来的 Excel 程序解析成 JSON 格式返回给前端,期间也试过 jxl ,不过它只支持到 Excel 2003。后来转而使用 apache 的 POI,作为初次使用者,使用过程中遇到了不少的问题:

# 如何引入 XSSF

刚下手写的时候,直接使用了 HSSFWorkbook 处理 Excel,后来发现它只能处理 2003 的 Excel,而不能处理 2007 版本的 Excel,翻了一下 POI 的文档,发现处理 2007 的 Excel 需要使用 XSSFWorkbook,但是引入的 POI 包中却找不到 XSSF 相关的类,原猜想是因为引入了版本较新的 POI,而官方的文档还是比较老的,因而被误导。结果发现使用 XSSF 需要额外引入 poi-ooxml 这个 jar 包, XSSF 相关的类都在这个 jar 包中,mvn 依赖如下:

<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>


# 兼容处理 Excel 2003 和 2007

引入了 poi-ooxml 以后就使用 XSSF 来处理,本以为 XSSF 既然能够处理 Excel 2007,那么 2003 也该能处理吧?得向下兼容不是?没想到不行!总不能用扩展名来区别是 2003 还是 2007 吧,后来发现了 WorkbookFactory 这个类,它的 create(InputStream inp) 方法可以根据版本来选择创建 HSSFWorkbook 还是 XSSFWorkbook,使用者无需关心版本的问题,非常方便!

# 以 String 的形式读取单元格的数据

要读取的 Excel 中有一些数据是数字的,单元格的类型是 Numberic 的,而我希望将单元格中的数据都以 String 的形式拿出来。于是当我看到 Cell.getStringCellValue() 这个方法的时候满心欢喜,但是当用了之后,这货居然直接给我一个异常,定眼一样,这方式是 getStringCellValue,而不是 getCellStringValue,真是瞎了眼了。

事实上,Cell 也根本没有 getCellStringValue 这样的方法,后来借助了 SOF,查到了一个方法:

row.getCell(j).setCellType(Cell.CELL_TYPE_STRING);
cellValue = row.getCell(j).getStringCellValue();


是的,就是先把单元格变成 String 类型的,然后再调用 getStringCellValue() 来获取数据,虽然这方法可行,但是总感觉有点猥琐,不知大家有没有更好的方法?

错误地使用 getPhysicalNumberOfCells()

遇到的最后一个坑就是使用了 getPhysicalNumberOfCells() 这个方法来获取一行中单元格的数量以对行的中单元格进行遍历,依靠这个方法来遍历会出现的情况就是如果行中间的某些单元格是空的,那么你就解析不到这一行最后的几个单元格,原因是因为按照文档的说明

Gets the number of defined cells (NOT number of cells in the actual row!). That is to say if only columns 0,4,5 have values then there would be 3.

这个方法只对有值的单元格进行计数,正确的遍历方法应该用 getFirstCellNum() 和 getLastCellNum() 来确定第一个单元格和最后一个单元格的位置,然后进行遍历,当然,要注意中间可能会出现空单元的情况,小心 NPE 异常。

另外,我发现很多 POI 的中文介绍资料上遍历 Excel 的样例代码都是采用了 getPhysicalNumberOfCells(),估计作者也没有经过彻底的测试,或者仔细阅读官方的文档和例子,平时大家做开发的时候,还是尽量找官方的介绍资料为好,看二手资料,一不小心就踩坑了。

相关推荐

# Python 3 # Python 3字典Dictionary(1)

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值(key=>value)对用冒号(:)分割,每个对之间用逗号(,)分割,整个字典包括在花括号({})中,格式如...

Python第八课:数据类型中的字典及其函数与方法

Python3字典字典是另一种可变容器模型,且可存储任意类型对象。字典的每个键值...

Python中字典详解(python 中字典)

字典是Python中使用键进行索引的重要数据结构。它们是无序的项序列(键值对),这意味着顺序不被保留。键是不可变的。与列表一样,字典的值可以保存异构数据,即整数、浮点、字符串、NaN、布尔值、列表、数...

Python3.9又更新了:dict内置新功能,正式版十月见面

机器之心报道参与:一鸣、JaminPython3.8的热乎劲还没过去,Python就又双叒叕要更新了。近日,3.9版本的第四个alpha版已经开源。从文档中,我们可以看到官方透露的对dic...

Python3 基本数据类型详解(python三种基本数据类型)

文章来源:加米谷大数据Python中的变量不需要声明。每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建。在Python中,变量就是变量,它没有类型,我们所说的"类型"是变...

一文掌握Python的字典(python字典用法大全)

字典是Python中最强大、最灵活的内置数据结构之一。它们允许存储键值对,从而实现高效的数据检索、操作和组织。本文深入探讨了字典,涵盖了它们的创建、操作和高级用法,以帮助中级Python开发...

超级完整|Python字典详解(python字典的方法或操作)

一、字典概述01字典的格式Python字典是一种可变容器模型,且可存储任意类型对象,如字符串、数字、元组等其他容器模型。字典的每个键值key=>value对用冒号:分割,每个对之间用逗号,...

Python3.9版本新特性:字典合并操作的详细解读

处于测试阶段的Python3.9版本中有一个新特性:我们在使用Python字典时,将能够编写出更可读、更紧凑的代码啦!Python版本你现在使用哪种版本的Python?3.7分?3.5分?还是2.7...

python 自学,字典3(一些例子)(python字典有哪些基本操作)

例子11;如何批量复制字典里的内容2;如何批量修改字典的内容3;如何批量修改字典里某些指定的内容...

Python3.9中的字典合并和更新,几乎影响了所有Python程序员

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

Python3大字典:《Python3自学速查手册.pdf》限时下载中

最近有人会想了,2022了,想学Python晚不晚,学习python有前途吗?IT行业行业薪资高,发展前景好,是很多求职群里严重的香饽饽,而要进入这个高薪行业,也不是那么轻而易举的,拿信工专业的大学生...

python学习——字典(python字典基本操作)

字典Python的字典数据类型是基于hash散列算法实现的,采用键值对(key:value)的形式,根据key的值计算value的地址,具有非常快的查取和插入速度。但它是无序的,包含的元素个数不限,值...

324页清华教授撰写【Python 3 菜鸟查询手册】火了,小白入门字典

如何入门学习python...

Python3.9中的字典合并和更新,了解一下

全文共2837字,预计学习时长9分钟Python3.9正在积极开发,并计划于今年10月发布。2月26日,开发团队发布了alpha4版本。该版本引入了新的合并(|)和更新(|=)运算符,这个新特性几乎...

python3基础之字典(python中字典的基本操作)

字典和列表一样,也是python内置的一种数据结构。字典的结构如下图:列表用中括号[]把元素包起来,而字典是用大括号{}把元素包起来,只不过字典的每一个元素都包含键和值两部分。键和值是一一对应的...

取消回复欢迎 发表评论:

请填写验证码