POI 實現對 Excel 檔案讀寫,poiexcel

來源:互聯網
上載者:User

POI 實現對 Excel 檔案讀寫,poiexcel
1. Apache POI 簡介

     Apache POI是Apache軟體基金會的開放源碼函式庫。

     提供API給Java應用程式對Microsoft Office格式檔案讀和寫的功能。

     老外起名字總是很謙虛,POI為(Poor Obfuscation Implementation)的首字母縮寫,意為“可憐的模糊實現”。

     如果你查看過 Apache 開源庫中的任意項目的源碼,你會發現恰到好處的設計模式、模組之間的高內聚低耦合、介面抽象相當到位、實現方式也非常優雅,這樣的一些特定。

     o(︶︿︶)o 唉 需要多嚴謹的思維、多大的代碼實現量,多少項目的設計積累,才能達到那樣的高度?

     POI 中主要提供的讀寫 Microsoft Office 功能點如下:

  •  HSSF -- 提供讀寫Microsoft Excel格式檔案的功能。
  •  XSSF -- 提供讀寫Microsoft Excel OOXML格式檔案的功能。
  •  HWPF -- 提供讀寫Microsoft Word格式檔案的功能。
  •  HSLF -- 提供讀寫Microsoft PowerPoint格式檔案的功能。
  •  HDGF -- 提供讀寫Microsoft Visio格式檔案的功能。

     本文借一次使用POI 實現讀寫 Excel 的過程,記述其中具體POI運用的方式。

     由搜尋引擎點進來的同學,上面這一句話就是本文的主旨句。若能解決你問題,請往下細看。

     項目中使用的是最新的 poi-3.14-20160307.jar,百度雲地址:http://pan.baidu.com/s/1bnWFWg3 密碼: kame

2.一點點實現前的設計

     因項目比較大,下面為單獨建立工程後的例子。

   

3.POI 寫 Excel

     左側使用案例圖為 POI 寫 Excel

    a.getExcelData: 擷取需要輸出到Excel資料,這裡的資料擷取可以是從持久層,頁面展示層......

      (例子中的資料為Mysql自有資料庫中表help_categroy 表記錄),其中的 JavaBean建立 與 資料庫擷取的過程這裡就不說了。

      擷取資料的資料類型是這樣的 List<HelpCategory>    

     b.POI Write Workbook:這裡才是關鍵的地方,使用POI 將資料執行個體化為 HSSFWorkbook。核心代碼如下:

