1. 程式人生 > >JavaWEB--POI之EXCEL操作、優化、封裝詳解系列(一)--概述與原理

JavaWEB--POI之EXCEL操作、優化、封裝詳解系列(一)--概述與原理

鑑於現在部落格混雜臃腫,對POI技術講解得十分不不充分,讓本博主在開發優化時遭遇諸多大坑,為了讓後人更好製作企業級報表,我將在這一系列詳細解說這個以及羅列我所遇到的諸多問題。並且基於強大的POI技術寫一個輔助工具庫給大家。

本系列的所有程式碼均可以直接執行,請放心使用。

文章結構:(1)概述;(2)原理(以例子講解)

先貼出官方地址:POI官網

一、概述:

(一)框架背景:

Apache POI 是用Java編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Java程式對Microsoft Office格式檔案讀和寫的功能。

Apache POI 是建立和維護操作各種符合Office Open XML(OOXML)標準和微軟的OLE 2複合文件格式(OLE2)的Java API。用它可以使用Java讀取和建立,修改MS Excel檔案.而且,還可以使用Java讀取和建立MS Word和MSPowerPoint檔案。Apache POI 提供Java操作Excel解決方案(適用於Excel97-2008)。

(二)POI框架的類庫:

HSSF - 提供讀寫Microsoft Excel格式檔案的功能。

XSSF - 提供讀寫Microsoft Excel OOXML格式檔案的功能。

HWPF - 提供讀寫Microsoft Word格式檔案的功能。

HSLF - 提供讀寫Microsoft PowerPoint格式檔案的功能。

HDGF - 提供讀寫Microsoft Visio格式檔案的功能。

(三)對比以前的框架JXL:(後面會給出一個jxl的例子)

(1)JXL概述:

通過Jxl,Java可以很方便的操作微軟的Excel文件。jxl是一個韓國人寫的java操作excel的工具,jExcelAPI對中文支援非常好,API是純Java的, 並不 依賴Windows系統,即使執行在Linux下,它同樣能夠正確的處理Excel檔案。 另外需要說明的是,這套API對圖形和圖表的支援很有限,而且 僅僅識別PNG格式。

(2)兩者現狀:

jxl現在基本上沒被維護了。相反,poi屬於Apache開源專案的一部分,更新維護得比較好,同時poi可以支援更高版本的excel,而jxl只能支援excel2003以及之前的版本(侷限的資料量)。

小檔案使用jxl解析效率比較高,但是因為支援的excel版本的限制,導致不能匯出65535以上量級的資料。

(3)JXL使用DEMO:

1)匯出JXL的庫
<!-- jxl excel匯入匯出的另一個庫 -->
    <dependency>
      <groupId>net.sourceforge.jexcelapi</groupId
>
<artifactId>jxl</artifactId> <version>2.6.12</version> </dependency>
2)程式碼實現:
package com.fuzhu.utils;

import jxl.Workbook;
import jxl.WorkbookSettings;
import jxl.write.Label;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by 符柱成 on 2017/8/23.
 */
public class JXLTest {

