cy_88 发表于 2017-1-1 10:21:44

【转】apache poi 读取excel

摘要: 适用于Microsoft Excel xls/xlsx两种类型电子表格的读取操作。
      网上关于介绍Apache POI操作Excel的文章已经很多了,但都讲得比较复杂。poi的API 与实际使用中的Excel很类似,可以说是POI把Excel中的workbook、sheet、cell等对象化了,在实际使用中极易理解。但由于Apache POI在存在已有不短时间,至少在excel2007之前就已经出现,造成同样一套Api并不能同时读取(写入)xls和xlsx两种类型的Excel文件。但poi对excel有一个很好的抽象(ss包下的Workbook、Sheet、Cell等类),可以一定程度上忽略xls/xlsx的处理细节,针对其通用部分进行处理,但如果需要对各自有理强的支持,还是建议使用相应的API。
    Apache POI 各个包功能描述:
      HSSF - 提供读写Microsoft Excel XLS格式档案的功能。
      XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。
      HWPF - 提供读写Microsoft Word DOC格式档案的功能。
      HSLF - 提供读写Microsoft PowerPoint格式档案的功能。
      HDGF - 提供读Microsoft Visio格式档案的功能。
      HPBF - 提供读Microsoft Publisher格式档案的功能。
      HSMF - 提供读Microsoft Outlook格式档案的功能。
下面给出一个简单的实现Demo:

package net.yeah.likun_zhang.excel;
import static net.yeah.likun_zhang.util.Debug.printf;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import net.yeah.likun_zhang.util.Debug;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
/**
* 读取Excel 97~2003 xls格式 /2007~ xlsx格式
* @authorZhangLiKun
* @maillikun_zhang@yeah.net
* @date2013-5-11
*/
public class ExcelReader {
/**
* 创建工作簿对象
* @param filePath
* @return
* @throws IOException
* @date2013-5-11
*/
public static final Workbook createWb(String filePath) throws IOException {
if(StringUtils.isBlank(filePath)) {
throw new IllegalArgumentException("参数错误!!!") ;
}
if(filePath.trim().toLowerCase().endsWith("xls")) {
return new HSSFWorkbook(new FileInputStream(filePath)) ;
} else if(filePath.trim().toLowerCase().endsWith("xlsx")) {
return new XSSFWorkbook(new FileInputStream(filePath)) ;
} else {
throw new IllegalArgumentException("不支持除:xls/xlsx以外的文件格式!!!") ;
}
}
public static final Sheet getSheet(Workbook wb ,String sheetName) {
return wb.getSheet(sheetName) ;
}
public static final Sheet getSheet(Workbook wb ,int index) {
return wb.getSheetAt(index) ;
}
public static final List<Object[]> listFromSheet(Sheet sheet) {
int rowTotal = sheet.getPhysicalNumberOfRows() ;
Debug.printf("{}共有{}行记录!" ,sheet.getSheetName() ,rowTotal) ;
List<Object[]> list = new ArrayList<Object[]>() ;
for(int r = sheet.getFirstRowNum() ; r <= sheet.getLastRowNum() ; r ++) {
Row row = sheet.getRow(r) ;
if(row == null)continue ;
// 不能用row.getPhysicalNumberOfCells(),可能会有空cell导致索引溢出
// 使用row.getLastCellNum()至少可以保证索引不溢出,但会有很多Null值,如果使用集合的话,就不说了
Object[] cells = new Object ;
for(int c = row.getFirstCellNum() ; c <= row.getLastCellNum() ; c++) {
Cell cell = row.getCell(c) ;
if(cell == null)continue ;
cells = getValueFromCell(cell) ;
}
list.add(cells) ;
}
return list ;
}

/**
* 获取单元格内文本信息
* @param cell
* @return
* @date2013-5-8
*/
public static final String getValueFromCell(Cell cell) {
if(cell == null) {
printf("Cell is null !!!") ;
return null ;
}
String value = null ;
switch(cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC :// 数字
if(HSSFDateUtil.isCellDateFormatted(cell)) {// 如果是日期类型
value = new SimpleDateFormat(DatePattern.LOCALE_ZH_DATE.getValue()).format(cell.getDateCellValue()) ;
} else value = String.valueOf(cell.getNumericCellValue()) ;
break ;
case Cell.CELL_TYPE_STRING:// 字符串
value = cell.getStringCellValue() ;
break ;
case Cell.CELL_TYPE_FORMULA:// 公式
// 用数字方式获取公式结果,根据值判断是否为日期类型
double numericValue = cell.getNumericCellValue() ;
if(HSSFDateUtil.isValidExcelDate(numericValue)) {// 如果是日期类型
value = new SimpleDateFormat(DatePattern.LOCALE_ZH_DATE.getValue()).format(cell.getDateCellValue()) ;
} else value = String.valueOf(numericValue) ;
break ;
case Cell.CELL_TYPE_BLANK:// 空白
value = ExcelConstants.EMPTY_CELL_VALUE ;
break ;
case Cell.CELL_TYPE_BOOLEAN:// Boolean
value = String.valueOf(cell.getBooleanCellValue()) ;
break ;
case Cell.CELL_TYPE_ERROR:// Error,返回错误码
value = String.valueOf(cell.getErrorCellValue()) ;
break ;
default:value = StringUtils.EMPTY ;break ;
}
// 使用[]记录坐标
return value + "["+cell.getRowIndex()+","+cell.getColumnIndex()+"]" ;
}
}




