POI詳解以及 Java 使用POI操做Excel

一. POI詳解

1. 簡介

Apache POI 簡介是用Java編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Java程式對Microsoft Office(Excel、WORD、PowerPoint、Visio等)格式檔案讀和寫的功能。POI爲「Poor Obfuscation Implementation」的首字母縮寫,意爲「可憐的模糊實現」。
Apache官網:https://www.apache.org/
POI網址:http://poi.apache.org/
POI文檔:http://poi.apache.org/apidocs/index.html
本項目中使用的是poi-3.17.jar,相對來講比較穩定,而且有對應版本的文檔。html

2.經常使用類介紹

Workbook類和HSSFWorkbook類、Sheet類 和 HSSFSheet類、Row類 和 HSSFRow類、Cell類和HSSFCell類是繼承關係,java

1)Workbook類

Workbook workbook = WorkbookFactory.create(new File(filePath)); // 根據已有的Excel文件建立工做簿
workbook.write(out); // 工做簿寫入,不加這句沒法更改Excel文件

2)HSSFWorkbook類

HSSFWorkbook wb= new HSSFWorkbook();// 生成新的Excel文件

HSSFWorkbook workbook= new HSSFWorkbook(new FileInputStream(path)); // 根據已有的Excel文件建立工做簿

3)Sheet類 和 HSSFSheet類

Sheet sheet = wb.getSheetAt(sheetIndex); // 經過索引得到文件中指定sheet,從0開始
 Sheet sheet = wb.getSheetAt("sheet1"); // 經過sheet名得到文件中指定sheet
 Sheet sheet = wb.createSheet(String sheetname);  // 建立一個新的Sheet 
 HSSFSheet sheet = workbook.getSheetAt(sheetIndex); // 經過索引得到文件中指定sheet,從0開始
 HSSFSheet sheet = workbook.getSheetAt("sheet1"); // 經過sheet名得到文件中指定sheet
 HSSFSheet sheet = workbook.createSheet("sheet1"); // 建立一個新的Sheet 

 int RowNum =  sheet.getLastRowNum(); // 得到最大行數

 sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol)); //  合併單元格 

sheet.shiftRows(rowIndex, lastRowNo, n); // 插入某一行

4)Row類 和 HSSFRow類

Row row = sheet.getRow(i); // 得到指定行
 HSSFRow row = sheet.getRow(i); 

 Row row = sheet.createRow(i); // 建立指定行
 HSSFRow row = sheet.createRow(i); // 建立指定行

 row.getCell(i); // 得到指定單元格

5)Cell類 和 HSSFCell類

cell.getRowIndex(); // 獲取當前單元格的行數
cell.getColumnIndex(); // 獲取當前單元格的列數
cell.setCellValue(""); // 給當前單元格賦值
cell.getRow() // 獲取當前單元格所在的行對象

6)CellStyle類 和 HSSFCellStyle類

CellStyle style = wb.createCellStyle(); // 建立一個單元格格式對象
style.setFillForegroundColor(IndexedColors.PALE_BLUE.getIndex()); // 設置單元格填充顏色
style.setFillBackgroundColor(short bg);  //設置背景顏色
style.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 設置單元格畫布格式
style.setWrapText(true); // 設置自動換行
style.setAlignment(HorizontalAlignment.CENTER); // 水平居中
style.setVerticalAlignment(VerticalAlignment.CENTER); // 垂直居中
font.setFontHeightInPoints((short) heigth); // 設置行高
style.setBorderBottom(BorderStyle.THIN); // 單元格邊框
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
cell.setCellStyle(style); // 將單元格格式賦值給單元格

7)Font類 和 HSSFFont類

Font font = wb.createFont(); // 建立字體格式對象
font.setFontName("宋體"); // 設置字體樣式
font.setFontHeightInPoints((short) 11); // 字體大小
font.setBold(boolean bold); // 設置是否粗體
font.setItalic(boolean italic);  // 設置傾斜
font.setUnderline(byte underline); 設置下劃線
style.setFont(font); // 將字體賦值給單元格樣式(必須將字體樣式賦值給單元格樣式,再將單元格樣式賦值給單元格對象才能生效)

二. Java 使用POI操做Excel

我寫項目時將操做Excel的方法進行簡單的封裝,一下代碼是從多個項目中提取的的通用方法,有些是項目中的需求邏輯,相信你們應該能看的出來,你們有什麼錯誤或者補充的能夠留言或私信。廢話很少說直接上代碼:apache

/**
     * 搜索全部的excel,而且循環調用excel數據處理方法
     *
     * @throws IOException
     */
    public void readFile() {
        File file = new File(path);
        // 獲取包下全部excel文件的名稱集合
        String[] filelist = file.list();
        for (int i = 0; i < filelist.length; i++) {
            // 獲取excel文件
            readExcelToObj(path + "\\" + filelist[i]);

        }
    }