    public static void main(String [] args){
        writeInExcel();
    }
    public static void writeInExcel() {
        //列的標題,把他寫進程式碼,是為了方便管理業務的增刪
        List<String> headList = new ArrayList<>();
        headList.add("專線型別");
        headList.add("業務型別");
        headList.add("工單標題");
        headList.add("工單號");
        headList.add("ESOP單號");
        headList.add("來源渠道");

        //(一)路徑的拼接(模板檔案路徑)
        //模板檔案流
        String basePath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
        basePath = StringUtils.substringBeforeLast(basePath, "/");
        basePath = StringUtils.substringBeforeLast(basePath, "/");
        basePath = StringUtils.substringBeforeLast(basePath, "/");
        basePath = basePath+"/src/main/webapp/source/";
        File templateFile = new File(basePath + "commonexport.xls");
        //(二)匯出的檔案流
        String resultFilePath = basePath + "匯出的檔名.xls";
        File resultFile = new File(resultFilePath);
        //(三)excel檔案物件
        Workbook wb = null;//先初始化一個EXCEL檔案
        WorkbookSettings settings = new WorkbookSettings();//以下兩行先不要理會,後面會詳細解釋,這個是關於Linux與wins的區別,關於單元格最大的字元限制
        settings.setWriteAccess(null);
        WritableWorkbook wwb = null;

        try {
            wb = Workbook.getWorkbook(templateFile);
            wwb = Workbook.createWorkbook(resultFile, wb, settings);
            WritableSheet sheet = wwb.createSheet("Sheet1", 0);//excel的工作表格
            //(四)標題欄
            for (int i = 0; i < headList.size(); i++) {//這個是我們匯出的模板excel的列數
                Label la = new Label(i, 0, wb.getSheet(0).getCell(i, 0).getContents());
                sheet.addCell(la);
            }
            List<Map<String, String>> dataList=new ArrayList<>();
            sheet.setRowView(0, 300);//設定第一行高度
            //(五)資料準備--假資料
            for (int t=0;t<1000;t++){
                Map<String, String> temp = new HashMap<>();
                temp.put("groupid", String.valueOf(1+t));
                temp.put("productcode", "abc"+String.valueOf(1+t));
                dataList.add(temp);
            }
            //(六)導進excel的資料
            for (int i = 0; i < dataList.size(); i++) {
                Map<String, String> map = dataList.get(i);
                Label C1 = new Label(0, i + 1, map.get("groupid"));//第一個引數指示:第一列
                Label C3 = new Label(2, i + 1, map.get("productcode"));//第一個引數指示:第三列
                sheet.addCell(C1);
                sheet.addCell(C3);
            }
            /*
            (七)匯出
            */
            wwb.write();
            wwb.close();
            wb.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

二、原理:

(一)明確組成一個EXCEL檔案需要多少物件:

(1)一個excel表格

HSSFWorkbook wb = new HSSFWorkbook();
XSSFWorkbook xb = new XSSFWorkbook();

(2)一個工作表格(sheet):

Sheet sheet = wb.getSheetAt(0);

(3)一行(row):

HSSFRow row1 = sheet.createRow(0);

(4)一個單元格(cell):

Cell cell = cells.next()

(5)單元格格式(cellstyle):

HSSFCellStyle style4 = wb.createCellStyle()

(6)單元格內容格式(HSSFDataFormat ):

HSSFDataFormat format= wb.createDataFormat();

(二)一個例子說明POI解析EXCEL的大致原理:(取自網上已有–一個粗糙例子)取自此文

某管理員要查某層樓有多少人叫什麼名字?

1)首先要明確大樓在那裡(找到對應的檔案)

2)其次要明確是在第幾單元(找到對應的sheet)

3)在找到第幾層樓(對應的row)

4)敲門問住戶戶主先生/小姐的姓名(cell)

public class TestA {  

    public static void main(String args[]) throws Exception {  
        //找到大樓的位置  
        FileInputStream input = new FileInputStream("d:\\dir.xls");  
        //告訴管理員  
        POIFSFileSystem f = new POIFSFileSystem(input);  
        //走到大樓樓下  
        HSSFWorkbook wb = new HSSFWorkbook(f);  
        //確認自己走到第幾單元  
        HSSFSheet sheet = wb.getSheetAt(0);  
        //看一看有沒有樓層  
        Iterator rows = sheet.rowIterator();  
        while (rows.hasNext()) {  
            //如果有我們一層層問  
            HSSFRow row = (HSSFRow)rows.next();  
            Iterator cells = row.cellIterator();  
            //如果有人開門  
            while(cells.hasNext()) {  
                //我們一戶一戶的登記  
                HSSFCell cell = (HSSFCell) cells.next();  
                //是先生還是小姐(對應的資料型別)  
                int cellType = cell.getCellType();  
                System.out.print(getValue(cell,cellType));  
            }  
            System.out.println("");  
        }  

    }  

(三)至於EXCEL原理,那太逆天了,這裡就不做解釋了。給個excel作用連線好了。

POI輔助庫下載:POI輔助庫

好了,JavaWEB–POI之EXCEL操作、優化、封裝詳解系列(一)概述與原理講完了,這是自己設計的第一個Java工具庫,在這裡寫出來記錄,這是積累的必經一步,我會繼續出這個系列文章,分享經驗給大家。歡迎在下面指出錯誤,共同學習!!你的點贊是對我最好的支援!!