1. 程式人生 > >封裝poi讀取excel的超強工具類,支援一行程式碼獲取excel內容

封裝poi讀取excel的超強工具類,支援一行程式碼獲取excel內容

時隔多年,再次更新下部落格。特貢獻一份poi讀取excel的超強工具類,一行程式碼讀取excel的封裝。包括讀、寫等操作。具體還是跟著程式碼看吧。

  1. ExcelReadDealUtils:excel讀取處理工具類
package all.file.excel.util;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import
java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFWorkbook; 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.xssf.usermodel.XSSFWorkbook; /** * * Excel檔案讀取封裝 使用說明:<br> * 1、使用loadExcelFile(String excelFilePath)方法載入Excel檔案,即可使用workbook靜態物件;<br> * 2、使用closeDestory()方法銷燬檔案流,即呼叫該方法後,類資源不可用;<br> * 3、使用Map<Object, Object> getRowDataToMap(Row row, boolean isValueKey), 需瞭解引數isValueKey的意義,獲取Excel檔案一行的內容,以Map儲存,該方法常用於Excel表格頭列的獲取;<br> * 4、使用List<String> getRowDataToList(Row row)方法 獲取Excel檔案一行的內容,以List儲存,List可包含重複值,常用於正文內容的獲取;<br> * 5、使用Map<Object, List<String>> getBatchRowDataToList(Sheet sheet, int startRowIndex, int endRowIndex) 批量查詢,獲取Excel檔案中指定開始下標索引與結束下標索引號之間的內容;<br> * 6、使用Object getCellValue(Cell cell)方法獲取指定單元格的內容;<br> * 7、使用getGivenSheetDatas(String excelFilePath, String[] sheetNames, int headIndex, String[] attributes, boolean isMerge, String[] mergeAttributes)<br> * 獲取指定Excel檔案、指定Sheet集、指定表格列集、指定需要合併列的內容 ,適用於較大資料,使用該方法不需要loadExcelFile()以及closeDestory()方法; 整個的載入Excel檔案與關閉、銷燬檔案流自動在方法體完成; * 8、使用getByGivenAttributeAndRowValue(Map<Object, Object> headDataMap, Row row, String[] attributes) 獲取一行指定列的資料集;<br> * 9、使用getMergeCellRowsData(Sheet sheet, Map<Object, Object> headRowData, int rowIndex, String[] attributes, String mergeAttribute, boolean isMerge, String[] mergeAttributes) 根據指定Sheet表及開始行進行獲取一個合併單元集;<br> * 10、使用getCellToDate(Object cellDateValue)將讀取到的Cell單元格為日期型別時,通過表示5位數的Double型別,轉換成Java的Date <br> * 11、使用deleteRows(Sheet sheet, int startRow, int endRow)方法刪除指定開始至結束行,並儲存至原路徑中;<br> * 12、使用getExcelWorkbook()方法獲取載入Excel檔案後的Workbook物件<br> * * 注意:deleteRows方法未完善,由於此方法不用於查詢的功能範圍內 * @author
qiqitrue * @version 1.0 * @since 2015-1-5 */
public class ExcelReadDealUtils extends ExcelCommon { /** * excel工作物件 */ public static Workbook workbook; /** * excel檔案流,用於closeDestory銷燬一次開啟會話 */ private static FileInputStream fis; /** * 使用示例 * @param args * @throws IOException */ public static void main(String[] args) throws IOException { // 載入excel檔案物件 loadExcelFile("D:/新建 Microsoft Excel 工作表.xlsx"); // 獲取指定sheet名稱的excel Sheet物件 Sheet sheet = workbook.getSheet("Sheet1"); // 驗證是否存在,有些時候沒有必要驗證 if (isExistSheet(sheet)) { // 獲取Sheet最後行號 int lastRowNum = sheet.getLastRowNum(); // 獲取表頭轉換成Map形式儲存 Map<Object, Object> headMap = getRowDataToMap(sheet.getRow(0), true); // 定義要獲取Excel中的表頭列 String[] attributes = new String[] { "關聯ID", "英文名", "中文名", "時間", "颱風編號", "強度等級", "緯度", "經度", "風速", "陣風", "氣壓", "風向", "移速", "6級風圈", "7級風圈", "8級風圈", "10級風圈" }; // 從索引為2開始,需注意根據實際情況來定 for (int i = 2; i <= lastRowNum; i++) { // 獲取行物件 Row row = sheet.getRow(i); // 驗證是否存在行 if (isExistRow(row)) { // 獲取一行指定列的資訊 List<Object> byGivenAttributeAndRowValue = getByGivenAttributeAndRowValue(headMap, row, attributes); for (int j = 0; j < byGivenAttributeAndRowValue.size(); j++) { // 特殊的單元格,日期處理 if (j == 3) { System.out.print(getCellToDate(byGivenAttributeAndRowValue.get(j)) + "\t"); } // 普通的單元格,轉換成字串輸出 else { System.out.print(String.valueOf(byGivenAttributeAndRowValue.get(j)) + "\t"); } } System.out.println(); } } } // 銷燬開啟會話的檔案 closeDestory(); } /** * * 載入Excel檔案,建立Workbook物件 * * @param excelFilePath * Excel檔案路徑 */ public static void loadExcelFile(String excelFilePath) { try { fis = new FileInputStream(excelFilePath); if (excelFilePath.endsWith(".xlsx")) { workbook = new XSSFWorkbook(fis); } else if (excelFilePath.endsWith(".xls")) { workbook = new HSSFWorkbook(fis); } else { throw new RuntimeException("錯誤提示: 您設定的Excel檔名不合法!"); } } catch (IOException e) { e.printStackTrace(); } } /** * 獲取Excel檔案的Workbook物件 * @return */ public static Workbook getExcelWorkbook(){ if(!isExist(workbook)){ throw new RuntimeException("錯誤提示:請先進行Excel載入,初始化Workbook物件!"); } return workbook; } /** * * 關閉Excel檔案流 * @throws IOException */ public static void closeDestory() throws IOException { if(fis == null){ throw new RuntimeException("錯誤提示:Excel檔案未載入或未初始化檔案!"); } fis.close(); } /********************************************row行操作********************************************/ /** * * 獲取一行的內容,Map儲存,儲存方式由引數定義 * * @param row * 行物件 * @param isValueKey * 是否以單元格內容作為Key?key為單元格內容, value為下標索引:key為下標索引, value為單元格內容 * @return 一行的內容,Map儲存 */ public static Map<Object, Object> getRowDataToMap(Row row, boolean isValueKey) { Map<Object, Object> headDatas = new HashMap<Object, Object>(); short countCellNum = row.getLastCellNum(); // 在外面判斷isValueKey是為了提高效率,放在迴圈體中降低效率 if (isValueKey) { for (int j = 0; j < countCellNum; j++) { Cell cell = row.getCell(j); if (isExistCell(cell)) { // Key=單元格內容, Value=下標索引 headDatas.put(getCellValue(cell), j); } } } else { for (int j = 0; j < countCellNum; j++) { Cell cell = row.getCell(j); if (isExistCell(cell)) { // Key=下標索引, Value=單元格內容 headDatas.put(j, getCellValue(cell)); } } } return headDatas; } /** * * 獲取一行的內容,List儲存 * * @param row * 行物件 * @return 一行的內容 */ public static List<Object> getRowDataToList(Row row) { List<Object> rowData = new ArrayList<Object>(); if (isExistRow(row)) { short countCellNum = row.getLastCellNum(); for (int i = 0; i < countCellNum; i++) { Cell cell = row.getCell(i); if (isExistCell(cell)) { rowData.add(getCellValue(cell)); } } } return rowData; } /** * * 獲取sheet批量行內容,以List儲存 * * @param sheet * Sheet表物件 * @param startRowIndex * 開始行下標索引號 * @param endRowIndex * 結束行下標索引號 * @return 批量內容行內容 */ public static List<List<Object>> getBatchRowDataToList(Sheet sheet, int startRowIndex, int endRowIndex) { List<List<Object>> batchDatas = new ArrayList<List<Object>>(); if(startRowIndex > endRowIndex){ throw new RuntimeException("錯誤提示:開始行不能大於結束行!"); } // 獲取sheet總行數 int lastRowNum = sheet.getLastRowNum(); if(startRowIndex > lastRowNum || endRowIndex > lastRowNum){ throw new RuntimeException("錯誤提示:開始行或結束行不能超過sheet最大行數!"); } for (int i = startRowIndex; i <= endRowIndex; i++) { Row row = sheet.getRow(i); batchDatas.add(getRowDataToList(row));// 此處不需要驗證row是否為空,在底層getRowData已驗證 } return batchDatas; } /** * * 獲取指定Excel檔案、指定Sheet集、指定表格列集、指定需要合併列的資料 * * @param excelFilePath * Excel檔案路徑,包括Excel檔名 * @param sheetNames * 要解析的Sheet名稱集,null表示全部獲取 * @param headIndex * Sheet表頭下標,從0開始 * @param attributes * 需要獲取Excel列 * @param isMerge * 是否需要合併的列,若為false,mergeAttributes可設定為null * @param mergeAttributes * 需要合併的列(在需要獲取Excel列中) * @return 整個Excel處理後的資料 * @throws IOException */ public static List<List<Object>> getGivenSheetDatas(String excelFilePath, String[] sheetNames, int headIndex, String[] attributes, boolean isMerge, String[] mergeAttributes) throws IOException { // 定義儲存Excel內容集合,List<Object>表示一行的內容 List<List<Object>> excelDatas = new ArrayList<List<Object>>(); // 列表頭,key=單元格內容,value=列下標索引號 Map<Object, Object> headDatasMap = new HashMap<Object, Object>(); // 載入檔案 loadExcelFile(excelFilePath); // 定義需進行解析的Sheet集 List<Sheet> sheets = new ArrayList<Sheet>(); // 按指定的Sheet進行解析 if (sheetNames != null) { for (int i = 0; i < sheetNames.length; i++) { // 獲取第i個Sheet表物件 Sheet sheet = workbook.getSheet(sheetNames[i]); if (!isExistSheet(sheet)) { throw new RuntimeException("錯誤提示: 您指定的Sheet集中的【" + sheetNames[i] + "】不存在,請檢查原Excel檔案!"); } // 新增至解析的Sheet集中 else { sheets.add(sheet); } } } // 沒有指定Sheet,則全部 else { int length = workbook.getNumberOfSheets(); for (int i = 0; i < length; i++) { Sheet sheet = workbook.getSheet(workbook.getSheetName(i)); sheets.add(sheet); } } // 以上是獲取需要讀取的Sheet表 for (Sheet sheet : sheets) { // 獲取表頭列行是否存在 Row headRow = sheet.getRow(headIndex); if (headRow == null) { System.out.println("錯誤提示: 您指定的表格列頭行【" + headIndex + "】不存在!"); } // 存在著指定的表頭列行 else { // 轉換成Map,Key=表頭列名稱,Value=列名稱下標索引 headDatasMap = getRowDataToMap(headRow, true); int eqCount = 0;// 實際存在的列個數 // 定義需要獲取到的列在實際中不存在的列集合 List<String> noEqAttributes = new ArrayList<String>(); for (String attribute : attributes) { if (headDatasMap.get(attribute) != null) { eqCount++; } // 不存在的列數 else { noEqAttributes.add(attribute); } } System.out.println("提示:Sheet表名稱為[" + sheet.getSheetName() + "]中需匯入的列數與存在的列數之比:" + attributes.length + ":" + eqCount); if (attributes.length != eqCount) { System.out.println("錯誤提示: 實際不存在的屬性集(程式中需要獲取的列在Sheet中不存在的列):"); for (int j = 0; j < noEqAttributes.size(); j++) { System.out.print(noEqAttributes.get(j) + "\t"); } System.out.println(); } // 全部等於進行解析該Sheet頁的所有內容 else { // 獲取當前Sheet表總行數 int rowCount = sheet.getLastRowNum(); // 從索引號為列頭行號索引+1開始進行讀取 for (int k = (headIndex + 1); k <= rowCount; k++) { Row row = sheet.getRow(k); if (!isExistRow(row)) { System.out.println("錯誤提示: 在第" + k + "行出現空行。"); continue; } // 一行資料 List<Object> rowDatas = getByGivenAttributeAndRowValue(headDatasMap, row, attributes); excelDatas.add(rowDatas);// 新增一行資料 } } } } // 需要合併 if (isMerge) { // 記錄需要合併的列Index List<Integer> mergerIndex = new ArrayList<Integer>(); for (String mergerAttribute : mergeAttributes) { Integer integerIndex = (Integer) headDatasMap.get(mergerAttribute); if (integerIndex != null) { mergerIndex.add(integerIndex); } } for (int i = 0; i < excelDatas.size(); i++) { List<Object> rowDatas = excelDatas.get(i); for (int j = 0; j < mergerIndex.size(); j++) { if (rowDatas.get(mergerIndex.get(j)).equals("")) { // 在第一行不為空的情況下 if (i != 0) { Object value = excelDatas.get(i - 1).get(mergerIndex.get(j)); rowDatas.set(mergerIndex.get(j), value); } } } } } closeDestory(); return excelDatas; } /** * * 獲取一行指定列的資料集 * * @param headDataMap * 表列頭Map資料,key=單元格內容,value為下標索引號 * @param row * 需獲取的指定行 * @param attributes * 需獲取的指定單元格 * @return 一行指定列的資料集 */ public static List<Object> getByGivenAttributeAndRowValue(Map<Object, Object> headDataMap, Row row, String[] attributes) { List<Object> datas = new ArrayList<Object>(); for (int i = 0; i < attributes.length; i++) { Integer index = (Integer) headDataMap.get(attributes[i]); if(index == null){ System.out.println("查詢列:"+attributes[i]+"失敗!"); } else{ Cell cell = row.getCell(index); Object cellValue = getCellValue(cell); if (cellValue == null) { cellValue = ""; } datas.add(cellValue); } } return datas; } /** * * 根據指定Sheet表及開始行進行獲取一個合併單元集,若沒理解,好比是從資料庫中只取一個表,並把表的所有欄位返回 * * @param sheet * 指定Sheet表物件 * @param headRowData * 表頭列,使用getRowDataToMap(Row, boolean)方法獲取 * @param rowIndex * 開始行物件,即有內容的開始行 * @param attributes * 需要獲取的單元格列物件 * @param mergeAttribute * 根據那一個單元格進行合併 * @param isMerge * 是否需要合併 * @param mergeAttributes * 需要合併的單元格集 * @return 返回一個合併單元集 */ public static List<List<Object>> getMergeCellRowsData(Sheet sheet,Map<Object, Object> headRowData, int rowIndex, String[] attributes, String mergeAttribute, boolean isMerge, String[] mergeAttributes) { List<List<Object>> rowsData = null; // 需要獲取的單元格列名稱在表格表頭行中完全存在 if (headRowData.keySet().containsAll(Arrays.asList(attributes))) { Row row = sheet.getRow(rowIndex); // 存在的列索引 Integer existCellIndex = (Integer) headRowData.get(mergeAttribute); Cell cell = row.getCell(existCellIndex); Object cellValue = getCellValue(cell); if (String.valueOf(cellValue).isEmpty()) {// 值是空的 System.out.println("錯誤提示: 給定的行【" + rowIndex + "】的【"+ mergeAttribute + "】為空, 請檢查!"); } else { rowsData = new ArrayList<List<Object>>(); rowsData.add(getByGivenAttributeAndRowValue(headRowData, row, attributes));// 第一行 while (true) { Row row2 = sheet.getRow(++rowIndex); Cell cell2 = row2.getCell(existCellIndex); if (String.valueOf(getCellValue(cell2)).isEmpty()) { rowsData.add(getByGivenAttributeAndRowValue(headRowData, row2, attributes)); } else { // 需要合併 if (isMerge) { // 記錄需要合併的列Index List<Integer> mergerIndex = new ArrayList<Integer>(); for (String mergerAttribute : mergeAttributes) { Integer integerIndex = (Integer) headRowData.get(mergerAttribute); if (integerIndex != null) { mergerIndex.add(integerIndex); } } for (int i = 0; i < rowsData.size(); i++) { List<Object> rowDatas = rowsData.get(i); for (int j = 0; j < mergerIndex.size(); j++) { if (rowDatas.get(mergerIndex.get(j)).equals("")) { // 在第一行不為空的情況下 if (i != 0) { Object value = rowsData.get(i - 1).get(mergerIndex.get(j)); rowDatas.set(mergerIndex.get(j), value); } } } } } return rowsData; } } } } else { System.out.println("錯誤提示: 要獲取表頭列在【" + sheet.getSheetName() + "】中的列頭不完全存在, 請檢查!"); } return rowsData;// 此時這裡是返回Null } /** * * 將讀取到的Cell單元格為日期型別時,通過表示5位數的Double型別,轉換成Java的Date * * @param cellDateValue * 單元格日期型別 * @return 返回Java Date型別 */ public static Date getCellToDate(Object cellDateValue) { if(cellDateValue == null || cellDateValue.equals("")){ return null; } double parseDouble = Double.parseDouble(cellDateValue.toString()); Date javaDate = HSSFDateUtil.getJavaDate(parseDouble); return javaDate; } /** * * 指定Sheet表中進行刪除指定開始到結束行中間的行 * * @param sheet * 指定的Sheet表 * @param startRow * 指定的開始行 * @param endRow * 指定的結束行 */ public static void deleteRows(Sheet sheet, int startRow, int endRow) { int lastRowNum = sheet.getLastRowNum(); // 開始刪除行與結束刪除行的範圍在該Sheet裡 if (startRow < lastRowNum && endRow < lastRowNum) { sheet.shiftRows(startRow, endRow, -1);// 刪除從startRow行到endRow行,然後使下方單元格上移 } // 待新增儲存處理 } /** * * 指定Sheet表中查詢關鍵字 * * @param sheet * 指定Sheet表 * @param keyWord * 查詢的關鍵字 * @param isGoEnd * 是否一找到底,如果找到一個了,就返回,還是繼續找 * @return 返回控制檯提示資訊 */ public static String isExistKeyWord(Sheet sheet, String keyWord, boolean isGoEnd) { if (isExistSheet(sheet)) { StringBuffer sbf = new StringBuffer(); int findCount = 0; int lastRowNum = sheet.getLastRowNum(); for (int i = 0; i <= lastRowNum; i++) { Row row = sheet.getRow(i); if (isExistRow(row)) { short lastCellNum = row.getLastCellNum(); for (int j = 0; j <= lastCellNum; j++) { Cell cell = row.getCell(j); if (isExistCell(cell)) { Object cellValue = getCellValue(cell); if (cellValue == null) { continue; } else { if (String.valueOf(cellValue).contains(keyWord)) { // 整個Sheet不停歇地找 if (isGoEnd) { findCount++; // 此處需加一個換行符 StringBuffer temp = new StringBuffer("提示:在Sheet表為【"+ sheet.getSheetName() + "】中的第【" + i + "】行【" + j + "】列查詢到關鍵字【" + keyWord + "】\n"); System.out.println(temp.toString()); sbf.append(temp); } else { return "提示:在Sheet表為【" + sheet.getSheetName() + "】中的第【" + i + "】行【" + j + "】列查詢到關鍵字【" + keyWord + "】"; } } } } } } } System.out.println("查詢結束提示:在Sheet表為【" + sheet.getSheetName() + "】中總計找到關鍵字【" + keyWord + "】個數:" + findCount); return sbf.toString(); } return null;// 即表示不存在 } }
  1. ExcelWriterDealUtils.java excel寫的處理工具類(水平不太好請勿介意)
package all.file.excel.util;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.RichTextString;
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;

import all.file.util.FileComonDealUtils;



/**
 * 
 * Excel檔案寫入封裝 使用說明:<br> 
 * 1、使用loadWorkbook(String excelFilePath)方法載入Workbook工作薄物件,即可使用靜態workbook物件;<br>
 * 2、使用saveFile()方法儲存Workbook內容到檔案中,並關閉檔案流; <br>
 * 3、使用setRowValue(Row row, List<Object> rowData)方法設定一行資料,並返回修改後的Row行物件; <br>
 * 4、使用setCellValue(Cell cell, Object value)方法設定單元格值,並返回修改後的Cell單元格物件; <br>
 * 5、使用createCellStyle(boolean isContentStyle)方法建立單元格樣式,isContentStyle設定是否為文字樣式,還有一種是表頭樣式;<br>
 * 6、使用setSheetAndHead(String sheetName, String[] headCellContent)方法同時建立Sheet並設定一行列頭;起到簡化的作用,返回Sheet;<br>
 * 7、使用setGivenRowDatas(Sheet sheet, int startRowIndex, List<List<Object>> rowsDatas方法設定從給定Sheet表、給定開始行批量新增、更新內容<br> 
 * 8、使用isExistRow(Row row)方法驗證一行物件是否存在,返回Boolean結果;<br> 
 * 9、使用isExistRow(Sheet sheet, int rowIndex)方法驗證指定Sheet表下的下標索引行是否存在,存在則返回原行物件,不存在則建立Row物件後返回 <br>
 * 10、使用isExistCell(Cell cell)方法驗證一單元格是否存在 ,返回Boolean結果 <br>
 * 11、使用isExistCell(Row row, int cellIndex)方法驗證指定Row行的單元格下標索引是否存在,存在則返回原單元格物件,不存在則建立單元格物件後返回 <br>
 * 12、使用saveFile(Workbook workbook, String saveExcelPath)方法進行儲存,此方法是該類中的saveFile()方法的擴充套件,適用於外部,並適用於空內容的Exce檔案操作;
 * 
 * @author 賴奇
 * @version 1.0
 * @since 2014-6-26
 */
public class ExcelWriterDealUtils extends ExcelCommon {

