java实现Excel导入(迭代一)
poi版本的变更历史记录:http://poi.apache.org/changes.html
目录
-
1.准备工作
-
2.Excel导入代码及demo
-
3.Excel导入的时候遇到的坑.
1.准备工作
1.对JDK5的支持,最后版本是POI-3.10-FINAL;从POI-3.11-beta1开始,最低支持JDK6。从POI4.0.0Removed support for Java 6 and 7 making Java 8 the minimum version supported
2.POI-3.5开始提供对xlsx格式的支持,而此前版本只支持xls格式。
3.xlsx实质上是ooxml格式,使用xml记录数据,用ZIP打包压缩,后缀名修改为xlsx。
4.maven依赖:
<!-- commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- excel导入 poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
2.Excel导入代码及demo
package com.wuage.clm.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.commons.io.FilenameUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellValue;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
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;
public class ExcelImportUtil {
/**
* Excel 2003
*/
private final static String XLS = "xls";
/**
* Excel 2007
*/
private final static String XLSX = "xlsx";
/**
* 分隔符
*/
private final static String SEPARATOR = "=";
/**
* 由Excel文件的Sheet导出至List
*
* @param file
* @param sheetNum
* @return
*/
public static List<String> exportListFromExcel(File file, int sheetNum) throws IOException {
return exportListFromExcel(new FileInputStream(file), FilenameUtils.getExtension(file.getName()), sheetNum);
}
/**
* 由Excel流的Sheet导出至List
*
* @param is
* @param extensionName
* @param sheetNum
* @return
* @throws IOException
*/
public static List<String> exportListFromExcel(InputStream is, String extensionName, int sheetNum)
throws IOException {
Workbook workbook = null;
if (extensionName.toLowerCase().equals(XLS)) {
workbook = new HSSFWorkbook(is);
} else if (extensionName.toLowerCase().equals(XLSX)) {
workbook = new XSSFWorkbook(is);
}
return exportListFromExcel(workbook, sheetNum);
}
/**
* 由指定的Sheet导出至List
*
* @param workbook
* @param sheetNum
* @return
* @throws IOException
*/
private static List<String> exportListFromExcel(Workbook workbook, int sheetNum) {
Sheet sheet = workbook.getSheetAt(sheetNum);
// 解析公式结果
FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
List<String> list = new ArrayList<String>();
int minRowIx = sheet.getFirstRowNum() + 1;
int maxRowIx = sheet.getLastRowNum();
System.out.println("总行数:" + maxRowIx + "最小行数:" + minRowIx);
for (int rowIx = minRowIx; rowIx <= maxRowIx; rowIx++) {
Row row = sheet.getRow(rowIx);
StringBuilder sb = new StringBuilder();
short minColIx = row.getFirstCellNum();
short maxColIx = row.getLastCellNum();
System.out.println("总列数:" + maxColIx);
for (short colIx = minColIx; colIx <= maxColIx; colIx++) {
Cell cell = row.getCell(new Integer(colIx));
CellValue cellValue = evaluator.evaluate(cell);
if (cellValue == null) {
sb.append(SEPARATOR + "");
continue;
}
// 经过公式解析,最后只存在Boolean、Numeric和String三种数据类型,此外就是Error了
// 其余数据类型,根据官方文档,完全可以忽略http://poi.apache.org/spreadsheet/eval.html
switch (cellValue.getCellTypeEnum()) {
case BOOLEAN:
sb.append(SEPARATOR + cellValue.getBooleanValue());
break;
case NUMERIC:
// 这里的日期类型会被转换为数字类型,需要判别后区分处理
if (DateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
if (date != null) {
sb.append(SEPARATOR + new SimpleDateFormat("yyyy-MM-dd").format(date));
} else {
sb.append(SEPARATOR + "");
}
} else {
// 注意,如果在excel中的值为数字,一般是double类型的,而这个数字是不是真正的double类型,或者是你想要的数字,就用下面这个判断
// 如果匹配下面的正则表达式,说明可能是double,如果不匹配一定是double
DecimalFormat decimalFormat = new DecimalFormat("#.000000");
String resultStr = decimalFormat.format(new Double(cell.getNumericCellValue() + ""));
if (resultStr.matches("^[-+]?\\d+\\.[0]+$")) {
sb.append(SEPARATOR + resultStr.substring(0, resultStr.indexOf(".")));
} else {
sb.append(SEPARATOR + cell.getNumericCellValue() + "");
}
}
break;
case STRING:
sb.append(SEPARATOR + cellValue.getStringValue());
break;
case FORMULA:
sb.append(SEPARATOR + cellValue.getStringValue());
break;
case BLANK:
sb.append(SEPARATOR + "");
break;
case ERROR:
sb.append(SEPARATOR + "");
break;
default:
sb.append(SEPARATOR + "");
break;
}
}
list.add(sb.toString());
}
return list;
}
}
TestJava类
public static void main(String[] args) {
String path = "C:\\Users\\Administrator\\Desktop\\importExcel.xlsx";
List<String> list = null;
try {
// ====================== 这个就是导入的excel返回的JSON数据============================start
list = ExcelImportUtil.exportListFromExcel(new File(path), 0);
System.out.println(JSON.toJSONString(list));
// ====================== 这个就是导入的excel返回的JSON数据============================end
} catch (IOException e) {
}
}
3.Excel导入的时候遇到的坑.
声明:一下是我在做excel批量导入的时候发现的问题,记录下,如果以便以后再工作中遇到这个问题方便查找。
switch (cell.getCellType()) {
case Cell.CELL_TYPE_STRING:
value = cell.getStringCellValue();
break;
case Cell.CELL_TYPE_NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
Date date = cell.getDateCellValue();
if (date != null) {
value = new SimpleDateFormat("yyyy-MM-dd").format(date);
}
else {
value = "";
}
}
else {
//注意,如果在excel中的值为数字,一般是double类型的,而这个数字是不是真正的double类型,或者是你想要的数字,就用下面这个判断
//如果匹配下面的正则表达式,说明可能是double,如果不匹配一定是double
DecimalFormat decimalFormat = new DecimalFormat("#.000000");
String resultStr = decimalFormat.format(new Double(cell.getNumericCellValue() + ""));
if (resultStr.matches("^[-+]?\\d+\\.[0]+$")) {
value = resultStr.substring(0, resultStr.indexOf("."));
}
else {
value = cell.getNumericCellValue() + "";
}
}
break;
case Cell.CELL_TYPE_FORMULA:
// 导入时如果为公式生成的数据则无值
if (!cell.getStringCellValue().equals("")) {
value = cell.getStringCellValue();
}
else {
value = cell.getNumericCellValue() + "";
}
break;
case Cell.CELL_TYPE_BLANK:
break;
case Cell.CELL_TYPE_ERROR:
value = "";
break;
case Cell.CELL_TYPE_BOOLEAN:
value = (cell.getBooleanCellValue() == true ? "Y" : "N");
break;
default:
value = "";
}