1. 程式人生 > >【JAVA】apache poi excel 檔案讀取,各種資料型別,不規則excel格式都可以讀取

【JAVA】apache poi excel 檔案讀取,各種資料型別,不規則excel格式都可以讀取

本文將通過例項來介紹apache poi  讀取excel的原理,包括各種資料型別的處理,本文提供的程式碼非常通用,即使不規則的excel檔案,也可以讀取。

直接看程式碼吧

package poi.excel;

import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
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.usermodel.WorkbookFactory;

/**
 * ClassName:ExcelFileParser <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date: 2015年12月29日 上午9:26:21 <br/>
 * 
 * @author chiwei
 * @version
 * @since JDK 1.6
 * @see
 */
public class ExcelFileParser {

	public static Workbook getWb(String path) {
		try {
			return WorkbookFactory.create(new File(path));
		} catch (Exception e) {
			throw new RuntimeException("讀取EXCEL檔案出錯", e);
		}
	}

	public static Sheet getSheet(Workbook wb, int sheetIndex) {
		if (wb == null) {
			throw new RuntimeException("工作簿物件為空");
		}
		int sheetSize = wb.getNumberOfSheets();
		if (sheetIndex < 0 || sheetIndex > sheetSize - 1) {
			throw new RuntimeException("工作表獲取錯誤");
		}
		return wb.getSheetAt(sheetIndex);
	}

	public static List<List<String>> getExcelRows(Sheet sheet, int startLine, int endLine) {
		List<List<String>> list = new ArrayList<List<String>>();
		// 如果開始行號和結束行號都是-1的話,則全表讀取
		if (startLine == -1)
			startLine = 0;
		if (endLine == -1) {
			endLine = sheet.getLastRowNum() + 1;
		} else {
			endLine += 1;
		}
		for (int i = startLine; i < endLine; i++) {
			Row row = sheet.getRow(i);
			if (row == null) {
				System.out.println("該行為空,直接跳過");
				continue;
			}
			int rowSize = row.getLastCellNum();
			List<String> rowList = new ArrayList<String>();
			for (int j = 0; j < rowSize; j++) {
				Cell cell = row.getCell(j);
				String temp = "";
				if (cell == null) {
					System.out.println("該列為空,賦值雙引號");
					temp = "NULL";
				} else {
					int cellType = cell.getCellType();
					switch (cellType) {
					case Cell.CELL_TYPE_STRING:
						temp = cell.getStringCellValue().trim();
						temp = StringUtils.isEmpty(temp) ? "NULL" : temp;
						break;
					case Cell.CELL_TYPE_BOOLEAN:
						temp = String.valueOf(cell.getBooleanCellValue());
						break;
					case Cell.CELL_TYPE_FORMULA:
						temp = String.valueOf(cell.getCellFormula().trim());
						break;
					case Cell.CELL_TYPE_NUMERIC:
						if (HSSFDateUtil.isCellDateFormatted(cell)) {
							temp = DateUtil.parseToString(cell.getDateCellValue(),
									DateUtil.FORMAT_DATE);
						} else {
							temp = new DecimalFormat("#.######").format(cell.getNumericCellValue());
						}
						break;
					case Cell.CELL_TYPE_BLANK:
						temp = "NULL";
						break;
					case Cell.CELL_TYPE_ERROR:
						temp = "ERROR";
						break;
					default:
						temp = cell.toString().trim();
						break;
					}
				}
				rowList.add(temp);
			}
			list.add(rowList);
		}
		return list;
	}

	public static void main(String a[]) {
		String path = "D:\\test.xlsx";
		Workbook wb = getWb(path);
		List<List<String>> list = getExcelRows(getSheet(wb, 0), -1, -1);
		for (int i = 0; i < list.size(); i++) {
			List<String> row = list.get(i);
			for (int j = 0; j < row.size(); j++) {
				System.out.print(row.get(j) + "\t");
			}
			System.out.println();
		}
	}

}



該測試excel檔案包括兩個sheet

該程式碼是將excel的單元格內容全部按照返回string來處理,方便通用

maven 依賴如下:

<dependency>
			<groupId>joda-time</groupId>
			<artifactId>joda-time</artifactId>
			<version>2.6</version>
		</dependency>
<dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.11</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.11</version>
        </dependency>
joda-time是針對日期型別哪裡轉字串用的,執行緒安全的類,建議大家不要再用SimpleDateFormat了

程式碼流程:

首先根據檔案路徑去建立一個工作簿物件Workbook

然後通過工作簿物件獲取一個工作表物件Sheet

最後對工作表的row進行遍歷

注意獲取每行的列數,我用的row.getLastCellNum();而不是row.getPhysicalNumberOfCells()

這個方法就可以處理不規則的excel單元格內容了,即某一行3列,某一行4列,5列之類的

然後對行迴圈記憶體的單元列也要進行空判斷,防止異常

程式碼提供的方法非常通用,只需傳進去一個檔案路徑,和幾個必要的引數即可,有其它需求的話,在此程式碼上二次開發非常簡單

有問題,請留言探討!