    /**
     * 工作薄物件
     */
    protected static Workbook workbook;

    /**
     * 寫入Excel檔案路徑
     */
    protected static String excelFilePath;

    /**
     * 檔案讀取流
     */
    private static FileInputStream fis;

    /**
     * 
     * 載入Workbook工作薄物件,即可使用靜態workbook物件
     * 
     * @param excelFilePath
     *            Excel檔案路徑
     */
    public static void loadWorkbook(String excelFilePath) {
        // try
        // {
        ExcelWriterDealUtils.excelFilePath = excelFilePath;
        // saveFile(new XSSFWorkbook() , excelFilePath);
        // fis = new FileInputStream(excelFilePath);
        if (excelFilePath.endsWith(".xlsx")) {
            workbook = new XSSFWorkbook();
        } else if (excelFilePath.endsWith(".xls")) {
            workbook = new HSSFWorkbook();
        }
        // }
        // catch (IOException e)
        // {
        // e.printStackTrace();
        // }
    }

    /**
     * 
     * 儲存Workbook內容到檔案中
     */
    public static void saveFile() {
        FileOutputStream fos = null;
        try {
            if (fis != null) {
                fis.close();// 先關閉
            }
            fos = new FileOutputStream(excelFilePath);
            workbook.write(fos);
            fos.flush();
            System.out.println(excelFilePath + ":檔案寫入成功...");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (fis != null) {
                    fis.close();// 關閉讀取流
                }
                if (fos != null) {
                    fos.close();// 關閉檔案流
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 
     * 儲存一個為Excel的檔案
     * 
     * @param workbook
     *            工作薄物件
     * @param saveExcelPath
     *            儲存到Excel的檔案路徑
     */
    public static void saveFile(Workbook workbook, String saveExcelPath) {
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(FileComonDealUtils
                    .createFile(saveExcelPath));
            workbook.createSheet("Sheet1");
            workbook.write(fos);
            fos.flush();
            // System.out.println(excelFilePath + ":檔案寫入成功...");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();// 關閉檔案流
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 
     * 設定一行的資料,返回設定後的行物件
     * 
     * @param row
     *            行物件
     * @param rowData
     *            行資料
     * @return 設定後的行物件
     */
    public static Row setRowValue(Row row, List<Object> rowData) {
        for (int i = 0; i < rowData.size(); i++) {
            Cell cell = isExistCell(row, i);
            setCellValue(cell, rowData.get(i));
        }
        return row;
    }

    /**
     * 
     * 設定單元格值
     * 
     * @param cell
     *            需要設定的單元格
     * @param value
     *            設定給單元格cell的值
     * @return 設定好的單元格列物件
     */
    public static Cell setCellValue(Cell cell, Object value) {
        if (value instanceof String) {
            cell.setCellValue((String) value);
            cell.setCellType(Cell.CELL_TYPE_STRING);
        } else if (value instanceof Date) {
            cell.setCellValue((Date) value);
            cell.setCellType(Cell.CELL_TYPE_STRING);
        } else if (value instanceof Boolean) {
            cell.setCellValue((Boolean) value);
            cell.setCellType(Cell.CELL_TYPE_BOOLEAN);
        } else if (value instanceof Double) {
            cell.setCellValue((Double) value);
            cell.setCellType(Cell.CELL_TYPE_NUMERIC);
        } else if (value instanceof Calendar) {
            cell.setCellValue((Calendar) value);
            cell.setCellType(Cell.CELL_TYPE_STRING);
        } else if (value instanceof RichTextString) {
            cell.setCellValue((RichTextString) value);
            cell.setCellType(Cell.CELL_TYPE_STRING);
        } else {
            cell.setCellValue(String.valueOf(value));
            cell.setCellType(Cell.CELL_TYPE_STRING);
            // System.out.println("錯誤提示: 您設定的單元格內容【"+value+"】不符合要求,不是常用型別!");
        }
        return cell;
    }

    /**
     * 
     * 建立單元格樣式: 內容樣式、表格列頭樣式
     * 
     * @param isContent
     *            是否為內容樣式
     * @return 單元格樣式
     */
    public static CellStyle createCellStyle(boolean isContentStyle) {
        CellStyle cellStyle = workbook.createCellStyle();
        if (isContentStyle) {

        } else {

        }
        return cellStyle;
    }

    /**
     * 
     * 建立指定的Sheet表名稱及表頭,返回Sheet表物件
     * 
     * @param sheetName
     *            Sheet表名稱
     * @param headCellContent
     *            表頭列屬性
     * @return 返回建立好後的Sheet表物件
     */
    public static Sheet setSheetAndHead(String sheetName,
            String[] headCellContent) {
        Sheet sheet = isExistSheet(sheetName);
        Row headRow = isExistRow(sheet, 0);
        List<Object> headRowDatas = new ArrayList<Object>();
        for (String headCellValue : headCellContent) {
            headRowDatas.add(headCellValue);
        }
        setRowValue(headRow, headRowDatas);
        return sheet;
    }

    /**
     * 
     * 設定從給定Sheet表、給定開始行批量新增、更新內容,返回結束行下標索引
     * 
     * @param sheet
     *            指定Sheet表
     * @param startRowIndex
     *            新增、更新開始行索引號
     * @param rowsDatas
     *            行內容資料
     * @return 返回Sheet表更新、新增後的行號
     */
    public static int setGivenRowDatas(Sheet sheet, int startRowIndex,
            List<List<Object>> rowsDatas) {
        int rowSize = rowsDatas.size();
        int endIndex = startRowIndex + rowSize;
        for (int i = 0; i < rowSize; i++) {
            Row row = isExistRow(sheet, startRowIndex + i);
            setRowValue(row, rowsDatas.get(i));
        }
        return endIndex;
    }

    /**
     * 
     * 驗證指定Sheet表名稱是否存在,存在則返回原Sheet表物件,不存在則建立Sheet表物件後返回
     * 
     * @param sheetName
     *            需要驗證的Sheet表名稱
     * @return Sheet表(存在就返回,不存在就新建)
     */
    public static Sheet isExistSheet(String sheetName) {
        Sheet sheet = workbook.getSheet(sheetName);
        if (sheet == null) {
            return workbook.createSheet(sheetName);
        } else {
            System.out.println("錯誤提示: 您設定的Sheet表名稱【" + sheetName
                    + "】已存在,請重新設定!");
            return sheet;
        }
    }

    /**
     * 
     * 驗證指定Sheet表下的下標索引行是否存在,存在則返回原行物件,不存在則建立Row物件後返回
     * 
     * @param sheet
     *            指定的Sheet物件
     * @param rowIndex
     *            指定的下標索引行號
     * @return Row行(存在就返回,不存在就新建)
     */
    public static Row isExistRow(Sheet sheet, int rowIndex) {
        Row row = sheet.getRow(rowIndex);
        if (row == null) {
            return sheet.createRow(rowIndex);
        } else {
            // System.out.println("警告提示: 您設定的Sheet表名稱【"+sheet.getSheetName()+"】中的第【"+rowIndex+"】行已存在!");
            return row;
        }
    }

    /**
     * 
     * 驗證指定Row行的單元格下標索引是否存在,存在則返回原單元格物件,不存在則建立單元格物件後返回
     * 
     * @param row
     *            指定的Row行物件
     * @param cellIndex
     *            指定的下標索引單元格列號
     * @return Cell行(存在就返回,不存在就新建)
     */
    public static Cell isExistCell(Row row, int cellIndex) {
        Cell cell = row.getCell(cellIndex);
        if (cell == null) {
            return row.createCell(cellIndex);
        } else {
            System.out.println("指定的列已存在");
            return cell;
        }
    }

    /**
     * 
     * 設定單元格合併
     * 
     * @param sheet
     *            指定合併的Sheet表
     * @param firstRow
     *            開始行
     * @param lastRow
     *            結束行
     * @param firstCol
     *            開始列
     * @param lastCol
     *            結束列
     */
    public static void setCellMerge(Sheet sheet, int firstRow, int lastRow,
            int firstCol, int lastCol) {
        sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol,
                lastCol));
    }

    /**
     * 
     * 設定指定列的單元格內如如果相同則進行單元格合併(需修改)
     * 
     * @param sheet
     *            Sheet表
     * @param headRowData
     *            開始行資料
     * @param mergeCells
     *            合併的單元格列
     * @param startRow
     *            開始行
     */
    public static void setCellMerge(Sheet sheet,
            Map<Object, Object> headRowData, String[] mergeCells, int startRow) {
        if (headRowData.keySet().containsAll(Arrays.asList(mergeCells))) {
            int lastRowNum = sheet.getLastRowNum();
            if (lastRowNum > 0) {
                int temp = startRow;
                for (String mergeCell : mergeCells) {
                    Integer cellIndex = (Integer) headRowData.get(mergeCell);
                    Row row = sheet.getRow(startRow);
                    if (row == null) {
                        continue;
                    }
                    Cell cell2 = row.getCell(cellIndex);
                    if (cell2 == null) {
                        continue;
                    }
                    Object cellValue = getCellValue(cell2);
                    int startMergerIndex = startRow;

                    while (startRow < (lastRowNum - 1)) {
                        Row eqRow = sheet.getRow(++startRow);
                        Cell cell = eqRow.getCell(cellIndex);
                        Object cellValue2 = getCellValue(cell);
                        System.out.println(cellValue + "\t" + cellValue2);
                        // 相同進行合併
                        if (!cellValue2.equals(cellValue)) {
                            System.out.println("裡:" + startMergerIndex + "\t"
                                    + lastRowNum + "\t" + cellIndex + "\t"
                                    + cellIndex);
                            setCellMerge(sheet, startMergerIndex, startRow - 1,
                                    cellIndex, cellIndex);
                            startMergerIndex = startRow;
                            cellValue = cellValue2;
                        }
                    }
                    System.out.println(startMergerIndex + "\t" + lastRowNum
                            + "\t" + cellIndex + "\t" + cellIndex);
                    setCellMerge(sheet, startMergerIndex, lastRowNum,
                            cellIndex, cellIndex);
                    startRow = temp;
                }
            }
        } else {
            System.out.println("錯誤提示: 你需要合併的列不存在!");
        }
    }
}
  1. ExcelCommon.java涉及到的公共封裝類
package all.file.excel.util;

import<