java应用集锦8:使用poi进行excel操作,同时支持excel2003和2007

阅读更多

下面的这段代码仅仅支持excel2003,要同时支持2007和2003的excel请看后半部分!!

经常使用exlce的操作,以前工作使用的jxl,现在工作又使用poi.还好以前总结过,轻松搞定.这里再次把代码贴出来,可以直接使用.

package poi;

import java.util.List;

/**
 * 测试poi的工具类. 
 * 
 */
public class PoiUtil {
	public static void main(String[] args) {
		String fileName = "D:\\工作\\开发需求\\测试2.xls";
                //参数1:文件名
                //参数2:要读取的多个sheet的index
                //参数3:是否在遇到第一个空行时停止往下读取
                List strs1 = ExcelReader.readAllExcel(fileName, new String[]{"3","1","2"}, true);
		for (int i = 0; i < strs1.size(); i++) {
			System.out.println(getString2Array(strs1.get(i)));
		} 
	}

	public static String getString2Array(String[][] str) {
		StringBuffer buf = new StringBuffer("[");
		//System.out.println("行数:" + str.length);
		//System.out.println("列数:" + str[0].length);
		int len1 = str.length;
		int len2 = str[0].length;
		for (int i = 0; i < len1; i++) {
			for (int j = 0; j < len2; j++) {
				buf.append(str[i][j]);
				if (j != len2 - 1) {
					buf.append(",");
				} else {
					buf.append("\n");
				}
			}
		}
		buf.append("]");
		return buf.toString();
	} 
}

 ExcelReader.java(仅对2003的excel操作有效!)