public List<List<String>> readExcelToObj(String filepath) {
        HSSFWorkbook wbook = new HSSFWorkbook(new FileInputStream(path));
        Workbook wb = null;
        try {
            wb = WorkbookFactory.create(new File(filepath));
            merge = readExcel(wb, 0, 4, 0);
        } catch (InvalidFormatException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                wb.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return merge;
    }

 /**
     * 讀取excel文件
     *
     * @param wb
     * @param sheetIndex    sheet頁下標:從0開始
     * @param startReadLine 開始讀取的行:從0開始
     * @param tailLine      去除最後讀取的行
     */
    private List<List<String>> readExcel(Workbook wb, int sheetIndex, int startReadLine, int tailLine) {
        Sheet sheet = wb.getSheetAt(sheetIndex);
        Sheet sheets =  wb.createSheet();
        Row row = null;
        int MaxRowNum = sheet.getLastRowNum();
        List<List<String>> result = new ArrayList<>();
        for (int i = startReadLine; i < MaxRowNum - tailLine + 1; i++) {
            row = sheet.getRow(i);
            List<String> rowContent = new ArrayList<>();
            for (Cell c : row) {
                if (getCellValue(c).contains("備註:1")) {
                    MaxRowNum = c.getRowIndex();
                    c.getColumnIndex();
                    break;
                }
                rowContent.add(getCellValue(c));
            }
            if (!rowContent.isEmpty()) {
                result.add(rowContent);
            }
        }
        return result;
    }

 /**
     * 讀取excel文件存儲爲Map<String,String>
     *
     * @param wb
     * @param sheetIndex    sheet頁下標:從0開始
     * @param startReadLine 開始讀取的行:從0開始
     * @param tailLine      去除最後讀取的行
     */
    private Map<String, String> readExcelForMap(Workbook wb, int sheetIndex, int startReadLine, int tailLine,int flat) {
        Sheet sheet = wb.getSheetAt(sheetIndex);
        Row row = null;
        int MaxRowNum = sheet.getLastRowNum();
        Map<String, String> map = new HashMap<>();
        if(flat == 0||flat== 1){
            for (int i = startReadLine; i < MaxRowNum - tailLine + 1; i++) {
                row = sheet.getRow(i);
                if (getCellValue(row.getCell(0)).contains("備註:1.")) {
                    break;
                }
                String key = getCellValue(row.getCell(1)) + "/" + getCellValue(row.getCell(2)) + "/" + getCellValue(row.getCell(3)) + "/" + getCellValue(row.getCell(4));
                String value = getCellValue(row.getCell(10));

                map.put(key, value);
            }
        }else{
            for (int i = startReadLine; i < MaxRowNum - tailLine + 1; i++) {
                row = sheet.getRow(i);
                String key = getCellValue(row.getCell(4))+"/"+getCellValue(row.getCell(8));
                String value = getCellValue(row.getCell(17));
                map.put(key, value);
            }
        }
        System.out.println(map);
        return map;
    }

 /**
     * 讀取excel文件存儲爲List<List<String>>
     *
     * @param wb
     * @param sheetIndex    sheet頁下標:從0開始
     * @param startReadLine 開始讀取的行:從0開始s
     * @param tailLine      去除最後讀取的行
     */
    private List<List<String>> readExcel(Workbook wb, int sheetIndex, int startReadLine, int tailLine, int flat) {
        Sheet sheet = wb.getSheetAt(sheetIndex);
        Row row = null;
        int MaxRowNum = sheet.getLastRowNum();
        List<List<String>> result = new ArrayList<>();
        for (int i = startReadLine; i < MaxRowNum - tailLine + 1; i++) {
            row = sheet.getRow(i);
            if (getCellValue(row.getCell(1)) == "" && getCellValue(row.getCell(2)) == "" && getCellValue(row.getCell(3)) == "") {
                continue;
            }
            List<String> rowContent = new ArrayList<>();
            if (flat == 3 && i == 3) {
                rowContent.add("序號");
            } else if (flat == 3 && i > 3) {
                rowContent.add(i - 3 + "");
            } else if (flat == 4 && i == 0) {
                rowContent.add("序號");
            } else if (flat == 4 && i > 0) {
                rowContent.add(i + "");
            }
            for (Cell hssfCell : row) {
                if (flat == 1) {
                    if (hssfCell.getColumnIndex() < 9) {
                        rowContent.add(getCellValue(hssfCell));
                    }
                } else if (flat == 2) {
                    if (hssfCell.getColumnIndex() == 3 || hssfCell.getColumnIndex() == 5 || hssfCell.getColumnIndex() == 9 || hssfCell.getColumnIndex() == 11) {
                        rowContent.add(getCellValue(hssfCell));
                    }
                } else if (flat == 3) {
                    rowContent.add(getCellValue(hssfCell));
                } else {

                    rowContent.add(getCellValue(hssfCell));
                }
            }
            result.add(rowContent);
        }
        return result;
    }


/**
     * 找到須要插入的行數,並新建一個POI的row對象
     *
     * @param sheet
     * @param rowIndex
     * @return
     */
    private HSSFRow createRow(HSSFSheet sheet,Integer rowIndex,int n) {
        HSSFRow row = null;
        if (sheet.getRow(rowIndex) != null) {
            int lastRowNo = sheet.getLastRowNum();
            sheet.shiftRows(rowIndex, lastRowNo, n);
        }
        row = sheet.createRow(rowIndex);
        return row;
    }

/**
     * 保存工做薄
     *
     * @param wb
     */
    private void saveExcel(HSSFWorkbook wb,String fileToBeRead) {
        FileOutputStream fileOut;
        try {
            fileOut = new FileOutputStream(fileToBeRead);
            wb.write(fileOut);
            fileOut.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 /**
     * 獲取單元格的值
     *
     * @param cell
     * @return
     */
    public String getCellValue(Cell cell) {
        if (cell == null) return "";
        if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
            return cell.getStringCellValue();
        } else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
            return String.valueOf(cell.getBooleanCellValue());
        } else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
            return cell.getCellFormula();
        } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
            return String.valueOf((int) cell.getNumericCellValue());
        }
        return "";
    }

