1. 程式人生 > >excel匯入,用反射匹配欄位名

excel匯入,用反射匹配欄位名

最近在開發的系統,涉及到很多xls匯入, 開發太忙,沒時間做比較通用的模組,我反正閒著, 就試著幫他們寫了個比較通用的xls匯入模組,自我感覺良好, 就寫個文章記錄下

(demo程式碼,輕噴)

首先縮小需求:

1. 按行匯入,不支援合併行,和並列,合併的單元格處理太累

2. 第一行是表頭, 匯入xls需要通過表頭的字串來匹配列

這樣相對就簡單了, 首先是建立表頭和列索引的關係, 通過類反射建立索引關係

類反射定義

```java

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface 
FieldDescInject { String value() default ""; }

類反射的使用

public class Order extends XlsObject {
    @FieldDescInject("訂單號")
    String thirdOrderId;
    @FieldDescInject("收件人")
    String receiveName;
    @FieldDescInject("省")
    String province;
    @FieldDescInject("市")
    String city;
    @FieldDescInject
("區") String zone; @FieldDescInject("地址") String detailAddress; @FieldDescInject("電話") String mobile;
}

把類成員變數和xls對應列關聯起來

XlsObject定義

package com.digitcore.readxls;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
* Created by pan on 2016/12/1. */ public abstract class XlsObject { //for example // @FieldDescInject("價格") // public int price; public void setFieldValue(String desc, String value){ String fieldStr = fieldDescMap.get(desc); if(fieldStr == null){ setFieldValueNotFound(desc, value); return; } try { Field field = this.getClass().getDeclaredField(fieldStr); field.setAccessible(true); Class clzz = field.getType(); if(clzz == String.class){ field.set(this, value); } else if(clzz == int.class || clzz == Integer.class){ field.setInt(this, Integer.parseInt(value)); } else if(clzz == float.class || clzz == Float.class){ field.setFloat(this, Float.parseFloat(value)); } else { throw new IllegalArgumentException("聯絡程式設計師補充型別支援!"); } } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public void setFieldValueNotFound(String field, String value){ } public XlsObject() { inject(); } private HashMap<String, String> fieldDescMap = new HashMap<String, String>(); public List<String> getDescList(){ return new ArrayList<String>(fieldDescMap.keySet()); } public void inject(){ Field[] fields = this.getClass().getDeclaredFields(); if (fields != null && fields.length > 0) { for (Field field : fields) { // Class<?> fieldType = field.getType(); FieldDescInject ed = field.getAnnotation(FieldDescInject.class); if (ed != null) { // field.setAccessible(true); fieldDescMap.put(ed.value(), field.getName()); } } } } }

再增加一個匯入的輔助工具類

package com.digitcore.readxls;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jxl.Range;
import jxl.Sheet;
import jxl.Workbook;

import static android.R.attr.order;

/**
 * Created by pan on 2016/11/29.
 * 匯入xls表, 通過變數描述對應表字段, 或者手動選擇(外部介面配合)列和物件變數對應
 */
public class ImportXls {
    private String mFile;
    private int mStartRow = 0;//head開始行, 預設從0開始
private Class<? extends XlsObject> mClazz;
    private HashMap<String, Integer> mIndexMap;

    public ImportXls(String file, int startRow, Class<? extends XlsObject> clazz){
        mFile = file;
        mStartRow = startRow;
        mClazz = clazz;
    }

    /**
     * 獲取xls表頭的head列表
     * @return
*/
public List<String> getXlsHead(){
        List<String> heads = new ArrayList<String>();

        InputStream is = null;
        Workbook book = null;
        try {
            is = new FileInputStream(mFile);
            book = Workbook.getWorkbook(is);

//            int num = book.getNumberOfSheets();
//            txt.setText("the num of sheets is " + num+ "\n");
//            // 獲得第一個工作表物件
Sheet sheet = book.getSheet(0);
            int Rows = sheet.getRows();
            int Cols = sheet.getColumns();
            if(Rows >= mStartRow && Cols > 0){
                for(int i = 0; i < Cols; i++){
                    heads.add(sheet.getCell(i, mStartRow).getContents());
                }
            }
        } catch (Exception e) {
            System.out.println(e);
        }
        finally {
            if(book != null){
                book.close();
            }
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return heads;
    }

    public void setIndexMap(HashMap<String, Integer> indexMap){
        mIndexMap = indexMap;
    }

    /**
     * 自動生成xls檔案中欄位索引表, xlsObject物件中註解的描述要和xls頭對應
     * @param importHead xlsObject中註解的描述
     */
public void generateIndexMap(List<String> importHead){
        List<String> xlsHead = getXlsHead();
        mIndexMap = new HashMap<String, Integer>();

        for(String head : importHead){
            int index = xlsHead.lastIndexOf(head);
            if(index >= 0) {
                mIndexMap.put(head, Integer.valueOf(index));
            }

        }
    }
    public List<XlsObject> importXls(){
        ArrayList<XlsObject> list = new ArrayList<XlsObject>();

        InputStream is = null;
        Workbook book = null;
        try {
            is = new FileInputStream(mFile);
            book = Workbook.getWorkbook(is);

            Sheet sheet = book.getSheet(0);
            int Rows = sheet.getRows();
//            int Cols = sheet.getColumns();
for (int i = 1; i < Rows; ++i) {
                XlsObject o = mClazz.newInstance();

                Iterator iter = mIndexMap.entrySet().iterator();
                while (iter.hasNext()) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    String key = (String) entry.getKey();
                    Integer val = (Integer) entry.getValue();
                    o.setFieldValue(key, sheet.getCell(val, i).getContents());
                }

                list.add(o);

            }
        } catch (Exception e) {
            System.out.println(e);
        }
        finally {
            if(book != null){
                book.close();
            }
            if(is != null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return list;
    }


}

使用示例:

ImportXls importXls = new ImportXls("/buhebing.xls", 0, Order.class);
Order order = new Order();List<String> imprtHead = order.getDescList();
importXls.generateIndexMap(imprtHead);
importXls.importXls();

優化:

generateIndexMap這個函式後面可以優化, 實際上不需要傳參, 寫的時候沒注意, 後面懶得調整了