package poi;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class ExcelReader {
    /**
     * 工作簿
     */
    private HSSFWorkbook workbook;

    /**
     * 日志记录
     */
    private Log log = LogFactory.getLog("logger");

    /**
     * excel表
     */
    private HSSFSheet sheet;

    /**
     * excel文件流
     */
    private FileInputStream fis;

    /**
     * 消息
     */
    private StringBuffer msg = null;


    public ExcelReader(File exl) throws IOException {
            fis = new FileInputStream(exl);
            workbook = new HSSFWorkbook(fis);
            msg = new StringBuffer();
    } 
    
	public ExcelReader(String exlFileName) throws IOException {
		File file = new File(exlFileName);
		fis = new FileInputStream(file);
		workbook = new HSSFWorkbook(fis);
		msg = new StringBuffer();
	}
    
	public ExcelReader(InputStream input) throws IOException {
		workbook = new HSSFWorkbook(input);
		msg = new StringBuffer();
	}

    public void destory() {
        try {
                msg = null;
                if(fis!=null)
                	fis.close();
        } catch (Exception ex) {
                log.error("ExcelReader-destory", ex);
                msg.append(ex.getMessage());
        }
    }

    public boolean setCurrentSheet(int num) {
            if (workbook != null && num < workbook.getNumberOfFonts()) {
                    try {
                            sheet = workbook.getSheetAt(num);
                            return true;
                    } catch (NullPointerException e) {
                            log.error("ExcelReader-setCurrentSheet", e);
                    }
            }        
            return false;
    }

    /**
     * 可以看到根据下面的五个参数确定了一个excel文件页面里面的一个矩形区域。
     * 
     * @param sheetNum
     *            文件的页面
     * @param firstRowNum
     *            第一行的行数
     * @param lastRowNum
     *            最后一行的行数
     * @param firstColIndex
     *            第一列的列数
     * @param lastColIndex
     *            最后一列的列数
     * @return
     */
    public String[][] getSheetAsTable(int sheetNum, int firstRowNum,
                    int lastRowNum, int firstColIndex, int lastColIndex) {
            String[][] cells = null;
            if (setCurrentSheet(sheetNum)) {
                    cells = new String[lastRowNum - firstRowNum + 1][lastColIndex
                                    - firstColIndex + 1];
                    int row = 0;
                    for (int c1 = firstRowNum; c1 <= lastRowNum; c1++) {
                            for (int c2 = firstColIndex; c2 <= lastColIndex; c2++) {
                                    try {
                                            cells[c1][c2] = getCellAsStringByIndex(c1, c2);
                                    } catch (Exception e) {
                                            log.error("ExcelReader-getSheetAsTable", e);
                                            cells[c1][c2] = "";
                                    }
                            }
                    }
            }
            return cells;
    }

    /**
     * 返回指定位置的单元格
     * 
     * @param rowId
     *            设置单元格的行
     * @param colId
     *            设置单元格的列
     * @return
     */
    public String getCellAsStringByIndex(int rowId, int colId) {
            String cellStr = "";
            if (sheet != null && rowId < sheet.getLastRowNum() + 1) {
                    try {
                            HSSFRow row = sheet.getRow(rowId);
                            if (row != null) {
                                    if (colId < row.getLastCellNum()) {
                                            HSSFCell cell = row.getCell((short) colId);
                                            if (cell != null) {
                                                    try {
                                                            switch (cell.getCellType()) {
                                                            case 0: {// CELL_TYPE_NUMERIC
                                                        if (HSSFDateUtil.isCellDateFormatted(cell)) { 
                					     Date d= HSSFDateUtil.getJavaDate(
                                   				  cell.getNumericCellValue());
                					  SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
                 				 		   cellStr = df.format(d);
            						}else{
                                                                    cellStr =Double.toString(cell.getNumericCellValue());   
             }
                                                                    break;
                                                            }
                                                            case 1: {// CELL_TYPE_STRING
                                                                    cellStr = cell.getStringCellValue();
                                                                    break;
                                                            }
                                                            case 2: {
                                                                    String formula = cell.getCellFormula();
                                                                    if (formula.indexOf("DATE(") >= 0) {
                                                                            Date d= HSSFDateUtil.getJavaDate(
                                                                                            cell.getNumericCellValue());
                                                                            SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
                                                                            cellStr = df.format(d);
                                                                    } else if (formula.indexOf("SUM(") >= 0) {
                                                                            cellStr = Double.toString(cell
                                                                                            .getNumericCellValue());
                                                                    }else if (formula.indexOf("SIN(") >= 0) {
                                                                            cellStr = Double.toString(cell
                                                                                            .getNumericCellValue());
                                                                    }
                                                                    else {
                                                                            cellStr = cell.getStringCellValue();
                                                                    }
                                                                    break;
                                                            }
                                                            case 4: {
                                                                    cellStr = Boolean.toString(cell.getBooleanCellValue());
                                                                    break;
                                                            }
                                                            default: {
                                                                    cellStr = new String("");
                                                            }
                                                                    if (cellStr == null) {
                                                                            cellStr = "";
                                                                    }
                                                            }
                                                    } catch (Exception e) {
                                                            log.error("ExcelReader-getCellAsStringByIndex", e);
                                                            cellStr = "";
                                                    }
                                            }
                                    }
                            }
                    } catch (Exception e) {
                            log.error("ExcelReader-getCellAsStringByIndex", e);
                            cellStr = "";
                    }
            }
            return cellStr;
    }
    
    /**
     * 返回指定sheet,指定行,指定列的单元格内容.
     * @param sheetNum
     * @param rowindex
     * @param colIndex
     * @return
     */
    public String getCellAsStringByIndex(int sheetNum,int rowindex,int colIndex)
    {
            if(setCurrentSheet(sheetNum)){
                    return getCellAsStringByIndex(rowindex,colIndex);
            }
            return "";
    }
    
    public void emptyCell(HSSFCell cell){
    	System.out.println(cell.getCellType());
    }
    
    public String getErrorMessage() {       
            return msg.toString();  
    }

    /**
     * 返回当前的页面
     * @return
     */
    public HSSFSheet getSheet() {
            return sheet;
    }

    /**
     * 返回当前的工作簿
     * @return
     */
    public HSSFWorkbook getWorkbook() {
            return workbook;
    }
    
    /**
	 * 
	 * @param fileName
	 *            要读取的excel文件名
	 * @param sheetNum
	 *            要读取的表单的数目
	 * @param row
	 *            要读取的单元格行数
	 * @param col
	 *            要读取的单元格列数
	 * @return
	 */
	public static String readExcel(String fileName, String sheetNum,
			String row, String col) { 
		try {
			ExcelReader excelRd = new ExcelReader(fileName);
			excelRd.setCurrentSheet(new Integer(sheetNum).intValue() - 1);
			return excelRd.getCellAsStringByIndex(
					(new Integer(row).intValue() - 1),
					(new Integer(col).intValue() - 1));
		} catch (Exception e) {
			e.printStackTrace();
			return "出现异常,可能是文件未找到!";
		}
	}

	/**
	 * 读取excel文件的一个表格里面的基本信息:最大行数
	 * 
	 * @param fileName
	 *            文件名
	 * @param sheetNum
	 *            要读取的表单的数目
	 * @return
	 */
	public static String readRowInfo(String fileName, String sheetNum) { 
		try {
			ExcelReader excelRd = new ExcelReader(fileName);
			excelRd.setCurrentSheet(new Integer(sheetNum).intValue() - 1);
			HSSFSheet sheet = excelRd.getSheet();
			int rowNum = sheet.getLastRowNum() + 1;
			return new Integer(rowNum).toString();
		} catch (Exception e) {
			e.printStackTrace();
			return "检查输入的文件是否存在或者页面不存在!";
		}
	}

	/**
	 * 读取excel中某一个表单的某一行的最大列数
	 * 
	 * @param fileName
	 *            文件名
	 * @param sheetNum
	 *            表单的数目
	 * @param row
	 *            行数
	 * @return
	 */
	public static String readColInfo(String fileName, String sheetNum,
			String row) { 
		ExcelReader excelRd;
		HSSFSheet sheet;
		HSSFRow rowNum;
		int colNum;
		try {
			excelRd = new ExcelReader(fileName);
			excelRd.setCurrentSheet(new Integer(sheetNum).intValue() - 1);
			sheet = excelRd.getSheet();
			rowNum = sheet.getRow(new Integer(row).intValue());
			colNum = rowNum.getLastCellNum();
			return new Integer(colNum).toString();
		} catch (Exception e) {
			e.printStackTrace();
			return "检查输入的文件是否存在!";
		}
	}

	/**
	 * 获取文件的工作簿的数目
	 * 
	 * @param fileName
	 *            文件名
	 * @return
	 */
	public static String readSheetInfo(String fileName) { 
		ExcelReader excelRd;
		HSSFWorkbook workbook;
		int sheetNum;
		try {
			excelRd = new ExcelReader(fileName);
			workbook = excelRd.getWorkbook();
			sheetNum = workbook.getNumberOfSheets();
			return new Integer(sheetNum).toString();
		} catch (Exception e) {
			e.printStackTrace();
			return "检查输入的文件是否存在!";
		}
	}

	/**
	 * 返回指定文件的页面的全部数据
	 * 
	 * @param fileName
	 *            文件名
	 * @param sheetNum
	 *            文件的表数
	 * @return String[][]
	 */
	public static String[][] readAllExcel(String fileName, String sheetNum) {
		return readAllExcel(fileName,sheetNum,false);
	}
	 
	public static List readAllExcel(String fileName, String[] sheetNums) {
		return readAllExcel(fileName,sheetNums,false);
	}
	
	public static List readAllExcel(String fileName, String[] sheetNums,
			boolean returnMeetFirstNullRow) {  
		ExcelReader excelRd;
		try {
			excelRd = new ExcelReader(fileName);
			return readAllExcel(excelRd, sheetNums, returnMeetFirstNullRow);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 返回指定文件的页面的全部数据,并指定是否在第一行遇到null的时候自动停止继续往下搜索 
	 * @param fileName
	 * @param sheetNum
	 * @param returnFirstNullRow
	 *            遇到第一个空行自动停止继续往下搜索.
	 * @return
	 */
	public static String[][] readAllExcel(String fileName, String sheetNum,
			boolean returnMeetFirstNullRow) {  
		ExcelReader excelRd;
		try {
			excelRd = new ExcelReader(fileName);
			return readAllExcel(excelRd, sheetNum, returnMeetFirstNullRow);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 返回指定文件的页面的全部数据
	 * @param input
	 * @param sheetNum
	 * @return
	 */
	public static String[][] readAllExcel(InputStream input, String sheetNum) {
		return readAllExcel(input,sheetNum,false);
	}
	
	/**
	 * 私有方法:返回指定excel中的指定sheet内容.
	 * @param excelRd
	 * @param sheetNum
	 * @param returnMeetFirstNullRow
	 * @return
	 */
	private static String[][] readAllExcel(ExcelReader excelRd, String sheetNum,
			boolean returnMeetFirstNullRow) {  
		String[] sheetNums = new String[]{sheetNum};
		List ans  = readAllExcel(excelRd,sheetNums,returnMeetFirstNullRow);
		return ans.get(0);
	}
	
	/**
	 * 一次返回多个sheet的内容.
	 * @param excelRd
	 * @param sheetNums
	 * @param returnMeetFirstNullRow
	 * @return
	 */
	private static List readAllExcel(ExcelReader excelRd, String[] sheetNums,
			boolean returnMeetFirstNullRow) {  
		//如果遇到第一个空行自动返回,调用下面的方法.
		List ans = new ArrayList(); 
		int sheetId;
		HSSFSheet sheet;
		int maxRowNum;
		HSSFRow row;
		int maxColNum;
		String[][] result;
		try { 
			for(int i=sheetNums.length-1;i>=0;i--){
				result = new String[][] {{}};
				sheetId = new Integer(sheetNums[i]).intValue() - 1;
				excelRd.setCurrentSheet(sheetId);
				sheet = excelRd.getSheet();
				//如果设置了要遇到第一个空行就自动返回,就计算maxRowNum!
				if (returnMeetFirstNullRow) {
					maxRowNum = 0;
					row = null;
					// 得到从0行开始的第一个非空行数.
					for (;; maxRowNum++) {
						row = sheet.getRow(maxRowNum);
						if (row == null) {
							if (maxRowNum != 0)
								maxRowNum--; 
							break;
						}
					}
				}
				//否则直接取全部的excel的行数
				else {
					maxRowNum = sheet.getLastRowNum();  
				} 
				if(maxRowNum!=0){
					// 得到第一行的列数.
					row = sheet.getRow(0);
					maxColNum = row.getLastCellNum();
					result = excelRd.getSheetAsTable(sheetId, 0, maxRowNum, 0,
							maxColNum - 1);
				}
				ans.add(result); 
			}
			excelRd.destory();
			return ans;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 返回指定文件的页面的全部数据
	 * @param input
	 * @param sheetNum
	 * @param returnMeetFirstNullRow 是否遇到空行直接返回
	 * @return
	 */
	public static String[][] readAllExcel(InputStream input, String sheetNum,
			boolean returnMeetFirstNullRow) {
		ExcelReader excelRd;
		try {
			excelRd = new ExcelReader(input);
			return readAllExcel(excelRd, sheetNum, returnMeetFirstNullRow);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 返回全部的指定sheet中的exlce内容.	 
	 * @param input
	 * @param sheetNums
	 * @return
	 */
	public static List readAllExcel(InputStream input, String[] sheetNums) {
		return readAllExcel(input,sheetNums,false);
	}
	
	/**
	 * 返回全部的指定sheet中的exlce内容.
	 * @param input
	 * @param sheetNums sheet字符串数组
	 * @param returnMeetFirstNullRow
	 * @return
	 */
	public static List readAllExcel(InputStream input,
			String[] sheetNums, boolean returnMeetFirstNullRow) {
		ExcelReader excelRd;
		try {
			excelRd = new ExcelReader(input);
			return readAllExcel(excelRd, sheetNums, returnMeetFirstNullRow);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}

 ExcelWrite.java

package poi;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;

public class ExcelWrite {
    /**
     * 工作簿
     */
    private HSSFWorkbook workbook;

    /**
     * 日志记录
     */
    private Log log = LogFactory.getLog("logger");

    /**
     * excel表
     */
    private HSSFSheet sheet;

    /**
     * excel文件流
     */
    private FileInputStream fis;

    /**
     * 消息
     */
    private StringBuffer msg = null;

    public ExcelWrite()
    {
            
    }
    /**
     * 从一个javaBean的集合向目标文件写数据
     * @param data 一个装有javaBean的list
     * @param targetFile 目标excel文件
     */
    public String setSheetFromTable(List data, String targetFile) {
            try {
                    HSSFWorkbook targetWorkbook = new HSSFWorkbook();
                    FileOutputStream fout = new FileOutputStream(targetFile,true);
                    setDataToWorksheet(data, targetWorkbook, 0);
                    targetWorkbook.write(fout);
                    fout.flush();
                    fout.close();
                    return "ok";
            } catch (Exception e) {
                    log.error("出现异常", e);
                    return "";
            }
    }

    /**
     * 将list的数据放进excel的一个工作表中去。
     * @param data 数据的来源list,是一个来自于数据库的装满了javabean的list
     * @param workbook 目的excel工作簿
     * @param sheetNum 目的excel工作簿的表格要填写数据的页码
     */
    public void setDataToWorksheet(List data,HSSFWorkbook workbook,int sheetNum)
    {
            HSSFRow title = null;
            HSSFSheet sheet = null;
            try{
            if(data.size()<1)
            {
                    return ;
            }
            sheet = workbook.createSheet();
            
            //下面设置cell的文字格式
            font = workbook.createFont();
            font.setFontName(HSSFFont.FONT_ARIAL);
            font.setUnderline((byte)1);
            font.setColor(HSSFColor.BLUE.index);
            //下面设置标题行的样式                
            titleStyle = workbook.createCellStyle();
            titleStyle.setBorderBottom((short)1);
            titleStyle.setBorderLeft((short)1);
            titleStyle.setBorderRight((short)1);
            titleStyle.setBorderTop((short)1);
            titleStyle.setFont(font);
            titleStyle.setFillForegroundColor(HSSFColor.LIGHT_CORNFLOWER_BLUE.index);
            titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
            
            //取list中的第一个数据,进行属性名称的读取,准备放到excel表格中的第一行
            Object aData = data.get(0);
            PropertyDescriptor[] props = Introspector.getBeanInfo(
                            aData.getClass(), Object.class).getPropertyDescriptors();
            //在表格的第一行建立一个数据行,用来放置这些属性的名称
            title = sheet.createRow(0);
            //设置行高.注意值设置的很大。。
            title.setHeight((short)500);
            for(short temp = 0; temp < props.length; temp++)
            {        HSSFCell cell = title.createCell(temp);
                    cell.setCellStyle(titleStyle);
                    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
                    cell.setCellValue(props[temp].getShortDescription());
                    //设置各个列的宽度
                    sheet.setColumnWidth((short)temp, (short)5000);
            }
            for(int temp = 0;temp 
 

 

 

同时支持excel2003和excel2007的java类:

对excel2003和excel2007使用的java类是不一样的,对于2003使用的java类前缀一般为HSSF,例如HSSFWorkbook,HSSFCell等,而对于2007前缀是XSSF,例如XSSFWorkbook类等.

下面的这个类创建一个workBook对象,并根据excel文件自动进行判断需要实例化2003的excel解析类还是2007的excel的解析类:

 

 
package poi;

import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;

import org.apache.poi.POIXMLDocument;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class WorkbookFactory {
	/**
	* Creates an HSSFWorkbook from the given POIFSFileSystem
	*/
	public static Workbook create(POIFSFileSystem fs) throws IOException {
	   return new HSSFWorkbook(fs);
	}
	/**
	* Creates an XSSFWorkbook from the given OOXML Package
	*/
	public static Workbook create(OPCPackage pkg) throws IOException {
	   return new XSSFWorkbook(pkg);
	} 
	
	public static Workbook create(InputStream inp) throws IOException, InvalidFormatException {
	    if(! inp.markSupported()) {
	    inp = new PushbackInputStream(inp, 8);
	   }
	  
	   if(POIFSFileSystem.hasPOIFSHeader(inp)) {
	    return new HSSFWorkbook(inp);
	   }
	   if(POIXMLDocument.hasOOXMLHeader(inp)) {
	    return new XSSFWorkbook(OPCPackage.open(inp));
	   }
	   throw new IllegalArgumentException("Your InputStream was neither an OLE2 stream, nor an OOXML stream");
	}
	}
	 

 

 

然后在调用生成workbook对象的时候,一律使用超类型即可,不要再使用HSSFWorkBook或者XSSFWorkBook的类型就行了!

例如下面的例子:ExcelReader.java,将其中的所有的构造函数中修改使用上面的create方法创建返回workBook对象即可!并且去掉所有前缀含有HSSF的类名即可!!

 

 

public ExcelReader(File exl) throws IOException {
            fis = new FileInputStream(exl);
            workbook = WorkbookFactory .create(fis);
            msg = new StringBuffer();
    } 
    
	public ExcelReader(String exlFileName) throws IOException {
		File file = new File(exlFileName);
		fis = new FileInputStream(file);
		workbook = WorkbookFactory .create(fis);
		msg = new StringBuffer();
	}
    
	public ExcelReader(InputStream input) throws IOException {
		workbook =WorkbookFactory .create(fis);
		msg = new StringBuffer();
	}
 

 

在实践中,遇到了这样的一个异常:

java.lang.NegativeArraySizeException
        at org.apache.poi.hssf.record.SSTDeserializer.readStringRemainder(SSTDeserializer.java:335)
        at org.apache.poi.hssf.record.SSTDeserializer.processContinueRecord(SSTDeserializer.java:320)
        at org.apache.poi.hssf.record.SSTRecord.processContinueRecord(SSTRecord.java:539)
        at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:216)
        at org.apache.poi.hssf.usermodel.HSSFWorkbook.(HSSFWorkbook.java:181)
        at org.apache.poi.hssf.usermodel.HSSFWorkbook.(HSSFWorkbook.java:228)
        at org.apache.poi.hssf.usermodel.HSSFWorkbook.(HSSFWorkbook.java:209)
 找了很久,结果换成使用最新的poi包,以及修改使用上面的create()创建新的workBook对象就可以了(后来不改这个类也可以,仅仅换包就行了),有点奇怪,不知道怎么引起的...

你可能感兴趣的:(Java,工作,Apache,Excel,单元测试)