/**
     * 判斷指定的單元格是不是合併單元格
     *
     * @param sheet
     * @param row    行下標
     * @param column 列下標
     * @return
     */
    private boolean isMergedRegion(Sheet sheet, int row, int column) {
        int sheetMergeCount = sheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergeCount; i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            int firstColumn = range.getFirstColumn();
            int lastColumn = range.getLastColumn();
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            if (row >= firstRow && row <= lastRow) {
                if (column >= firstColumn && column <= lastColumn) {
                    return true;
                }
            }
        }
        return false;
    }

/**
     * 獲取合併單元格的值
     *
     * @param sheet
     * @param row
     * @param column
     * @return
     */
    public String getMergedRegionValue(Sheet sheet, int row, int column) {
        int sheetMergeCount = sheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergeCount; i++) {
            CellRangeAddress ca = sheet.getMergedRegion(i);
            int firstColumn = ca.getFirstColumn();
            int lastColumn = ca.getLastColumn();
            int firstRow = ca.getFirstRow();
            int lastRow = ca.getLastRow();
            if (row >= firstRow && row <= lastRow) {
                if (column >= firstColumn && column <= lastColumn) {
                    Row fRow = sheet.getRow(firstRow);
                    Cell fCell = fRow.getCell(firstColumn);
                    return getCellValue(fCell);
                }
            }
        }
        return null;
    }

 /**
     * 設置字體樣式
     *
     * @param heigth
     * @param font
     * @param style
     * @param cell
     */
    public void setFontStyle(int heigth, HSSFFont font, HSSFCellStyle style, HSSFCell cell) {
        font.setFontName("宋體");
        font.setFontHeightInPoints((short) heigth);
        style.setFont(font);
        cell.setCellStyle(style);
    }

    public static void setHeadStyle(CellStyle style, HSSFCell cell) {
        style.setWrapText(true);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setBorderBottom(BorderStyle.THIN);
        style.setBorderLeft(BorderStyle.THIN);
        style.setBorderRight(BorderStyle.THIN);
        style.setBorderTop(BorderStyle.THIN);
        cell.setCellStyle(style);
    }

 /**
     * 複製一個單元格樣式到目的單元格樣式
     * @param fromStyle
     * @param toStyle
     */
    public static void copyCellStyle(HSSFCellStyle fromStyle,
                                     HSSFCellStyle toStyle) {
        toStyle.setAlignment(fromStyle.getAlignmentEnum());
        //邊框和邊框顏色
        toStyle.setBorderBottom(fromStyle.getBorderBottomEnum());
        toStyle.setBorderLeft(fromStyle.getBorderLeftEnum());
        toStyle.setBorderRight(fromStyle.getBorderRightEnum());
        toStyle.setBorderTop(fromStyle.getBorderTopEnum());
        toStyle.setTopBorderColor(fromStyle.getTopBorderColor());
        toStyle.setBottomBorderColor(fromStyle.getBottomBorderColor());
        toStyle.setRightBorderColor(fromStyle.getRightBorderColor());
        toStyle.setLeftBorderColor(fromStyle.getLeftBorderColor());
        toStyle.setDataFormat(fromStyle.getDataFormat());
        toStyle.setFillPattern(fromStyle.getFillPatternEnum());
//		toStyle.setFont(fromStyle.getFont(null));
        toStyle.setHidden(fromStyle.getHidden());
        toStyle.setIndention(fromStyle.getIndention());//首行縮進
        toStyle.setLocked(fromStyle.getLocked());
        toStyle.setRotation(fromStyle.getRotation());//旋轉
        toStyle.setVerticalAlignment(fromStyle.getVerticalAlignmentEnum());
        toStyle.setWrapText(fromStyle.getWrapText());
    }

三. 結語

這是我畢業剛入職第一天的第一個任務,在徹底沒學過,甚至沒聽過的狀況下,能將功能一個一個實現出來,感受仍是挺有幫助的,但願之後能繼續保持學習進步的精神。畢竟有句話說的好,真正的大師永遠保持一顆學徒(學禿)的心,我離大師還很遠很遠,可是我會朝着這個方向一直走下去。api

相關文章
相關標籤/搜索