1 介紹
excel匯入工具
整個專案的程式碼結構如下
\---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匯入可以分為幾步
- 上傳excel檔案
- 將excel轉換為資料,有需要的資料進行轉換
2 使用
2.1 ExcelImport工具類
首先例項化ExcelImport工具類,我這裡提供了一個建構函式
public ExcelImport(Class<T> clazz, List<CellParam> cellParams)
複製程式碼
引數 | 含義 |
---|---|
clazz | Class物件(需要轉換為Bean的Class物件) |
cellParams | CellParam的list列表(每一列對應的欄位及資料轉換類) |
例項化ExcelImport工具類之後,需要呼叫importExcel方法,方法定義如下
public List<T> importExcel(InputStream is)
複製程式碼
只需要傳入InputStream即可。
2.2 匯入列引數類CellParam
CellParam類程式碼如下
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);
}
複製程式碼
我這裡預設提供了兩種資料轉換,一個是鍵值對,另一個是日期
2.3.1 鍵值對資料轉換
鍵值對資料轉換類是為了將一些通用資料轉換而提供的。
例如:男女、是否和一些不同名稱對應的不同數字(正常-->0,異常-->1,其他-->2)
使用者可以通過傳入的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…,有需要的可以看看