`
JonyUabka
  • 浏览: 12965 次
  • 性别: Icon_minigender_1
  • 来自: 东营
社区版块
存档分类
最新评论

POI 的兼容实现 兼容03和07的写法

阅读更多
在介绍该写法之前,为了不在此的走错误的方式,有以下总结点:
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<String,String>  rowappend=new HashMap<String,String>();
					 
					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.针对之前写的代码,近期我会对其进行性能测试和改进。
分享到:
评论
1 楼 JonyUabka 2011-09-27  
POI 尝试过如果读取2007 Excel 文件 的sheet 页数超过 10以上就会很慢,30个就会 out of memory 但 03 不会出现该种问题。 POI 两种版本测试都会如此, 3.6与3.7。 唯一比较稳定的版本为 3.6  该版本的 读取 03Excel 的sheet页的个数 相当稳定,但 3.7却没有想象的那么好。

相关推荐

Global site tag (gtag.js) - Google Analytics