package com.haiyisoft.iecp.util;java
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.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;apache
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
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.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;數組
/**
* excel讀取數據
*
* @author 白亞龍
*
* <p>
* 2018-04-19 白亞龍 新建
* </p>
*/xss
public class ReadExceTool {excel
/**
* 導出Excel文件的信息 形式爲:List<List<Object>> 支持格式爲 : xlsx,xls
* 第一層list爲文件sheet信息 第二層list爲一個sheet頁面的信息 第三層爲sheet內容某一行的信息
* 文件信息由上自下由左自右查找
* 分數數據暫時只能讀取成小數保存
* @param File 輸入文件
* @param String 文件後綴
* @return List<List<Object>> (最內層object爲一個List<Object>數組)
*/
public List<List<Object>> readExcel(File file, String extension) {
List<List<Object>> fileObject = new java.util.ArrayList<List<Object>>();
Workbook wb = null;
// 讀取文件格式判斷,若是是excel文件則返回Workbook實例
wb = readFile(file, extension);
if(wb != null){
// 循環sheet頁面,添加第一層list
for(int numSheet = 0; numSheet < wb.getNumberOfSheets(); numSheet++){
Sheet sheet = wb.getSheetAt(numSheet);
if(sheet == null){
continue;
}
/**
* column: sheet頁面最大列數;
* 根據 sheet頁最大行,最大列對頁面進行循環處理
*/
List<Object> sheetObjects = new ArrayList<Object>();
// 獲取數據最小列數
int startColumn = getFirstColNum(sheet, sheet.getLastRowNum());
// 獲取數據最大列數
int endColumn = getLastColNum(sheet, sheet.getLastRowNum());
// 根據最大行數進行循環,將行數據數據放入第二層list
for(int i =0; i <= sheet.getLastRowNum(); i++){
Row row = sheet.getRow(i);
List<Object> rowValues = new ArrayList<Object>();
// 空行忽略
if(row == null){
continue;
}else {
// 每行內根據最大列數循環,將單元數據數據放入第三層list
for(int j = startColumn; j < endColumn; j++){
Cell cell = row.getCell(j);
// 空單元忽略
String cellValue = null;
if(cell == null) continue;
// 判斷是否爲合併單元格
if(isMergedRegion(sheet, i, j)){
// 合併單元格取值(全部單元格取第一個單元格的值,跨列合併單元格 只取第一個數據)
cellValue = getMergedValue(sheet, i, j);
}else{
// 單元格取值
cellValue = getValue(cell);
}
// 若是是跨列合併單元格 只取第一個數據
if(cellValue != null && cellValue.equals("ignoredData"))continue;
else rowValues.add(cellValue);
}
if (rowValues.size()>0) {
sheetObjects.add(rowValues);
}
}
}
if (sheetObjects.size()>0) {
fileObject.add(sheetObjects);
}
}
/*//遍歷解析出來的list (數據驗證)
for (List<Object> sheetObjects : fileObject) {
for (Object rowObjects : sheetObjects) {
List<Object> cellValues = (List<Object>) rowObjects;
for (int i = 0; i < cellValues.size(); i++) {
System.out.print(cellValues.get(i) + ",");
}
System.out.println();
}
System.out.println();
}*/
}
return fileObject;
}orm
/**
* 求Excel某一工做簿0~某行內的最小列數
* @param sheet 工做簿
* @param rowNum 行數
* @return
*/
private static int getFirstColNum(Sheet sheet, int lastRowNum) {
if(sheet == null){
return 0;
}
// 初始值設置爲一個較大的值
int firstCol = 1000;
Row row = null;
// 根據行循環,取第一個非空值的最小下標
for(int i = 0; i <= lastRowNum; i++){
row = sheet.getRow(i);
if(row != null){
for(int j = 0; j < row.getLastCellNum(); j++){
if(row.getCell(j) != null){
if(firstCol > j){
firstCol = j;
break;
}
}
}
}
}
return firstCol;
}對象
/**
* 求Excel某一工做簿0~某行內的最大列數
* @param sheet 工做簿
* @param rowNum 行數
* @return
*/
private static int getLastColNum(Sheet sheet, int rowNum) {
if(sheet == null ){
return 0;
}
int lastCol = 0;
Row row = null;
for(int i = 0; i <= rowNum; i++){
row = sheet.getRow(i);
if(row != null){
int temp = row.getLastCellNum();
if(temp > lastCol){
lastCol = temp;
}
}
}
return lastCol;
}ci
/**
* 獲取合併單元格的值
* @param sheet 工做簿
* @param rowNum 單元行
* @param columnIndex 單元列
* @return Object 單元值
*/
private static String getMergedValue(Sheet sheet, int rowNum,
int columnIndex) {
// 獲取合併單元格個數
int mergeNum = sheet.getNumMergedRegions();
String value = null;
// 循環判斷單元格所在合併單元格,合併單元格內全部單元格賦相同的值
for(int i = 0; i < mergeNum; i++){
CellRangeAddress range = sheet.getMergedRegion(i);
// 數據依次爲合併單元格的第一列、最後一列、第一行、最後一行
int firstColumn = range.getFirstColumn();
int lastColumn = range.getLastColumn();
int firstRow = range.getFirstRow();
int lastRow = range.getLastRow();
// 判斷是否在次單元格區間內
if(rowNum >= firstRow && rowNum <= lastRow){
// 全部單元格取第一個單元格的值,跨列合併單元格 只取第一個數據
if(columnIndex == firstColumn){
value = getValue(sheet.getRow(firstRow).getCell(firstColumn));
}else if(columnIndex > firstColumn && columnIndex <= lastColumn){
value = "ignoredData";
}
}
}
return value;
}字符串
/**
* 判斷是否是合併單元格
* @param sheet Excel工做簿
* @param rowNum 單元格行下標
* @param columnIndex 單元格列下標
* @return
*/
private static boolean isMergedRegion(Sheet sheet, int rowNum,
int columnIndex) {
// 獲取合併單元格個數
int sheetMergedNum = sheet.getNumMergedRegions();
for(int i = 0; i < sheetMergedNum; i++){
CellRangeAddress range = sheet.getMergedRegion(i);
// 數據依次爲合併單元格的第一列、最後一列、第一行、最後一行
int firstColumn = range.getFirstColumn();
int lastColumn = range.getLastColumn();
int firstRow = range.getFirstRow();
int lastRow = range.getLastRow();
// 判斷是否在次單元格區間內,若是是則返回true
if(rowNum >= firstRow && rowNum <= lastRow){
if(columnIndex >= firstColumn && columnIndex <= lastColumn){
return true;
}
}
}
// 若是不在全部的合併單元格內則返回false
return false;
}get
/**
* 讀取文件類型,若是是excel則返回對象實例, 若是不是則返回null
* @param filePath 文件路徑
* @return Workbook實例
*/
private static Workbook readFile(File file, String extension) {
Workbook wb = null;
if(file != null && extension != null && !extension.equals("")){
try {
InputStream inputStream = null;
inputStream = new FileInputStream(file);
if(extension.equals("xls")){
wb = new HSSFWorkbook(inputStream);
}else if(extension.equals("xlsx")){
wb = new XSSFWorkbook(inputStream);
}else{
wb = null;
}
} catch (FileNotFoundException e) {
System.out.println("未找到文件位置!");
e.printStackTrace();
} catch (IOException e) {
System.out.println("文件類型不正確,請從新選擇!");
e.printStackTrace();
}
}
return wb;
}
/** * 獲取單元格的值,並格式化 日期格式不變 其餘格式轉換爲字符串類型 * @param cell 單元格 * @return */ private static String getValue(Cell cell){ String cellValue = null; // 格式化數據對象 DecimalFormat df = new DecimalFormat("0.######"); if(cell != null){ // 獲取單元格數據類型 switch (cell.getCellType()) { case Cell.CELL_TYPE_NUMERIC: DateFormat formater = null; Date d = cell.getDateCellValue(); if(cell.getCellStyle().getDataFormat() == 31){ formater = new SimpleDateFormat("yyyy年MM月dd日"); cellValue = formater.format(d); }else if(cell.getCellStyle().getDataFormat() == 58){ formater = new SimpleDateFormat("MM月dd日"); cellValue = formater.format(d); }else if(cell.getCellStyle().getDataFormat() == 14){ formater = new SimpleDateFormat("yyyy-MM-dd"); cellValue = formater.format(d); }else if(cell.getCellStyle().getDataFormat() == 57){ formater = new SimpleDateFormat("yyyy年MM月"); cellValue = formater.format(d); }else if(cell.getCellStyle().getDataFormat() == 20){ formater = new SimpleDateFormat("HH:mm"); cellValue = formater.format(d); }else if(cell.getCellStyle().getDataFormat() == 32){ formater = new SimpleDateFormat("HH時mm分"); cellValue = formater.format(d); }else if(cell.getCellStyle().getDataFormat() == 9){ cellValue = df.format(cell.getNumericCellValue()*100) + "%"; }else if(DateUtil.isCellDateFormatted(cell)){ formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); cellValue = formater.format(d); }else{ cellValue = df.format(cell.getNumericCellValue()); } break; case Cell.CELL_TYPE_FORMULA: try { cellValue = df.format(cell.getNumericCellValue()); } catch (Exception e) { cellValue = cell.getCellFormula(); } break; case Cell.CELL_TYPE_STRING: cellValue = cell.getRichStringCellValue().getString(); break; case Cell.CELL_TYPE_BLANK: break; case Cell.CELL_TYPE_ERROR: break; default: cellValue = ""; break; } } return cellValue; }}