excel導入工具

1 介紹

excel導入工具java

整個項目的代碼結構以下git

\---excelExport # 導出工具包
        |   AsyncExportExcel.java #多線程導出
        |   ExcelImport.java # 導出工具類
        |
        +---data
        |       BaseParam.java # 基礎導出參數類
        |
        +---dataConversion
        |       DataExportConversion.java # 屬性導出轉換接口
        |
        +---defaultDataHandle # 默認的數據處理
        |       AbstractDataHandler.java
        |       BooleanDataHandler.java
        |       DataHandlerFactory.java
        |       DateDataHandler.java
        |       StringDataHandler.java
        |
        \---style # 默認的樣式
                AbstractCellStyle.java
                DefaultDataCellStyle.java
                DefaultTitleCellStyle.java

com
\---utils
    +---demo # 案例相關
    |   |   ExcelImportApplication.java # springboot啓動類
    |   |
    |   +---bean
    |   |       DemoBean.java # 測試bean
    |   |
    |   +---controller
    |   |       ExcelImportController.java # 測試從web導入excel和從文件導入excel
    |   |
    |   \---importParam
    |       |   DemoImportParam.java # 導入參數
    |       |
    |       \---dataConversion
    |               HobbyConversion.java # 愛好屬性導入轉換類
    |
    \---excelImport # 導入工具包
        |   ExcelImport.java # 導入工具類
        |
        +---data
        |       CellParam.java # 導入列參數類
        |
        \---dataConversion
            |   DataImportConversion.java # 屬性導入轉換接口
            |
            \---impl
                    DateConversion.java # 日期屬性導入轉換接口
                    MapConversion.java  # 鍵值對屬性導入轉換接口 
複製代碼

簡單的來講excel導入能夠分爲幾步github

  1. 上傳excel文件
  2. 將excel轉換爲數據,有須要的數據進行轉換

2 使用

2.1 ExcelImport工具類

首先實例化ExcelImport工具類,我這裏提供了一個構造函數web

public ExcelImport(Class<T> clazz, List<CellParam> cellParams) 複製代碼
參數 含義
clazz Class對象(須要轉換爲Bean的Class對象)
cellParams CellParam的list列表(每一列對應的字段及數據轉換類)

實例化ExcelImport工具類以後,須要調用importExcel方法,方法定義以下spring

public List<T> importExcel(InputStream is)
複製代碼

只須要傳入InputStream便可。springboot

2.2 導入列參數類CellParam

CellParam類代碼以下bash

public class CellParam {
	private String fieldName;
    private DataImportConversion conversion;
	
	//Set Get Constructor
}
複製代碼

2.2.1 屬性

能夠看到CellParam類有兩個屬性多線程

private String fieldName;
private DataImportConversion conversion;
複製代碼
參數 含義
fieldName 列對應Bean的屬性
conversion 數據轉換類

2.3 數據轉換接口DataImportConversion

public interface DataImportConversion<T> {
    T transferData(Object data);
}
複製代碼

我這裏默認提供了兩種數據轉換,一個是鍵值對,另外一個是日期app

2.3.1 鍵值對數據轉換

鍵值對數據轉換類是爲了將一些通用數據轉換而提供的。
例如:男女、是否和一些不一樣名稱對應的不一樣數字(正常-->0,異常-->1,其餘-->2)ide

使用者能夠經過傳入的map的泛型決定返回值的類型。

public class MapConversion<K,V> implements DataImportConversion<V> {

    private Map<K,V> map ;

    private V defaultReturnValue;

    public MapConversion(Map<K, V> map) {
        this(map,null);
    }

    public MapConversion(Map<K, V> map,V defaultReturnValue) {
        this.map = map;
        this.defaultReturnValue = defaultReturnValue;
    }

    @Override
    public V transferData(Object data) {
        if (map == null) return null;

        //若是data爲null且map的null對應的值不爲null,則直接返回map中null對應的值
        if (data == null && map.get(null) != null){
            return map.get(null);
        }

        //循環查找對應的key
        for (Map.Entry<K,V> entry:map.entrySet()){
            if (entry.getKey() != null && entry.getKey().equals(data)){
                return entry.getValue();
            }
        }
        //若是map裏面找不到對應的數據,則返回defaultReturnValue
        return defaultReturnValue;
    }
}
複製代碼

2.3.2 日期數據轉換

