最近要完成一个根据模板将Excel数据批量导入数据库的业务
本打算用Kettle,但是客户提供的Excel模板实在太乱,Spoon没办法完成解析,只好打算手动实现
poi框架可以实现对MS Office文档的查看、修改功能,实际Kettle对Excel识别模块也是用poi框架完成的,这里我们只需要引用Excel关联的模块
给出Maven Dependency:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
其中poi是Office 2003格式的标准库,poi-ooxml是Office 2007的扩展库
对于Excel来说,处理的根节点就是Workbook接口,对应2003(xls)和2007(xlsx)格式分别有两个实现类:HSSFWorkbook和XSSFWorkbook
之后对应的还有HSSFSheet和XSSFSheet、HSSFRow和XSSFRow、HSSFCell和XSSFCell
当然,这几个类分别都实现了Sheet接口、Row接口、Cell接口
所以当不确定文件格式的时候只要在创建Workbook的时候创建对应的Workbook实现类,之后都可以直接使用接口进行通用操作
而创建对应的Workbook实现类也在poi内部有所实现:
Workbook workbook = WorkbookFactory.create(inputStream);
传入的是一个包含文件数据的InputStream。当然create方法在WorkbookFactory中重载了多次,具体可以自行参考源码和API
注意的是WorkbookFactory在create Workbook对象的时候,若传入的文件流根本不是Excel格式的时候会抛出一个RuntimeException的继承类IllegalArgumentException,因为继承自RuntimeException,所以不会要求捕获。如果传入文件接口是开放的时候需要手动去try cache这个Exception
调用WorkbookFactory的create方法生成Workbook方法比手动判断文件后缀更安全有效,毕竟文件可能被修改过后缀名。
-------------------------------------------------------
有效表格范围
poi只能获取大致的有效表格范围,并且只能得到行范围,列范围需要遍历Row对象以后取最大值得到。但是这个范围不一定准确,常常把空白行和列包含进去,poi的判断应该是未被修改过格式且玩诶空值。当然只会多不会少。如果对格式要求比较高可能需要手动去过滤掉空行空列
poi内置有一个类表示表格范围:CellRangeAddress,这个类是用来表示合并单元格的范围的,但是用来表示表格的有效范围也适用
---------------------------------------------------------
合并单元格
合并单元格对象需要在Sheet对象中得到。无法在Cell对象中获取
可以用Sheet接口的getNumMergedRegions()取得数量,再用getMergedRegion(index)方法得到每个合并单元格范围,得到的是CellRangeAddress对象
List<CellRangeAddress> mergedRegions = new ArrayList<CellRangeAddress>();
int cellCount = sheet.getNumMergedRegions();
for (int index=0;index<cellCount;index++){
mergedRegions.add(sheet.getMergedRegion(index));
}
return mergedRegions;
---------------------------------------------------------
合并单元格内容读取
合并单元格内部只有左上角的单元格坐标可以得到合并单元格的值,其他坐标单元格只能得到一个空字符串。因此需要事先遍历合并单元格列表检查当前单元格坐标是否在某个合并单元格内部,然后以合并单元格左上角坐标代替当前坐标读取内容即可
而判断方法在CellRangeAddress内有封装,即isInRange(row,col)
private Cell checkInMergedRegion(int row,int col){
for (CellRangeAddress mergedAddress:mergedRegions){
if (mergedAddress.isInRange(row,col)){
return getCell(mergedAddress.getFirstRow(),mergedAddress.getFirstColumn());
}
}
return getCell(row, col);
}
private Cell getCell(int rowNumber,int colNumber){
Row row = sheet.getRow(rowNumber);
return row.getCell(colNumber);
}
--------------------------------------------------------
读取单元格内容
首先获取Cell的内容类型,分为5种,分别为空白、字符串、数字、公式、布尔。根据不同类型做对应处理。
注意的是公式类型的处理。可以调用cell.getNumericCellValue()方法直接获得公式计算结果。
private String getCellStringValue(Cell cell) {
int type = cell.getCellType();
switch (type) {
case Cell.CELL_TYPE_BLANK:
case Cell.CELL_TYPE_STRING:
return cell.getStringCellValue();
case Cell.CELL_TYPE_NUMERIC:
case Cell.CELL_TYPE_FORMULA:
//取得数值并取两位小数,同时转为字符串
return roundNumber(cell.getNumericCellValue(), 2);
case Cell.CELL_TYPE_BOOLEAN:
return cell.getBooleanCellValue() + "";
default:
return "ERROR VALUE";
}
}
---------------------------------
百分数的处理
excel中的百分数在poi中并没有做特别的处理,其默认类型是Cell.CELL_TYPE_NUMERIC,所以如果不做特别处理的话取出来的将是这个百分数对应的小数的值。如果需要对百分数做特别处理的情况(如将百分数作为字符串提取出来)就必须判断本单元格是否为百分数。
在cell.getCellType()中是得不到想要的结果的,不过poi提供了另一种方式:
cell.getCellStyle().getDataFormatString()
例如保留一位小数的百分数调用此方法将得到这样一个字符串:
0.0%
因此,剩下的我们只需要判断这个dataFormatString中是否包含百分号即可确认是百分数。剩下的就是把取得的double值乘以100并在结尾加上个百分号即可
分享到:
相关推荐
"POI学习笔记" POI(Apache POI)是一款流行的Java库,用于处理Microsoft Office文件格式,包括Excel、Word、PowerPoint等。POI提供了一个简洁和灵活的API,允许开发者轻松地读取、写入和操作Office文件。 POI的...
### POI学习笔记知识点解析 #### 一、POI简介 Apache POI是一个开源的Java API,用于处理Microsoft Office格式的文件,包括Excel (.xls, .xlsx), PowerPoint (.ppt, .pptx) 和 Word (.doc, .docx)。POI提供了一套...
Spring MVC 是一个基于Java的轻量级Web应用框架,它为构建MVC(Model-View-Controller)架构的Web应用...通过阅读和学习提供的PDF和Excel格式的学习笔记,你可以深入了解其工作原理,从而在实际项目中得心应手地使用。
【CRMSys项目笔记】 CRMSys项目是一个典型的...综上所述,CRMSys项目笔记涵盖了从源码解析到工具应用,再到具体功能实现的广泛内容。通过深入学习和实践,我们可以增强自己的软件开发技能,特别是在CRM系统开发领域。
【everynote云笔记】是一个集合了个人学习心得与网络精华的资源库,涵盖了广泛的IT技术领域,特别是Java编程和分布式计算。以下是对压缩包中各文件内容的详细解读: 1. **BTrace 指南.html**:BTrace是一款强大的...
这表明学习者可以期待一系列详细的教学,逐步解析乐优商城的开发过程。 【标签】"黑马"、"乐优"、"商城"这三个标签有助于我们理解课程的核心内容。"黑马"通常指的是黑马程序员,这是一个知名的编程教育平台,以其...
《SSM商务平台项目源码解析与学习指南》 在IT行业中,Java Web项目是企业级应用开发的重要领域,SSM框架(Spring、SpringMVC、MyBatis)因其灵活性和强大功能,成为开发者们首选的技术栈。本资源提供了一个完整的...
在IT领域,桌面搜索是一种非常实用的技术,它允许用户快速高效地在...其背后的实现涵盖了文件处理、数据索引、搜索算法、用户交互等多个IT领域的核心知识点,对于学习和开发类似应用的开发者来说具有很高的参考价值。