POI讀寫excel

前段時間做項目用到POI解析excel並且往excel中寫數據,一直沒空下時間來寫自己的實現,現在把解析和讀取的方法共享下:

讀取excel時:POI提供兩種API一種解析xls格式的一種解析xlsx格式的我分別來說:

package com.test.ajing.util;
/**
 * 讀取excel demo
 */
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;


import org.apache.poi.hssf.model.InternalSheet;
import org.apache.poi.hssf.record.DVRecord;
import org.apache.poi.hssf.record.aggregates.DataValidityTable;
import org.apache.poi.hssf.record.formula.Ptg;
import org.apache.poi.hssf.usermodel.HSSFCell;
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.ss.formula.Formula;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DataValidationConstraint.ValidationType;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


public class PoiUtil {


public static void main(String[] args)throws Exception {
// readExcelXlsx("f:\\mergion.xlsx",0);
readExcelXsl("f:\\ceshi.xls",0);
}


/******************read xlsx excel start*******************************/
/**
* 讀取excel .xlsx擴展名的
* @param fileName 文件的絕對路徑
* @param sheetIndex sheet索引
*/
public static void readExcelXlsx(String fileName,int sheetIndex){
try {
 
//創建workbook
XSSFWorkbook workbook=new XSSFWorkbook(fileName);
XSSFSheet sheet = workbook.getSheetAt(sheetIndex);
//獲取表格中實際的最大行數
int lastRowNum = sheet.getLastRowNum();
//獲取表格中實際的最大列數
int maxCols= getXlsxMaxColum(sheet);
System.out.println("numer==="+sheet.getNumMergedRegions());
for(int i=0;i<lastRowNum;i++){
for(int j=0;j<maxCols;j++){
XSSFCell cell = sheet.getRow(i).getCell(j);
if (cell==null) {
// System.out.println("單元格爲空===");
}else if(xlsxMergedType(cell, getXlsxMergedRange(sheet))==1){
// System.out.println("合併單元格=第一個"+cell.getReference()+";x="+cell.getRowIndex());
// System.out.println("y="+cell.getReference()+";x="+cell.getRowIndex()
// +";type="+cell.getCellType()/*+";data="+cell.getDateCellValue()+
// ";formula="+cell.getCellFormula()+";type="+cell.getCellType()*/
// );
}else if (xlsxMergedType(cell, getXlsxMergedRange(sheet))==2) {
// System.out.println("其它合併單元格不必記錄");
}else{

if (cell.getCellType()==XSSFCell.CELL_TYPE_BLANK) {//此代表不爲空的單元格但是有顏色
// System.out.println("y==="+cell.getReference()+";x="+cell.getRowIndex());
}else if (cell.getCellType()==XSSFCell.CELL_TYPE_FORMULA) {//讀取規則單元格
// System.out.println("CELL_TYPE_FORMULA=="+cell.getCellFormula());
}else if (cell.getCellType()==XSSFCell.CELL_TYPE_NUMERIC) {//讀取數字單元格
// System.out.println("x="+cell.getRowIndex()+";y="+cell.getReference());
// System.out.println("x="+cell.getRowIndex()+";y="+cell.getReference());
// System.out.println("CELL_TYPE_NUMERIC=="+cell.getNumericCellValue());
// System.out.println("CELL_TYPE_NUMERIC=="+cell.get);

}else if (cell.getCellType()==XSSFCell.CELL_TYPE_STRING) {
// System.out.println("CELL_TYPE_STRING");
}else {
System.out.println("y==="+cell.getReference()+";x="+cell.getRowIndex());
System.out.println("cellType== "+cell.getCellType());
}
}
}
}
 
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 單獨解析下拉列表框和取值範圍的單元格
* @param sheet
*/
public static void parseDropDownList(XSSFSheet sheet){
List<XSSFDataValidation> dataValidations = sheet.getDataValidations();

for(XSSFDataValidation data:dataValidations){
//如果數據類型是ANY類型則是限制範圍的例如[1,20]此時取規則是Formula1和Formula2都取
if (data.getValidationConstraint().getValidationType()==ValidationType.INTEGER) {
// System.out.println("取值範圍1="+data.getValidationConstraint().getFormula1());
// System.out.println("取值範圍2="+data.getValidationConstraint().getFormula2());
}else if (data.getValidationConstraint().getValidationType()==ValidationType.LIST) {
//是下拉列表框一次全取出來執行Formula1即可
// System.out.println("下拉列表框的值="+data.getValidationConstraint().getFormula1());
}
}

}

/**
* 取得sheet中最大列數,
* @param sheet
* @return
*/
public static int getXlsxMaxColum(XSSFSheet sheet){
int max=0;
//得到最大行數循環行數
int maxRow = sheet.getLastRowNum();
for(int i=0;i<maxRow;i++){
if (max<sheet.getRow(i).getLastCellNum()) {
max=sheet.getRow(i).getLastCellNum();
}
}
return max;
}
/**
* 獲取合併單元格集合
* @param sheet
* @return
*/
public static List<CellRangeAddress> getXlsxMergedRange(XSSFSheet sheet){
List<CellRangeAddress> addresses = new ArrayList<CellRangeAddress>();
int sum=sheet.getNumMergedRegions();
if (sum>0) {
for(int i=0;i<sum;i++){
addresses.add(sheet.getMergedRegion(i));
}
}
return addresses;
}

/**
* 判斷此單元格類型 如果是0爲普通單元格,爲1爲合併單元格第一個,如果爲2是其它合併單元格不必記錄
* @param cell 要判斷的單元格
* @param mergedList 合併單元格集合
*/
public static int xlsxMergedType(XSSFCell cell,List<CellRangeAddress> mergedList){
int cellRow=cell.getRowIndex();
int cellCol=cell.getColumnIndex();
int type=0;
for(CellRangeAddress address : mergedList){
if (cellRow>=address.getFirstRow()&&cellRow<=address.getLastRow()
&&cellCol>=address.getFirstColumn()&&cellCol<=address.getLastColumn()) {
if (cellRow==address.getFirstRow()&&cellCol==address.getFirstColumn()) {
type=1;
}else{
type= 2;
}
}else{
continue;
}
}
return type;
}
/******************read xlsx excel end*******************************/




/*****

* 以下代碼爲讀取xls格式的excel


*/
/******************read xls excel start*******************************/
public static void readExcelXsl(String fileName,int sheetIndex){

//得到workbook
HSSFWorkbook workbook;
try {
workbook = new HSSFWorkbook(new FileInputStream(fileName));
HSSFSheet sheet = workbook.getSheetAt(sheetIndex);
processInternalSheet(sheet);
// getXlsType(null,sheet);
int firstRow = sheet.getFirstRowNum();
int lastRow = sheet.getLastRowNum();
for(;firstRow<lastRow;firstRow++){
HSSFRow hssfRow = sheet.getRow(firstRow);
if (hssfRow!=null) {
for(int i=0;i<getXlsMaxColum(sheet);i++){
HSSFCell cell = hssfRow.getCell(i);
if (cell==null) {
// System.out.println("此單元格爲空");
}else if (getXlsType(cell,sheet)==0) {
if (cell.getCellType()==Cell.CELL_TYPE_NUMERIC) {

}else if (cell.getCellType()==Cell.CELL_TYPE_FORMULA) {

}else if (cell.getCellType()==Cell.CELL_TYPE_STRING) {

}
}else if (getXlsType(cell,sheet)==1) {
// System.out.println("合併單元格存取值:row="+cell.getRowIndex()+",colum="+cell.getColumnIndex());
}
}
}

}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

}


public static int getRowColun(HSSFCell cell,HSSFSheet sheet){


int sumMerged = sheet.getNumMergedRegions();
int resultType=0;
if (cell==null||sheet==null) {
return resultType;
}
for(int i=0;i<sumMerged;i++){
CellRangeAddress address = sheet.getMergedRegion(i);
if (address.getFirstRow()==cell.getRowIndex()&&address.getFirstColumn()==cell.getColumnIndex()) {
// resultType=(address.getLastRow()-address.getFirstRow())==0?0:;
}
}
return resultType;
}

/**
* 判斷單元格是否爲合併單元格中的一個 返回值:如果爲0說明是未合併單元格
* 如果是1說明是應該存取的第一個單元格,如果是2就是其它的合併單元格不需要存儲
* @param cell
* @param sheet
* @return
*/
public static int getXlsType(HSSFCell cell,HSSFSheet sheet){

int sumMerged = sheet.getNumMergedRegions();
int resultType=0;
if (cell==null||sheet==null) {
return resultType;
}
for(int i=0;i<sumMerged;i++){
CellRangeAddress address = sheet.getMergedRegion(i);
if (address.getFirstRow()==cell.getRowIndex()&&address.getFirstColumn()==cell.getColumnIndex()) {
resultType=1;
}else if (address.getFirstRow()<cell.getRowIndex()&&address.getFirstColumn()<cell.getColumnIndex()
&&address.getLastRow()>=cell.getRowIndex()&&address.getLastColumn()>=cell.getColumnIndex()) {
resultType=2;
}
// System.out.println("fristrow=="+address.getFirstRow()+";fristcolum="+address.getFirstColumn()+";lastrow="
// +address.getLastRow()+";lastcolum="+address.getLastColumn());
}
return resultType;
}

/**
* 獲得最大列
* @param sheet
* @return
*/
public static int getXlsMaxColum(HSSFSheet sheet){

int maxColum=0;
int firstRow = sheet.getFirstRowNum();
int lastRow = sheet.getLastRowNum();
for(;firstRow<lastRow;firstRow++){
HSSFRow hssfRow = sheet.getRow(firstRow);
if (hssfRow!=null) {
if (maxColum<hssfRow.getLastCellNum()) {
maxColum=hssfRow.getLastCellNum();
}else{
continue;
}
}else{
continue;
}

}
// System.out.println("maxColum==="+maxColum);
return maxColum;

}

/**
* 讀取下拉列表框和數據範圍的單元格單獨處理
* @param sheet
* @throws UnsupportedEncodingException 
*/
public static void processInternalSheet(HSSFSheet sheet) throws UnsupportedEncodingException{
try {

//得到解析下拉列表框的和限制範圍規則的的InternalSheet
InternalSheet internalSheet = getFieldObject(sheet,"_sheet");
DataValidityTable tables = internalSheet.getOrCreateDataValidityTable();
//得到記錄集合(是規則類型)單元格的規則是相同的爲一個
List<DVRecord> dvRecords  = getFieldObject(tables,"_validationList");
// System.out.println("dvRecords=="+dvRecords.size());
for(DVRecord record:dvRecords){
CellRangeAddressList addresses = record.getCellRangeAddress();
CellRangeAddress[] CellRangeAddress=addresses.getCellRangeAddresses();
for(int i=0;i<CellRangeAddress.length;i++){
// System.out.println("record.getDataType()==="+record.getDataType());
CellRangeAddress address = CellRangeAddress[i];
// System.out.println("cell firstrow=="+address.getFirstRow()+";firstcolum="+address.getFirstColumn()
// +";lastrow="+address.getLastRow()+";lastcolums="+address.getLastColumn()
// );

}
if (record.getDataType()==ValidationType.INTEGER) {
Formula formula1 = (Formula)getFieldObject(record,"_formula1");
Formula formula2 = (Formula)getFieldObject(record,"_formula2");
// System.out.println("toStringFormula1=="+toStringFormula(formula1));
// System.out.println("toStringFormula2=="+toStringFormula(formula2));
}else if (record.getDataType()==ValidationType.LIST) {
Formula formula1 = (Formula)getFieldObject(record,"_formula1");

System.out.println("toStringFormula=="+toStringFormula(formula1));
String[] t = toStringFormula(formula1).split("");
for(String str:t){
System.out.println("length=="+str);
}
}
}
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch blockl
e.printStackTrace();
}
}
/**
* 得到 某個類上的某個屬性
* @param obj 傳入的對象
* @param fieldName  對象身上的字段名
* @return
* @throws SecurityException
* @throws NoSuchFieldException
* @throws IllegalArgumentException
* @throws IllegalAccessException
*/
@SuppressWarnings("unchecked")
public static <T> T  getFieldObject(Object obj,String fieldName)throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException{
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return (T)field.get(obj);
}

/**
* 格式化規則
* @param f
* @return
* @throws UnsupportedEncodingException 
*/
public static String toStringFormula(Formula f) throws UnsupportedEncodingException {
if (f == null) {
     return null;
   }else{
    StringBuffer xy = new StringBuffer();
    Ptg[] ptgs = f.getTokens();
    for (int i = 0; i < ptgs.length; i++){
//     System.out.println("ptgs[i]=="+
//     new String(ptgs[i].toFormulaString().getBytes("ISO-8859-1"),"GB2312"));
    xy.append(ptgs[i].toFormulaString());
    }
//     System.out.println(xy.toString().split(""));
    return xy.toString();
   }
 }
/******************read xlsx excel end*******************************/
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章