测试类

package net.yeah.likun_zhang.excel;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import net.yeah.likun_zhang.BaseTest;
import net.yeah.likun_zhang.util.Debug;
import net.yeah.likun_zhang.util.ToString;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.Test;
/**
* 读取
* @authorZhangLiKun
* @maillikun_zhang@yeah.net
* @date2013-5-8
*/
public class ExcelReaderTest extends BaseTest{
@Test
public void testRead() throws FileNotFoundException, IOException {
Workbook wb = ExcelReader.createWb("src/main/resources/excels/demo-3.xlsx") ;
// 获取Workbook中Sheet个数
int sheetTotal = wb.getNumberOfSheets() ;
Debug.printf("工作簿中的工作表个数为:{}" ,sheetTotal);
// 获取Sheet
Sheet sheet = ExcelReader.getSheet(wb, 0) ;
// 遍历Sheet
List<Object[]> list = ExcelReader.listFromSheet(sheet) ;
Debug.printf(list, new ToString<Object[]>(){
private int index = 1 ;
@Override
public String toString(Object[] t) {
if(t == null || t.length == 0)return StringUtils.EMPTY ;
StringBuffer sb = new StringBuffer(index ++ + ":") ;
for(int i = 0 ,len = t.length ; i < len ; i++) {
sb.append(t + ",") ;
}
return sb.toString();
}
}) ;
}
}


测试辅助类

package net.yeah.likun_zhang.util;
import java.util.Collection;
import java.util.Iterator;
import org.apache.commons.lang3.ArrayUtils;
/**
* Debug函数库
* @authorZhangLiKun
* @maillikun_zhang@yeah.net
* @date2013-5-8
*/
public class Debug {
/**
* 打印函数
* @param objects
* @date2013-5-8
*/
public static final void printf(String msg ,Object ...objects) {
if(ArrayUtils.isEmpty(objects)) {
System.out.println(msg);
return ;
}
for(int i = 0 ,len = objects.length ; i < len ; i ++) {
Object obj = objects ;
msg = msg.replaceFirst("\\{\\}", obj == null ? "" : obj.toString()) ;
}
System.out.println(msg);
}
/**
* 打印函数
* @param obj
* @date2013-5-8
*/
public static final void printf(Object obj) {
if(obj != null){
System.out.println(obj.toString());
}
}
/**
* 打印集合
* @param list
* @param ts
* @date2013-5-8
*/
public static final <T> void printf(Collection<T> list ,ToString<T> ts) {
if(list == null || list.isEmpty()) return ;
Iterator<T> iter = list.iterator() ;
while(iter.hasNext()) {
T t = iter.next() ;
//if(t == null)continue ;
if(ts == null) {
System.out.println(t.toString());
} else {
String msg = ts.toString(t) ;
//if(msg != null) {
System.out.println(msg);
//}
}
}
}
}
页: [1]
查看完整版本: 【转】apache poi 读取excel