以ORM的思路來從Excel文件中讀取JSON數據列表

1.一個常見的問題就是如何讀取excel。

這裏面有幾個分支的問題,一個是如何使用poi讀取excel,網上例子不少,可是這隻解決了第一步。如何將excel讀取入必定的數據結構這是第二個問題,還有就是讀取到數據了之後如何存放,如何將其轉換成咱們但願的對象?這些問題一個比一個在應用的更高層級上,也就是說,若是excel是數據源,如何將數據源讀取到的數據轉換成咱們喜好的實體類,也就是ORM的思想,只是在讀取excel這個事情上,咱們的數據源是個文件,須要必定的驅動去讀取,僅此而已。java

2..破解問題

咱們須要poi包的支持,這是世界java圈裏公認的組件,不用再次發明輪子。咱們須要用到json包,用alibaba出品的fastjson包,這個也很是好用。感謝zj的推薦。思考的過程是這樣的,在咱們現有的知識裏面,已經有這樣幾個概念了,excel經過poi能夠讀取它的值,json包能夠把string直接轉換成pojo,那麼咱們將他們創建聯繫,從excel中讀取行到json,再把json變成實體類,就能夠達到咱們預想的效果了。那麼還有一個問題須要解決,就是如何指定類的屬性與excel對應列的關係。仔細想了一陣子,還沒想到好的解決辦法,若是沒有辦法自動,那就能夠用指定的方法,外部指定其實已經解耦了,只是沒那麼完美而已。git

3.解決問題

第一步,咱們創建pojo類屬性與excel的對照關係,咱們仍是利用json做爲中間傳遞的載體。
/**
 * 建立用於翻譯中文列名到英文變量名的對照字典。
 * @param keys  中文或默認的excel列名稱
 * @param values 變量名
 * @return
 * @throws Exception
 */
public JSONObject genImportKyes(String[] keys,String[] values) throws Exception {
    try {
        JSONObject result = new JSONObject();
        for (int i = 0; i < keys.length; i++) {
            result.put(keys[i], values[i]);
        }
        return result;
    }catch (Exception e){
        e.printStackTrace();
        throw e;
    }
}
調用的時候好比excel有字段"序號", "數量", "日期", "小計", "備註",而咱們的pojo對象的屬性是"id","count","date","sum","memo",咱們這樣調用
JSONObject keys = eo.genImportKyes(new String[]{"序號", "數量", "日期", "小計", "備註"},new String[]{"id","count","date","sum","memo"} );
這樣這個keys裏面咱們就創建了excel中的列名和咱們實體類屬性的對應關係了。
第二步,從excel的指定行去讀取一行,來創建屬性名和excel列的位置的對應關係。也就是咱們須要知道咱們的序號兌換成的id這個數據是放在excel的第幾列裏面的。
public JSONObject createRowIndex(Row row, JSONObject keys) {
    int col_count = row.getLastCellNum();
    JSONObject jsonObject = new JSONObject();
    for (int i = 0; i < col_count; i++) {
        String cv = row.getCell(i).getStringCellValue();
        if (keys == null) {
            jsonObject.put(cv, i);
        } else {
            String key = keys.getString(cv);
            jsonObject.put(key, i);
        }
    }
    return jsonObject;
}
經過讀取excel的一個row放進這個函數,再加上咱們第一步準備好的keys,咱們就能夠比較容易的作出對應關係來。由於第一步咱們解決了excel列明與實體類屬性的對照關係,在第二步咱們解決了屬性與excel的列的對應位置關係,接下來咱們就能夠去讀取格子了,由於咱們須要的信息都準備好了。也就是咱們已經創建好了讀取的規則。
第三步:讀取excel的其餘全部行,並按照第一步創建的關係建立出json對象來。這中間有一個須要注意的地方是咱們隊與excel中的特殊類型須要額外的關照一下,好比日期類型、數字類型等等。具體能夠看源碼public String parseCell(Cell cell) 這個函數的實現。咱們經過每一行的讀取來得到一個json的對象,接下來咱們在使用json包轉javaobject的能力把它變成對應的實體類。接近成功了。

4.最後咱們來看看,假設咱們有一個excel文件是這樣的


咱們但願讀取出來之後的實體類是這樣的。

是時候展現真正的實力啦。json

@Test
public void test1() throws Exception {
    excelOpterator eo = new excelOpterator().setHeadRowIndex(0);
    JSONObject keys = eo.genImportKyes(new String[]{"序號", "數量", "日期", "小計", "備註"},new String[]{"id","count","date","sum","memo"} );
    JSONArray rows = eo.readXls("C:/excel.xls", keys);
    for(Object jo :rows){
        testEntity to = JSON.toJavaObject((JSONObject)jo,testEntity.class );
        System.out.println(to);
    }
}

看到輸出的時候老是很開心,可是回頭看本身思考的過程,也會比較有意思,但願你們都能享受到這個輕鬆的結果。bingo
數據結構

文末有福利函數

https://gitee.com/youliaoo/lutraExcelHelper翻譯

相關文章
相關標籤/搜索