public HSSFWorkbook expExcel(List<HelpCategory> helpCategories) { HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet(); createSheetStyle(workbook, sheet); HSSFRow row = sheet.createRow(0); HSSFCell cell; HelpCategory category = new HelpCategory(); Field[] fields = category.getClass().getDeclaredFields(); for (int j = 0; j < fields.length; j++) { cell = row.createCell(j); cell.setCellValue(fields[j].getName()); cell.setCellStyle(this.textAlignCenter); } for (int i = 0; i < helpCategories.size(); i++) { category = helpCategories.get(i); row = sheet.createRow(i + 1); for (int k = 0; k < fields.length; k++) { Field field = fields[k]; Object o = invokeGet(category, field.getName()); cell = row.createCell(k); cell.setCellValue(o != null ? o.toString() : ""); cell.setCellStyle((k == 0 || k == 1) ? this.textAlignCenter : this.textAlignLeft); } } return workbook; }Core Code

     擷取JavaBean欄位值作為表頭,並設定表頭的樣式:

        HSSFRow row = sheet.createRow(0);        HSSFCell cell;        HelpCategory category = new HelpCategory();        Field[] fields = category.getClass().getDeclaredFields();        for (int j = 0; j < fields.length; j++) {            cell = row.createCell(j);            cell.setCellValue(fields[j].getName());            cell.setCellStyle(this.textAlignCenter);        }

     擷取JavaBean HelpCategory 中欄位的值填充到對應的表格中,並設定樣式:

     for (int i = 0; i < helpCategories.size(); i++) {            category = helpCategories.get(i);            row = sheet.createRow(i + 1);            for (int k = 0; k < fields.length; k++) {                Field field = fields[k];                Object o = invokeGet(category, field.getName());                cell = row.createCell(k);                cell.setCellValue(o != null ? o.toString() : "");                cell.setCellStyle((k == 0 || k == 1) ? this.textAlignCenter : this.textAlignLeft);            }        }

      這裡面用的了一點反射的東西,來擷取javaBean屬性的值。

      如果你覺得反射的效率有點差勁,可以自己構造一個Map資料集合,同樣能達到這樣的效果。

  private Object invokeGet(Object o, String fieldName) {        Method method = getGetMethod(o.getClass(), fieldName);        try {            return method.invoke(o, new Object[0]);        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    private Method getGetMethod(Class objectClass, String fieldName) {        StringBuilder sb = new StringBuilder();        sb.append("get");        sb.append(fieldName.substring(0, 1).toUpperCase());        sb.append(fieldName.substring(1));        try {            return objectClass.getMethod(sb.toString());        } catch (Exception e) {            e.printStackTrace();        }        return null;    }

        同樣你可以設定表格樣式、邊框樣式:

    private void createSheetStyle(HSSFWorkbook _workbook, HSSFSheet _sheet) {        // 設定表字型        HSSFFont font10 = _workbook.createFont();        font10.setFontHeightInPoints((short) 12);        font10.setFontName("黑體");        // 設定表樣        this.textAlignCenter = getCellStyle(_workbook, font10, HSSFCellStyle.ALIGN_CENTER);        this.textAlignLeft = getCellStyle(_workbook, font10, HSSFCellStyle.ALIGN_LEFT);        // 設定列寬        _sheet.setColumnWidth(0, 4000);        _sheet.setColumnWidth(1, 4000);        _sheet.setColumnWidth(2, 10000);        _sheet.setColumnWidth(3, 10000);    }

      上面的樣式設定,如果還滿足不了你的功能需求,更多的設定請參考部落格:http://langhua9527.iteye.com/blog/388005

4.POI 讀 Excel

      左側使用案例圖為 POI 寫 Excel

      a.getExcleFile:擷取要讀取的Excel檔案...這裡就不說了。(注意:判斷擷取的檔案尾碼名)

        String fileName = excel.getName();        int iIndex = fileName.lastIndexOf(".");        String ext = (iIndex < 0) ? "" : fileName.substring(iIndex + 1).toLowerCase();        if (!"xls,xlsx".contains(ext) || "".contains(ext)) {            System.out.println("檔案類型不是EXCEL!");        }

      b.POI Read Workbook:這裡就是重點啦,使用POI讀取Excel檔案,解析並進行儲存到你自己資料類型當中。

           ArrayList<HelpCategory> categories = new ArrayList<>();        try {            POIFSFileSystem poifsFileSystem = new POIFSFileSystem(new FileInputStream(excel));            HSSFWorkbook workbook = new HSSFWorkbook(poifsFileSystem);            HSSFSheet sheet = workbook.getSheetAt(0);            HelpCategory category = new HelpCategory();            Field[] declaredField = category.getClass().getDeclaredFields();            for (int k = 1; k <= sheet.getLastRowNum(); k++) {                HSSFRow row = sheet.getRow(k);                category = new HelpCategory();                for (int j = 0; j < declaredField.length; j++) {                    HSSFCell cell = row.getCell(j);                    invokeSet(category, declaredField[j].getName(), cell.getStringCellValue());                }                categories.add(category);            }        } catch (Exception e) {            e.printStackTrace();        }

       上面也同樣用到了一些反射的東西,這裡擷取JavaBean 的set方法,來設定具體的屬性。

   public void invokeSet(Object o, String fieldName, Object value) {        Method method = getSetMethod(o.getClass(), fieldName);        try {            method.invoke(o, new Object[]{value});        } catch (Exception e) {            e.printStackTrace();        }    }    public Method getSetMethod(Class objectClass, String fieldName) {        try {            Class[] parameterTypes = new Class[1];            Field field = objectClass.getDeclaredField(fieldName);            parameterTypes[0] = field.getType();            StringBuffer sb = new StringBuffer();            sb.append("set");            sb.append(fieldName.substring(0, 1).toUpperCase());            sb.append(fieldName.substring(1));            Method method = objectClass.getMethod(sb.toString(), parameterTypes);            return method;        } catch (Exception e) {            e.printStackTrace();        }        return null;    }

      上述例子僅當作拋磚引玉之用,項目中的具體需求隨時都有其他的變化。

     如擷取資料的途徑可能是多表聯集查詢或者是展現層、結果需要進行其他運算、寫Excel表格樣式的變化........

      但熟悉具體核心讀寫實現,已不變應萬變,可為上將。

     

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.