java匯出Excel檔案

deeply發表於2021-09-09

一、背景

  最近在java上做了一個EXCEL的匯出功能,寫了一個通用類,在這裡分享分享,該類支援多sheet,且無需手動進行復雜的型別轉換,只需提供三個引數即可:

  • fileName

    excel檔名

  • HasMap> data

    具體的資料,每個List代表一張表的資料,?表示可為任意的自定義物件

  • LinkedHashMap headers

    Stirng代表sheet名。每個String[][]代表一個sheet的定義,舉個例子如下:

    String[][] header = {
        {"field1","引數1"}
        ,{"field2","引數2"}
        ,{"field3","引數3"}
    }

    其中的field1,field2,field3為物件中的屬性名,引數1,引數2,引數3為列名,實際上這個指定了列的名稱和這個列用到資料物件的哪個屬性。

二、怎麼用

  以一個例子來說明怎麼用,假設有兩個類A和B定義如下:

public class A{    private String name;    private String address;
}public class B{    private int id;    private double sum;    private String cat;
}

現在我們透過查詢資料庫獲得了A和B的兩個列表:

List

我們將這兩個匯出到excel中,首先需要定義sheet:

String[][] sheetA = {
    {"name","姓名"}
    ,{"address","住址"}
}
String[][] sheetB = {
    {"id","ID"}
    ,{"sum","餘額"}
    ,{"cat","貓的名字"}
}

然後將資料彙總構造一個ExcelUtil:

String fileName = "測試Excel";
HashMap> data = new HashMap();//ASheet為表名,後面headers裡的key要跟這裡一致data.put("ASheet",dataA);
data.put("BSheet",dataB);
LinkedHashMap headers = new LinkedHashMap();
headers.put("ASheet",sheetA);
headers.put("BSheet",sheetB);
ExcelUtil excelUtil = new ExcelUtil(fileName,data,headers);//獲取表格物件HSSFWorkbook workbook = excelUtil.createExcel();//這裡內建了一個寫到response的方法(判斷瀏覽器型別設定合適的引數),如果想寫到檔案也是類似的workbook.writeToResponse(workbook,request,response);

當然通常資料是透過資料庫查詢的,這裡為了演示方便沒有從資料庫查詢。

三、實現原理

  這裡簡單說明下實現過程,從呼叫createExcel()這裡開始

1、遍歷headers建立sheet

    public HSSFWorkbook createExcel() throws Exception {        try {
            HSSFWorkbook workbook = new HSSFWorkbook();            //遍歷headers建立表格
            for (String key : headers.keySet()) {                this.createSheet(workbook, key, headers.get(key), this.data.get(key));
            }            return workbook;
        } catch (Exception e) {
            log.error("建立表格失敗:{}", e.getMessage());            throw e;
        }
    }

將workbook,sheet名,表頭資料,行資料傳入crateSheet方法中建立sheet。

2、建立表頭

  表頭也就是一個表格的第一行,通常用來對列進行說明

        HSSFSheet sheet = workbook.createSheet(sheetName);        // 列數
        int cellNum = header.length;        // 單元行,單元格
        HSSFRow row;
        HSSFCell cell;        // 表頭單元格樣式
        HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);        // 設定表頭
        row = sheet.createRow(0);        for (int i = 0; i 

3、插入行資料

  這裡是最重要的部分,首先透過資料的類物件獲取它的反射屬性Field類,然後將屬性名和Field做一個hash對映,避免迴圈查詢,提高插入速度,接著透過一個switch語句,根據屬性類別設值,主要程式碼如下:

/**
 * 設定單元格,根據fieldName獲取對應的Field類,使用反射得到值
 *
 * @param cell 單元格例項
 * @param obj 存有屬性的物件例項
 * @param fieldMap  屬性名與Field的對映
 * @param fieldName 屬性名
 */private void setCell(HSSFCell cell, Object obj, Map fieldMap, String fieldName) throws Exception {    //獲取該屬性的Field物件
    Field field = fieldMap.get(fieldName);    //透過反射獲取屬性的值,由於不能確定該值的型別,用下面的判斷語句進行合適的轉型
    Object value = field.get(obj);    if (value == null) {
        cell.setCellValue("");
    } else {        switch (field.getGenericType().getTypeName()) {        case "java.lang.String":
            cell.setCellValue((String) value);            break;        case "java.lang.Integer":        case "int":
            cell.setCellValue((int) value);            break;        case "java.lang.Double":        case "double":
            cell.setCellValue((double) value);            break;        case "java.util.Date":
            cell.setCellValue(this.dateFormat.format((Date) value));            break;        default:
            cell.setCellValue(obj.toString());
        }
    }
}

完整程式碼可以到github上檢視下載,這裡就不列出來了。

github地址:

原文出處:https://www.cnblogs.com/wuyoucao/p/9526620.html

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/1978/viewspace-2812461/,如需轉載,請註明出處,否則將追究法律責任。

相關文章