在介绍该写法之前,为了不在此的走错误的方式,有以下总结点:
1.对POI的使用需要进行运行时异常的捕捉,否则连错误都不知道哪里出的。
2.POI对中文日期,也就是通过格式刷读取的内容都会作为数字去识别,对中文格式的样式不支持。
3.需要自己结合判断excel的日期和时间的区别,否则给出的结果也不是期望值。比如:12:00:00和1970-05-01都是敏感日期,也是作为日期和时间分割的临界点。
4.结合POI可以做出很强大的数据映射算法,该强大指的是从实用角度,灵活方便的对数据进行java的数据存储映射进行数据匹配工作。
配置jar文件列表:
POI-3.6-20091214.jar
POI-contrib-3.6-20091214.jar
POI-ooxml-3.6-20091214.jar
POI-ooxm.-schemas-3.6-20091214.jar
POI-scratchpad-3.6-20091214.jar
log4j-1.2.14.jar
(另外由于POI需要调用其他的jar包但POI官网也没提供下载,通过捕捉运行时异常才发现缺少该jar包)
xmlbeans-2.3.0.jar
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
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 TestPOI {
public void ExcelModel(String filename) throws FileNotFoundException{
int sheets=0;
FileInputStream fis = new FileInputStream(filename);
try{
//System.out.println(FilePath);
Workbook wb = null;
if (filename.endsWith(".xls")) {
// inp = new FileInputStream(FilePath);
wb = (Workbook) new HSSFWorkbook(new POIFSFileSystem(fis));
} else if (filename.endsWith(".xlsx")) {
wb = (Workbook) new XSSFWorkbook(fis);
}
Sheet childSheet = wb.getSheetAt(sheets);//默认第一页读取
for(int r=1; r < childSheet.getPhysicalNumberOfRows(); r++) {//循环该 子sheet 行数
String sheetname=childSheet.getSheetName();
System.out.println(sheetname );
Row row = childSheet.getRow(r);
if(row==null ){
System.out.println("第 " +r +" 行 为空行" ) ;
}
//System.out.println("childSheet " + (r+1) + "行数:: " + childSheet.getPhysicalNumberOfRows());
//System.out.println("childSheet 单元格的数目:: " + childSheet.getRow(r).getPhysicalNumberOfCells());
HashMap rowappend=new HashMap();
for (short c = 0; c < childSheet.getRow(r).getPhysicalNumberOfCells(); c++) {//循环该子sheet行对应的单元格项
Cell cell = childSheet.getRow(r).getCell(c);
//System.out.println("cell:: " + cell);
String value = null;
String temp=null;
if (cell == null)
continue;
//System.out.println("cell.getCellType():: " + cell.getCellType());
switch (cell.getCellType()) {
case HSSFCell.CELL_TYPE_NUMERIC:
if(DateUtil.isCellDateFormatted(cell)) {
//DateUtil.isCellDateFormatted(cell)
//此处再次判断时间和日期的类型分支
Date d = cell.getDateCellValue();
DateFormat formater = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String isTime=formater.format(d);
String Time= isTime.substring(0,isTime.lastIndexOf(" ") );
String Date = isTime.substring(isTime.lastIndexOf(" ")+1,isTime.length());
if(Time.equals("1900-01-05")){
isTime=isTime.substring(isTime.lastIndexOf(" ")+1);
value=""+isTime;
}else if(Date.equals("12:00:00")){
isTime=isTime.substring(0, isTime.lastIndexOf(" "));
value=""+isTime;
}else{
value=""+formater.format(d);
}
}else{
NumberFormat nf = NumberFormat.getInstance();
nf.setGroupingUsed(false);//true时的格式:1,234,567,890
double acno=cell.getNumericCellValue();
temp=nf.format(acno);
value=""+temp;
}
break;
case HSSFCell.CELL_TYPE_STRING:
String a=cell.getStringCellValue();
if(a.endsWith("null")||a.endsWith("NULL")||a.endsWith("Null")){
value="";
System.out.println("------------ 此处已经对null字符串进行了处理" );
}else {
value = cell.getStringCellValue();
}
break;
// 此处对用户删除数据后,单元格为null的处理
case HSSFCell.CELL_TYPE_BLANK:
{
value="";
}
;
break;
default:
}
System.out.println("value :: " + value);
}
}
}catch (Exception e) {
e.printStackTrace();
System.out.println("-----------------已运行transCount() : " + e);
}finally{
try {
fis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String args[]){
try{
TestPOI test = new TestPOI();
String testExcel = "C:/test.xlsx";
test.transCount(testExcel);
} catch (Exception e) {
System.out.println("已运行xlRead() : " + e);
}
}
}
经过了一段时间的测试 :该POI 存在一些性能问题如下
1.过多的sheet 页读取 wb.getNumberOfSheets() 会出现
java.lang.OutOfMemoryError: Java heap space
2.POI会对 2007 的excel 文件 读取生成一个 等大小的临时文件在
X:\apache-tomcat-5.5.26\temp\poifiles 下,反编译后读取源码发现,并没有对该文件进行删除。
3.针对之前写的代码,近期我会对其进行性能测试和改进。