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
首先實例化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
CellParam類代碼以下bash
public class CellParam {
private String fieldName;
private DataImportConversion conversion;
//Set Get Constructor
}
複製代碼
能夠看到CellParam類有兩個屬性多線程
private String fieldName;
private DataImportConversion conversion;
複製代碼
參數 | 含義 |
---|---|
fieldName | 列對應Bean的屬性 |
conversion | 數據轉換類 |
public interface DataImportConversion<T> {
T transferData(Object data);
}
複製代碼
我這裏默認提供了兩種數據轉換,一個是鍵值對,另外一個是日期app
鍵值對數據轉換類是爲了將一些通用數據轉換而提供的。
例如:男女、是否和一些不一樣名稱對應的不一樣數字(正常-->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;
}
}
複製代碼
提供日期轉換功能,經過傳入的日期轉換格式進行轉換。
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;
}
}
複製代碼
原始數據以下
姓名 | 性別 | 出生日期 | 愛好 |
---|---|---|---|
塵心 | 女 | 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
}
複製代碼
能夠看到有三個屬性須要轉換,分別是性別、日期和愛好。性別和日期的數據轉換能夠使用默認的數據轉換。愛好須要將字符串根據,
分割並轉換爲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;
}
}
複製代碼
數據轉換類寫好了以後,開始編寫導入參數類,代碼以下
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個列參數
接下來有兩種數據導出方式,一種是url訪問彈出下載excel文件,另一種是導出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;
}
複製代碼
@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…,有須要的能夠看看