提供日期轉換功能,經過傳入的日期轉換格式進行轉換。

public class DateConversion implements DataImportConversion<Date> {
    private SimpleDateFormat format;

    public DateConversion(String pattern) {
        this.format = new SimpleDateFormat(pattern);
    }

    @Override
    public Date transferData(Object data) {
        try {
            return format.parse(data.toString());
        } catch (Exception e){
            e.printStackTrace();
        }

        return null;
    }
}
複製代碼

3 案例

3.1 場景

原始數據以下

姓名 性別 出生日期 愛好
塵心 2018-08-08 14:59:11 舞刀,弄槍
千月 2018-08-08 14:59:11 唱歌,跳舞

須要轉換爲實體bean的列表,以下

DemoBean{name='塵心', sex=0, birthday=Wed Aug 08 14:13:45 CST 2018, hobbies=[舞刀, 弄槍]}
DemoBean{name='千月', sex=1, birthday=Wed Aug 08 14:13:45 CST 2018, hobbies=[唱歌, 跳舞]}
複製代碼

實體類以下

public class DemoBean {

    //姓名
    private String name;

    //性別,0->女,1->男
    private Integer sex;

    //出生日期
    private Date birthday;

    //愛好
    private List<String> hobbies;

    //Set Get
    
}
複製代碼

3.2 數據轉換

能夠看到有三個屬性須要轉換,分別是性別、日期和愛好。性別和日期的數據轉換能夠使用默認的數據轉換。愛好須要將字符串根據分割並轉換爲list列表數據,下面是愛好的數據轉換,

public class HobbyConversion implements DataImportConversion<List<String>> {
    @Override
    public List<String> transferData(Object data) {
        if (data == null) return null;

        //根據,分割字符串
        String hobbyStr = data.toString();
        String[] hobbyArray = hobbyStr.split(",");

        //轉換成list
        List<String> hobbies = Arrays.asList(hobbyArray);
        return hobbies;
    }
}
複製代碼

3.3 導入參數類

數據轉換類寫好了以後,開始編寫導入參數類,代碼以下

public class DemoImportParam {
    public static List<CellParam> getCellParams(){
        Map<String,Integer> sexMap = new HashMap<>();
        sexMap.put("女",0);
        sexMap.put("男",1);

        List<CellParam> cellParams = new ArrayList<>();
        cellParams.add(new CellParam("name"));
        cellParams.add(new CellParam("sex", new MapConversion(sexMap)));
        cellParams.add(new CellParam("birthday", new DateConversion("yyyy-MM-dd HH:mm:ss")));
        cellParams.add(new CellParam("hobbies", new HobbyConversion()));
        return cellParams;
    }
}
複製代碼

在DemoImportParam類中能夠看到一個靜態方法getCellParams,返回List。方法內部先定義了一個mao對象,存放性別字符串對應的數字,而後就是List的定義。
能夠看到總共有4個列參數

  • 第一列標題名稱爲姓名,對應的屬性名稱爲name
  • 第二列標題名稱爲性別,對應的屬性名稱爲sex,數據轉換對象MapConversion
  • 第三列標題名稱爲出生日期,對應的屬性名稱爲birthday,日期轉換
  • 第四列標題名稱爲愛好,對應的屬性名稱爲hobbies,數據轉換對象HobbyConversion

3.4 導出

接下來有兩種數據導出方式,一種是url訪問彈出下載excel文件,另一種是導出excel到文件

3.4.1 從web導入excel

@ResponseBody
@PostMapping("/import")
public List<DemoBean> importByWeb(MultipartFile file) throws Exception {
    ExcelImport excelImport = new ExcelImport(DemoBean.class, DemoImportParam.getCellParams());
    List<DemoBean> list = excelImport.importExcel(file.getInputStream());

    return list;
}
複製代碼

3.4.2 從文件導入excel

@Test
public void importByFile() throws Exception {
    File file = new File("F:\\導出demo.xlsx");
    FileInputStream inputStream = new FileInputStream(file);

    //導入轉換
    ExcelImport excelImport = new ExcelImport(DemoBean.class, DemoImportParam.getCellParams());
    List<DemoBean> list = excelImport.importExcel(inputStream);

    //輸出
    for (DemoBean bean:list){
        System.out.println(bean);
    }
}
複製代碼

項目位置:github.com/rainbowda/u…,有須要的能夠看看

相關文章
相關標籤/搜索