使用POI解析Excel

使用POI解析Excel

1、OpenXML标准
Word、Excel、PPT是Office办公套件中最常用的三个组件。早期的Office套件使用二进制格式,这里面包括以.doc、.xls、.ppt为后缀的文件;直到07这个划时代的版本将基于XML的压缩格式作为默认文件格式,也就是相应以.docx、.xlsx、.pptx为后缀的文件。

这个结合了XML与Zip压缩技术的新文件格式使用的是OpenXML标准。微软从2000年开始酝酿这项技术标准,到2006年申请成为ECMA-376,然后在Office2007中用作默认的文件格式,再到08年成为了ISO / IEC 29500国际标准,后续每两三年就会发布一个新版本。Office的一路凯歌无不彰显微软雄厚的实力。

所以说三流公司做产品,二流公司做平台,一流公司定标准。
微软的官方文档中详细介绍了WordprocessingML(Word)、SpreadsheetML(Excel)、PresentationML(PPT)三个标准,这里主要介绍Excel的部分内容。

首先Excel几个最基础的概念:

一个Excel就是一个工作簿(Workbook)
一个Sheet就是一张表格
一个Workbook可以包含多个Sheet
每一行Row的每一列就是一个单元格(Cell)

因为07版后的.xlsx本质上就是一个压缩包,我们完全可以用解压工具打开它。

一个基础的Excel解压之后

更典型的Excel还包括:数字、文本、公式、图表(Chart)、普通列表(Table)、数据透视表(Pivot Table)等内容。

Excel远比我们想象的复杂

2、使用POI操作Excel
Java领域最常见的两个操作Excel的工具库分别是JXL(Java Excel API)和Apache的POI。JXL有个严重的缺点就是只支持07版本之前的二进制格式Excel,而POI除了能操作Excel,还可以操作Word和PPT以及Office套装中其他的组件,高下立现。

POI全称是Poor Obfuscation Implementation,简洁模糊实现,也有人翻译成糟糕的模糊实现。

POI目前最新版本是4.0,可以将相应maven依赖添加到pom.xml文件中:

复制代码

org.apache.poi poi 4.0.0 org.apache.poi poi-ooxml 4.0.0 复制代码 POI提供了三种读写Excel的方式:

HSSF XSSF SXSSF

1、HSSF支持.xls为后缀的二进制格式,并提供了流解析模式的HSSFListener相关API以及基于内存模型的HSSFWorkbook相关API。

2、XSSF支持.xlsx为后缀的OpenXML格式。因为是底层文件是XML所以可以使用SAX解析,POI提供了XSSFReader用来获取压缩包中的各个XML文件相应的输入流;另外提供了基于DOM解析模式的XSSFWorkbook相关API。

3、POI3.8后提供了SXSSF API,它是基于XSSF构建的低内存占用版本(使用滑动窗口机制来实现低内存访问)。但是需要注意的是SXSSFWorkbook默认使用内联字符串而不是共享字符串表(SharedStringsTable),这样可以让保存在内存中的数据尽可能更少(SharedStringsTable需要常驻内存),所以如果是自己写SAX解析要注意兼容性。

POI滑动窗口只窗口范围内的单元格数据加载到内存中,窗口外的数据读写内容会以临时文件的形式保存到磁盘上,同时还支持临时文件的压缩。SXSSF可以通过构造函数中的rowAccessWindowSize参数指定窗口大小,
compressTmpFiles指定是否压缩临时文件,useSharedStringsTable指定是否使用共享字符表。

2.1、使用Workbook API
上面说的三种方式都有一个Workbook实现类,用法上基本一致。唯一不同的是SXSSFWorkbook最后需要调用dispose()方法处理磁盘上的临时文件。

下面是使用XSSFWorkbook读取.xlsx文件的例子:

// 打开指定位置的Excel文件
FileInputStream file = new FileInputStream(new File(fileLocation));
Workbook workbook = new XSSFWorkbook(file);
// 打开Excel中的第一个Sheet
Sheet sheet = workbook.getSheetAt(0);

// 读取Sheet中的数据
Map<Integer, List<String>> data = new HashMap<>();
int i = 0;
for (Row row : sheet) { // 行
    data.put(i, new ArrayList<String>());
    for (Cell cell : row) { // 单元格
        switch (cell.getCellType()) { // 不同的数据类型
            case STRING: ... break; // 字符串类型
            case NUMERIC: ... break; // 数值类型
            case BOOLEAN: ... break; // 布尔类型
            case FORMULA: ... break; // 公式类型
            case BLANK: ... break; // 空白类型
        }
    }
    i++;
}

POI有不同的方法来读取每种类型的数据:

switch(cel
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值