1. 程式人生 > >自己封裝的poi操作Excel工具類

自己封裝的poi操作Excel工具類

該工具類主要完成的功能是:讀取Excel、彙總Excel的功能。在讀取時,可以設定開始和結束讀取的位置、設定是否讀取多個sheet、設定讀取那個或者那些sheet等。在彙總時,如設定是否覆蓋目標檔案、設定是否比較檢查重複內容、設定檢查重複的列索引等功能。具體來演示一下吧:


       工具類原始碼:

    package com.tgb.ccl.excel.util;
     
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
     
    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.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檔案操作工具類,包括讀、寫、合併等功能
     *
     */
    public class ExcelUtil {
        
        //%%%%%%%%-------常量部分 開始----------%%%%%%%%%
        /**
         * 預設的開始讀取的行位置為第一行(索引值為0)
         */
        private final static int READ_START_POS = 0;
        
        /**
         * 預設結束讀取的行位置為最後一行(索引值=0,用負數來表示倒數第n行)
         */
        private final static int READ_END_POS = 0;
        
        /**
         * 預設Excel內容的開始比較列位置為第一列(索引值為0)
         */
        private final static int COMPARE_POS = 0;
        
        /**
         * 預設多檔案合併的時需要做內容比較(相同的內容不重複出現)
         */
        private final static boolean NEED_COMPARE = true;
        
        /**
         * 預設多檔案合併的新檔案遇到名稱重複時,進行覆蓋
         */
        private final static boolean NEED_OVERWRITE = true;
        
        /**
         * 預設只操作一個sheet
         */
        private final static boolean ONLY_ONE_SHEET = true;
        
        /**
         * 預設讀取第一個sheet中(只有當ONLY_ONE_SHEET = true時有效)
         */
        private final static int SELECTED_SHEET = 0;
        
        /**
         * 預設從第一個sheet開始讀取(索引值為0)
         */
        private final static int READ_START_SHEET= 0;
        
        /**
         * 預設在最後一個sheet結束讀取(索引值=0,用負數來表示倒數第n行)
         */
        private final static int READ_END_SHEET = 0;
        
        /**
         * 預設列印各種資訊
         */
        private final static boolean PRINT_MSG = true;
        
        //%%%%%%%%-------常量部分 結束----------%%%%%%%%%
        
     
        //%%%%%%%%-------欄位部分 開始----------%%%%%%%%%
        /**
         * Excel檔案路徑
         */
        private String excelPath = "data.xlsx";
     
        /**
         * 設定開始讀取的位置,預設為0
         */
        private int startReadPos = READ_START_POS;
     
        /**
         * 設定結束讀取的位置,預設為0,用負數來表示倒數第n行
         */
        private int endReadPos = READ_END_POS;
        
        /**
         * 設定開始比較的列位置,預設為0
         */
        private int comparePos = COMPARE_POS;
     
        /**
         *  設定彙總的檔案是否需要替換,預設為true
         */
        private boolean isOverWrite = NEED_OVERWRITE;
        
        /**
         *  設定是否需要比較,預設為true(僅當不覆寫目標內容是有效,即isOverWrite=false時有效)
         */
        private boolean isNeedCompare = NEED_COMPARE;
        
        /**
         * 設定是否只操作第一個sheet
         */
        private boolean onlyReadOneSheet = ONLY_ONE_SHEET;
        
        /**
         * 設定操作的sheet在索引值
         */
        private int selectedSheetIdx =SELECTED_SHEET;
        
        /**
         * 設定操作的sheet的名稱
         */
        private String selectedSheetName = "";
        
        /**
         * 設定開始讀取的sheet,預設為0
         */
        private int startSheetIdx = READ_START_SHEET;
     
        /**
         * 設定結束讀取的sheet,預設為0,用負數來表示倒數第n行    
         */
        private int endSheetIdx = READ_END_SHEET;
        
        /**
         * 設定是否列印訊息
         */
        private boolean printMsg = PRINT_MSG;
        
        
        //%%%%%%%%-------欄位部分 結束----------%%%%%%%%%
        
     
        public static void main(String[] args) {
            ExcelUtil eu = new ExcelUtil();
            
            //從第一行開始讀取
            eu.setStartReadPos(1);
            
            String src_xlspath = "D:\\2.xls";
            String dist_xlsPath = "D:\\1.xls";
            List<Row> rowList;
            try {
                rowList = eu.readExcel(src_xlspath);
                //eu.writeExcel_xls(rowList, src_xlspath, dist_xlsPath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        
        public ExcelUtil(){
            
        }
        
        public ExcelUtil(String excelPath){
            this.excelPath = excelPath;
        }
        
        /**
         * 還原設定(其實是重新new一個新的物件並返回)
         * @return
         */
        public ExcelUtil RestoreSettings(){
            ExcelUtil instance = new  ExcelUtil(this.excelPath);
            return instance;
        }
        
        /**
         * 自動根據副檔名,呼叫對應的讀取方法
         *
         * @Title: writeExcel
         * @param xlsPath
         * @throws IOException
         */
        public List<Row> readExcel() throws IOException{
            return readExcel(this.excelPath);
        }
     
        /**
         * 自動根據副檔名,呼叫對應的讀取方法
         *
         * @Title: writeExcel
         * @param xlsPath
         * @throws IOException
         */
        public List<Row> readExcel(String xlsPath) throws IOException{
            
            //副檔名為空時,
            if (xlsPath.equals("")){
                throw new IOException("檔案路徑不能為空!");
            }else{
                File file = new File(xlsPath);
                if(!file.exists()){
                    throw new IOException("檔案不存在!");
                }
            }
            
            //獲取副檔名
            String ext = xlsPath.substring(xlsPath.lastIndexOf(".")+1);
            
            try {
                
                if("xls".equals(ext)){                //使用xls方式讀取
                    return readExcel_xls(xlsPath);
                }else if("xlsx".equals(ext)){        //使用xlsx方式讀取
                    return readExcel_xlsx(xlsPath);
                }else{                                    //依次嘗試xls、xlsx方式讀取
                    out("您要操作的檔案沒有副檔名,正在嘗試以xls方式讀取...");
                    try{
                        return readExcel_xls(xlsPath);
                    } catch (IOException e1) {
                        out("嘗試以xls方式讀取,結果失敗!,正在嘗試以xlsx方式讀取...");
                        try{
                            return readExcel_xlsx(xlsPath);
                        } catch (IOException e2) {
                            out("嘗試以xls方式讀取,結果失敗!\n請您確保您的檔案是Excel檔案,並且無損,然後再試。");
                            throw e2;
                        }
                    }
                }
            } catch (IOException e) {
                throw e;
            }
        }
        
        /**
         * 自動根據副檔名,呼叫對應的寫入方法
         *
         * @Title: writeExcel
         * @param rowList
         * @throws IOException
         */
        public void writeExcel(List<Row> rowList) throws IOException{
            writeExcel(rowList,excelPath);
        }
        
        /**
         * 自動根據副檔名,呼叫對應的寫入方法
         *
         * @Title: writeExcel
         * @param rowList
         * @param xlsPath
         * @throws IOException
         */
        public void writeExcel(List<Row> rowList, String xlsPath) throws IOException {
     
            //副檔名為空時,
            if (xlsPath.equals("")){
                throw new IOException("檔案路徑不能為空!");
            }
            
            //獲取副檔名
            String ext = xlsPath.substring(xlsPath.lastIndexOf(".")+1);
            
            try {
                
                if("xls".equals(ext)){                //使用xls方式寫入
                    writeExcel_xls(rowList,xlsPath);
                }else if("xlsx".equals(ext)){        //使用xlsx方式寫入
                    writeExcel_xlsx(rowList,xlsPath);
                }else{                                    //依次嘗試xls、xlsx方式寫入
                    out("您要操作的檔案沒有副檔名,正在嘗試以xls方式寫入...");
                    try{
                        writeExcel_xls(rowList,xlsPath);
                    } catch (IOException e1) {
                        out("嘗試以xls方式寫入,結果失敗!,正在嘗試以xlsx方式讀取...");
                        try{
                            writeExcel_xlsx(rowList,xlsPath);
                        } catch (IOException e2) {
                            out("嘗試以xls方式寫入,結果失敗!\n請您確保您的檔案是Excel檔案,並且無損,然後再試。");
                            throw e2;
                        }
                    }
                }
            } catch (IOException e) {
                throw e;
            }
        }
        
        /**
         * 修改Excel(97-03版,xls格式)
         *
         * @Title: writeExcel_xls
         * @param rowList
         * @param dist_xlsPath
         * @throws IOException
         */
        public void writeExcel_xls(List<Row> rowList, String dist_xlsPath) throws IOException {
            writeExcel_xls(rowList, excelPath,dist_xlsPath);
        }
     
        /**
         * 修改Excel(97-03版,xls格式)
         *
         * @Title: writeExcel_xls
         * @param rowList
         * @param src_xlsPath
         * @param dist_xlsPath
         * @throws IOException
         */
        public void writeExcel_xls(List<Row> rowList, String src_xlsPath, String dist_xlsPath) throws IOException {
     
            // 判斷檔案路徑是否為空
            if (dist_xlsPath == null || dist_xlsPath.equals("")) {
                out("檔案路徑不能為空");
                throw new IOException("檔案路徑不能為空");
            }
            // 判斷檔案路徑是否為空
            if (src_xlsPath == null || src_xlsPath.equals("")) {
                out("檔案路徑不能為空");
                throw new IOException("檔案路徑不能為空");
            }
     
            // 判斷列表是否有資料,如果沒有資料,則返回
            if (rowList == null || rowList.size() == 0) {
                out("文件為空");
                return;
            }
     
            try {
                HSSFWorkbook wb = null;
     
                // 判斷檔案是否存在
                File file = new File(dist_xlsPath);
                if (file.exists()) {
                    // 如果複寫,則刪除後
                    if (isOverWrite) {
                        file.delete();
                        // 如果檔案不存在,則建立一個新的Excel
                        // wb = new HSSFWorkbook();
                        // wb.createSheet("Sheet1");
                        wb = new HSSFWorkbook(new FileInputStream(src_xlsPath));
                    } else {
                        // 如果檔案存在,則讀取Excel
                        wb = new HSSFWorkbook(new FileInputStream(file));
                    }
                } else {
                    // 如果檔案不存在,則建立一個新的Excel
                    // wb = new HSSFWorkbook();
                    // wb.createSheet("Sheet1");
                    wb = new HSSFWorkbook(new FileInputStream(src_xlsPath));
                }
     
                // 將rowlist的內容寫到Excel中
                writeExcel(wb, rowList, dist_xlsPath);
     
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        /**
         * 修改Excel(97-03版,xls格式)
         *
         * @Title: writeExcel_xls
         * @param rowList
         * @param dist_xlsPath
         * @throws IOException
         */
        public void writeExcel_xlsx(List<Row> rowList, String dist_xlsPath) throws IOException {
            writeExcel_xls(rowList, excelPath , dist_xlsPath);
        }
     
        /**
         * 修改Excel(2007版,xlsx格式)
         *
         * @Title: writeExcel_xlsx
         * @param rowList
         * @param xlsPath
         * @throws IOException
         */
        public void writeExcel_xlsx(List<Row> rowList, String src_xlsPath, String dist_xlsPath) throws IOException {
     
            // 判斷檔案路徑是否為空
            if (dist_xlsPath == null || dist_xlsPath.equals("")) {
                out("檔案路徑不能為空");
                throw new IOException("檔案路徑不能為空");
            }
            // 判斷檔案路徑是否為空
            if (src_xlsPath == null || src_xlsPath.equals("")) {
                out("檔案路徑不能為空");
                throw new IOException("檔案路徑不能為空");
            }
     
            // 判斷列表是否有資料,如果沒有資料,則返回
            if (rowList == null || rowList.size() == 0) {
                out("文件為空");
                return;
            }
     
            try {
                // 讀取文件
                XSSFWorkbook wb = null;
     
                // 判斷檔案是否存在
                File file = new File(dist_xlsPath);
                if (file.exists()) {
                    // 如果複寫,則刪除後
                    if (isOverWrite) {
                        file.delete();
                        // 如果檔案不存在,則建立一個新的Excel
                        // wb = new XSSFWorkbook();
                        // wb.createSheet("Sheet1");
                        wb = new XSSFWorkbook(new FileInputStream(src_xlsPath));
                    } else {
                        // 如果檔案存在,則讀取Excel
                        wb = new XSSFWorkbook(new FileInputStream(file));
                    }
                } else {
                    // 如果檔案不存在,則建立一個新的Excel
                    // wb = new XSSFWorkbook();
                    // wb.createSheet("Sheet1");
                    wb = new XSSFWorkbook(new FileInputStream(src_xlsPath));
                }
                // 將rowlist的內容新增到Excel中
                writeExcel(wb, rowList, dist_xlsPath);
     
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
        /**
         * //讀取Excel 2007版,xlsx格式
         *
         * @Title: readExcel_xlsx
         * @return
         * @throws IOException
         */
        public List<Row> readExcel_xlsx() throws IOException {
            return readExcel_xlsx(excelPath);
        }
     
        /**
         * //讀取Excel 2007版,xlsx格式
         *
         * @Title: readExcel_xlsx
         * @return
         * @throws Exception
         */
        public List<Row> readExcel_xlsx(String xlsPath) throws IOException {
            // 判斷檔案是否存在
            File file = new File(xlsPath);
            if (!file.exists()) {
                throw new IOException("檔名為" + file.getName() + "Excel檔案不存在!");
            }
     
            XSSFWorkbook wb = null;
            List<Row> rowList = new ArrayList<Row>();
            try {
                FileInputStream fis = new FileInputStream(file);
                // 去讀Excel
                wb = new XSSFWorkbook(fis);
     
                // 讀取Excel 2007版,xlsx格式
                rowList = readExcel(wb);
     
            } catch (IOException e) {
                e.printStackTrace();
            }
            return rowList;
        }
     
        /***
         * 讀取Excel(97-03版,xls格式)
         *
         * @throws IOException
         *
         * @Title: readExcel
         */
        public List<Row> readExcel_xls() throws IOException {
            return readExcel_xls(excelPath);
        }
     
        /***
         * 讀取Excel(97-03版,xls格式)
         *
         * @throws Exception
         *
         * @Title: readExcel
         */
        public List<Row> readExcel_xls(String xlsPath) throws IOException {
     
            // 判斷檔案是否存在
            File file = new File(xlsPath);
            if (!file.exists()) {
                throw new IOException("檔名為" + file.getName() + "Excel檔案不存在!");
            }
     
            HSSFWorkbook wb = null;// 用於Workbook級的操作,建立、刪除Excel
            List<Row> rowList = new ArrayList<Row>();
     
            try {
                // 讀取Excel
                wb = new HSSFWorkbook(new FileInputStream(file));
     
                // 讀取Excel 97-03版,xls格式
                rowList = readExcel(wb);
     
            } catch (IOException e) {
                e.printStackTrace();
            }
            return rowList;
        }
     
        /***
         * 讀取單元格的值
         *
         * @Title: getCellValue
         * @param cell
         * @return
         */
        private String getCellValue(Cell cell) {
            Object result = "";
            if (cell != null) {
                switch (cell.getCellType()) {
                case Cell.CELL_TYPE_STRING:
                    result = cell.getStringCellValue();
                    break;
                case Cell.CELL_TYPE_NUMERIC:
                    result = cell.getNumericCellValue();
                    break;
                case Cell.CELL_TYPE_BOOLEAN:
                    result = cell.getBooleanCellValue();
                    break;
                case Cell.CELL_TYPE_FORMULA:
                    result = cell.getCellFormula();
                    break;
                case Cell.CELL_TYPE_ERROR:
                    result = cell.getErrorCellValue();
                    break;
                case Cell.CELL_TYPE_BLANK:
                    break;
                default:
                    break;
                }
            }
            return result.toString();
        }
     
        /**
         * 通用讀取Excel
         *
         * @Title: readExcel
         * @return
         */
        private List<Row> readExcel(Workbook wb) {
            List<Row> rowList = new ArrayList<Row>();
            
            int sheetCount = 1;//需要操作的sheet數量
            
            Sheet sheet = null;
            if(onlyReadOneSheet){    //只操作一個sheet
                // 獲取設定操作的sheet(如果設定了名稱,按名稱查,否則按索引值查)
                sheet =selectedSheetName.equals("")? wb.getSheetAt(selectedSheetIdx):wb.getSheet(selectedSheetName);
            }else{                            //操作多個sheet
                sheetCount = wb.getNumberOfSheets();//獲取可以操作的總數量
            }
            
            // 獲取sheet數目
            for(int t=startSheetIdx; t<sheetCount+endSheetIdx;t++){
                // 獲取設定操作的sheet
                if(!onlyReadOneSheet) {
                    sheet =wb.getSheetAt(t);
                }
                
                //獲取最後行號
                int lastRowNum = sheet.getLastRowNum();
     
                if(lastRowNum>0){    //如果>0,表示有資料
                    out("\n開始讀取名為【"+sheet.getSheetName()+"】的內容:");
                }
                
                Row row = null;
                // 迴圈讀取
                for (int i = startReadPos; i <= lastRowNum + endReadPos; i++) {
                    row = sheet.getRow(i);
                    if (row != null) {
                        rowList.add(row);
                        out("第"+(i+1)+"行:",false);
                         // 獲取每一單元格的值
                         for (int j = 0; j < row.getLastCellNum(); j++) {
                             String value = getCellValue(row.getCell(j));
                             if (!value.equals("")) {
                                 out(value + " | ",false);
                             }
                         }
                         out("");
                    }
                }
            }
            return rowList;
        }
     
        /**
         * 修改Excel,並另存為
         *
         * @Title: WriteExcel
         * @param rowList
         * @param xlsPath
         */
        private void writeExcel(Workbook wb, List<Row> rowList, String xlsPath) {
     
            if (wb == null) {
                out("操作文件不能為空!");
                return;
            }
     
            Sheet sheet = wb.getSheetAt(0);// 修改第一個sheet中的值
     
            // 如果每次重寫,那麼則從開始讀取的位置寫,否則果獲取原始檔最新的行。
            int lastRowNum = isOverWrite ? startReadPos : sheet.getLastRowNum() + 1;
            int t = 0;//記錄最新新增的行數
            out("要新增的資料總條數為:"+rowList.size());
            for (Row row : rowList) {
                if (row == null) continue;
                // 判斷是否已經存在該資料
                int pos = findInExcel(sheet, row);
     
                Row r = null;// 如果資料行已經存在,則獲取後重寫,否則自動建立新行。
                if (pos >= 0) {
                    sheet.removeRow(sheet.getRow(pos));
                    r = sheet.createRow(pos);
                } else {
                    r = sheet.createRow(lastRowNum + t++);
                }
                
                //用於設定單元格樣式
                CellStyle newstyle = wb.createCellStyle();
                
                //迴圈為新行建立單元格
                for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
                    Cell cell = r.createCell(i);// 獲取資料型別
                    cell.setCellValue(getCellValue(row.getCell(i)));// 複製單元格的值到新的單元格
                    // cell.setCellStyle(row.getCell(i).getCellStyle());//出錯
                    if (row.getCell(i) == null) continue;
                    copyCellStyle(row.getCell(i).getCellStyle(), newstyle); // 獲取原來的單元格樣式
                    cell.setCellStyle(newstyle);// 設定樣式
                    // sheet.autoSizeColumn(i);//自動跳轉列寬度
                }
            }
            out("其中檢測到重複條數為:" + (rowList.size() - t) + " ,追加條數為:"+t);
            
            // 統一設定合併單元格
            setMergedRegion(sheet);
            
            try {
                // 重新將資料寫入Excel中
                FileOutputStream outputStream = new FileOutputStream(xlsPath);
                wb.write(outputStream);
                outputStream.flush();
                outputStream.close();
            } catch (Exception e) {
                out("寫入Excel時發生錯誤! ");
                e.printStackTrace();
            }
        }
     
        /**
         * 查詢某行資料是否在Excel表中存在,返回行數。
         *
         * @Title: findInExcel
         * @param sheet
         * @param row
         * @return
         */
        private int findInExcel(Sheet sheet, Row row) {
            int pos = -1;
     
            try {
                // 如果覆寫目標檔案,或者不需要比較,則直接返回
                if (isOverWrite || !isNeedCompare) {
                    return pos;
                }
                for (int i = startReadPos; i <= sheet.getLastRowNum() + endReadPos; i++) {
                    Row r = sheet.getRow(i);
                    if (r != null && row != null) {
                        String v1 = getCellValue(r.getCell(comparePos));
                        String v2 = getCellValue(row.getCell(comparePos));
                        if (v1.equals(v2)) {
                            pos = i;
                            break;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return pos;
        }
     
        /**
         * 複製一個單元格樣式到目的單元格樣式
         *
         * @param fromStyle
         * @param toStyle
         */
        public static void copyCellStyle(CellStyle fromStyle, CellStyle toStyle) {
            toStyle.setAlignment(fromStyle.getAlignment());
            // 邊框和邊框顏色
            toStyle.setBorderBottom(fromStyle.getBorderBottom());
            toStyle.setBorderLeft(fromStyle.getBorderLeft());
            toStyle.setBorderRight(fromStyle.getBorderRight());
            toStyle.setBorderTop(fromStyle.getBorderTop());
            toStyle.setTopBorderColor(fromStyle.getTopBorderColor());
            toStyle.setBottomBorderColor(fromStyle.getBottomBorderColor());
            toStyle.setRightBorderColor(fromStyle.getRightBorderColor());
            toStyle.setLeftBorderColor(fromStyle.getLeftBorderColor());
     
            // 背景和前景
            toStyle.setFillBackgroundColor(fromStyle.getFillBackgroundColor());
            toStyle.setFillForegroundColor(fromStyle.getFillForegroundColor());
     
            // 資料格式
            toStyle.setDataFormat(fromStyle.getDataFormat());
            toStyle.setFillPattern(fromStyle.getFillPattern());
            // toStyle.setFont(fromStyle.getFont(null));
            toStyle.setHidden(fromStyle.getHidden());
            toStyle.setIndention(fromStyle.getIndention());// 首行縮排
            toStyle.setLocked(fromStyle.getLocked());
            toStyle.setRotation(fromStyle.getRotation());// 旋轉
            toStyle.setVerticalAlignment(fromStyle.getVerticalAlignment());
            toStyle.setWrapText(fromStyle.getWrapText());
     
        }
     
        /**
         * 獲取合併單元格的值
         *
         * @param sheet
         * @param row
         * @param column
         * @return
         */
        public void setMergedRegion(Sheet sheet) {
            int sheetMergeCount = sheet.getNumMergedRegions();
     
            for (int i = 0; i < sheetMergeCount; i++) {
                // 獲取合併單元格位置
                CellRangeAddress ca = sheet.getMergedRegion(i);
                int firstRow = ca.getFirstRow();
                if (startReadPos - 1 > firstRow) {// 如果第一個合併單元格格式在正式資料的上面,則跳過。
                    continue;
                }
                int lastRow = ca.getLastRow();
                int mergeRows = lastRow - firstRow;// 合併的行數
                int firstColumn = ca.getFirstColumn();
                int lastColumn = ca.getLastColumn();
                // 根據合併的單元格位置和大小,調整所有的資料行格式,
                for (int j = lastRow + 1; j <= sheet.getLastRowNum(); j++) {
                    // 設定合併單元格
                    sheet.addMergedRegion(new CellRangeAddress(j, j + mergeRows, firstColumn, lastColumn));
                    j = j + mergeRows;// 跳過已合併的行
                }
     
            }
        }
        
     
        /**
         * 列印訊息,
         * @param msg 訊息內容
         * @param tr 換行
         */
        private void out(String msg){
            if(printMsg){
                out(msg,true);
            }
        }
        /**
         * 列印訊息,
         * @param msg 訊息內容
         * @param tr 換行
         */
        private void out(String msg,boolean tr){
            if(printMsg){
                System.out.print(msg+(tr?"\n":""));
            }
        }
     
        public String getExcelPath() {
            return this.excelPath;
        }
     
        public void setExcelPath(String excelPath) {
            this.excelPath = excelPath;
        }
     
        public boolean isNeedCompare() {
            return isNeedCompare;
        }
     
        public void setNeedCompare(boolean isNeedCompare) {
            this.isNeedCompare = isNeedCompare;
        }
     
        public int getComparePos() {
            return comparePos;
        }
     
        public void setComparePos(int comparePos) {
            this.comparePos = comparePos;
        }
     
        public int getStartReadPos() {
            return startReadPos;
        }
     
        public void setStartReadPos(int startReadPos) {
            this.startReadPos = startReadPos;
        }
     
        public int getEndReadPos() {
            return endReadPos;
        }
     
        public void setEndReadPos(int endReadPos) {
            this.endReadPos = endReadPos;
        }
     
        public boolean isOverWrite() {
            return isOverWrite;
        }
     
        public void setOverWrite(boolean isOverWrite) {
            this.isOverWrite = isOverWrite;
        }
     
        public boolean isOnlyReadOneSheet() {
            return onlyReadOneSheet;
        }
     
        public void setOnlyReadOneSheet(boolean onlyReadOneSheet) {
            this.onlyReadOneSheet = onlyReadOneSheet;
        }
     
        public int getSelectedSheetIdx() {
            return selectedSheetIdx;
        }
     
        public void setSelectedSheetIdx(int selectedSheetIdx) {
            this.selectedSheetIdx = selectedSheetIdx;
        }
     
        public String getSelectedSheetName() {
            return selectedSheetName;
        }
     
        public void setSelectedSheetName(String selectedSheetName) {
            this.selectedSheetName = selectedSheetName;
        }
     
        public int getStartSheetIdx() {
            return startSheetIdx;
        }
     
        public void setStartSheetIdx(int startSheetIdx) {
            this.startSheetIdx = startSheetIdx;
        }
     
        public int getEndSheetIdx() {
            return endSheetIdx;
        }
     
        public void setEndSheetIdx(int endSheetIdx) {
            this.endSheetIdx = endSheetIdx;
        }
     
        public boolean isPrintMsg() {
            return printMsg;
        }
     
        public void setPrintMsg(boolean printMsg) {
            this.printMsg = printMsg;
        }
    }

       以上就是工具類的全部程式碼,現在演示一下讀取的功能:

        public void testRead() {
            try {
                
                ExcelUtil eu = new ExcelUtil();
                eu.setExcelPath("d:\\2.xls");
                
                System.out.println("=======測試Excel 預設 讀取========");
                eu.readExcel();
                
                System.out.println("\n=======測試Excel 從第四行讀取,倒數第二行結束========");
                eu = eu.RestoreSettings();//還原設定
                eu.setStartReadPos(3);
                eu.setEndReadPos(-1);
                eu.readExcel();
                
                System.out.println("\n=======測試Excel 讀取第二個sheet========");
                eu = eu.RestoreSettings();//還原設定
                eu.setSelectedSheetIdx(1);
                eu.readExcel();
                
                System.out.println("\n=======測試Excel 讀取所有的sheet========");
                eu = eu.RestoreSettings();//還原設定
                eu.setOnlyReadOneSheet(false);
                eu.readExcel();
                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

       操作的Excel檔案內容如下:


執行結果如下:


       上面程式碼的提示和結果已經解釋的很清楚了,我就不在這裡過多介紹。


       現在演示多個Excel的彙總合併功能,把上面的Excel內容合併到另一個Excel表中,這個Excel內容如下:


       測試程式碼如下:

        public void testMerge(){
            try {
                ExcelUtil eu1 = new ExcelUtil();//用來讀取源xls
                ExcelUtil eu2 = new ExcelUtil();//用來讀取目標xls,用於演示合併結果
                eu1.setExcelPath("d:\\2.xls");
                eu2.setExcelPath("d:\\1.xls");
                
                System.out.println("\n=======修改前,1.xls中的內容========");
                eu2.readExcel();
                
                System.out.println("\n=======讀取原始檔2.xls中的內容========");
                eu1.setStartReadPos(3);
                //eu1.setOverWrite(false);//是否覆寫目標檔案(預設覆寫)
                //eu1.setComparePos(1);//設定比較哪一列內容(預設為0,比較第一列內容)
                //eu1.setNeedCompare(false);//設定是否比較(預設值是true)。只有當不覆蓋目標檔案時,設定檢查重複才有效。
                
                eu1.writeExcel(eu1.readExcel(), "d:\\1.xls");//將讀取到的2.xls中的資料合併到1.xls中
                System.out.println("\n=======修改後,1.xls中的內容========");
                eu2.readExcel();//讀取合併後的1.xls的資料
                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

       執行結果如下:


       明明有重複的,為什麼提示重複為0呢?這是因為預設對目標檔案進行了覆寫,直接把原始檔的資料覆蓋到目標檔案中。所以只會顯示原始檔的內容。

       如果把上段測試程式碼的13、14、15行換成下面的內容,手動還原1.xls,再測試一下:

        eu1.setOverWrite(false);//是否覆寫目標檔案(預設覆寫)
        //eu1.setComparePos(1);//設定比較哪一列內容(預設為0,比較第一列內容)
        //eu1.setNeedCompare(false);//設定是否比較(預設值是true)。只有當不覆蓋目標檔案時,設定檢查重複才有效。

        執行結果如下:


       這次把覆寫給取消了,在合併的時候,預設會比較第一列的資料,存在的則不再追加,所以1.xls中的張三保留了,李四追加到了後面。對比上面的覆蓋,可以看到,覆寫時跟2.xls的順序一致(李四在張三前面),而不覆寫,則在文件的最後執行追加操作。


       我們再次修改測試程式碼:

        eu1.setOverWrite(false);//是否覆寫目標檔案(預設覆寫)
        eu1.setComparePos(1);//設定比較哪一列內容(預設為0,比較第一列內容)
        //eu1.setNeedCompare(false);//設定是否比較(預設值是true)。只有當不覆蓋目標檔案時,設定檢查重複才有效。

       同時手動把1.xls中的內容修改如下:


       執行結果如下:


       大家可以看到,比較的物件變到的第二列,由於張三所在行的第二列與新增的內容不相同,所以張三被追加到了文件的和麵。


       最後再次修改測試程式碼,並且手動還原1.xls為原始狀態。

        eu1.setOverWrite(false);//是否覆寫目標檔案(預設覆寫)
        //eu1.setComparePos(1);//設定比較哪一列內容(預設為0,比較第一列內容)
        eu1.setNeedCompare(false);//設定是否比較(預設值是true)。只有當不覆蓋目標檔案時,設定檢查重複才有效。

        執行結果如下:


       這次把覆寫和自動比較都取消了,結果就是直接在目標檔案的後面進行追加操作。


       程式碼有點多,大家可能看的有點累了,不過寫這個工具類消耗了我n多腦細胞,還是希望對大家可以有所幫助。如果有什麼問題,歡迎大家批評指正。