本案例為某后臺管理系統(tǒng)信息導(dǎo)入模塊,Excel格式是已知的(如知残,已知每列的數(shù)據(jù)類型辱志,首行是表頭)虐急。
- 前期準(zhǔn)備:導(dǎo)入poi-x.x.x.jar等jar包箱残,并添加到項(xiàng)目的lib中; 點(diǎn)此下載所需jar包
相關(guān)閱讀:IDEA如何添加庫lib(java)
1.后臺接口實(shí)現(xiàn)
主要工作:獲取前端上傳的文件流止吁,進(jìn)行解析被辑;
處理流程:
1. 獲取HSSFWorkbook對象,獲取workbook表單的個數(shù)敬惦,進(jìn)行遍歷盼理;
2. 對于每一個表單,先獲取行數(shù)俄删,進(jìn)行遍歷宏怔,第一行跳過;
3. 單元格的格式有多種畴椰,需在不同的switch分支中進(jìn)行處理臊诊;(代碼27-54行)
4. 最后講遍歷得到的員工數(shù)據(jù)集合返回。
public static Listexcel2Supplier(MultipartFile file) {
List list =new ArrayList<>();
Supplier supplier =null;
try {
//1. 創(chuàng)建一個 workbook 對象
HSSFWorkbook workbook =new HSSFWorkbook(file.getInputStream());
//2. 獲取 workbook 中表單的數(shù)量
int numberOfSheets = workbook.getNumberOfSheets();
for (int i =0; i < numberOfSheets; i++) {
//3. 獲取表單
HSSFSheet sheet = workbook.getSheetAt(i);
//4. 獲取表單中的行數(shù)
int physicalNumberOfRows = sheet.getPhysicalNumberOfRows();
for (int j =0; j < physicalNumberOfRows; j++) {
//5. 跳過標(biāo)題行
if (j ==0) {
continue;//跳過標(biāo)題行
}
//6. 獲取行
HSSFRow row = sheet.getRow(j);
if (row ==null) {
continue;//防止數(shù)據(jù)中間有空行
}
//7. 獲取列數(shù)
int physicalNumberOfCells = row.getPhysicalNumberOfCells();
supplier =new Supplier();
for (int k =0; k < physicalNumberOfCells; k++) {
HSSFCell cell = row.getCell(k);
//按照每一列的不同類型 獲取數(shù)據(jù)
switch (cell.getCellType()) {
//如果是String類型
case STRING:
String cellValue = cell.getStringCellValue();
switch (k) {//看它是第幾列的內(nèi)容
case 1:
supplier.setSupplier_code(cellValue);
break;
//省略其他的 case
}
break;
default: {
switch (k) {
//不同類型的獲取函數(shù)不同:
//日期類型:getDateCellValue()
//數(shù)字類型:getNumericCellValue()斜脂,返回double值
case 18:
supplier.setStatus((int) cell.getNumericCellValue());
break;
//省略其他的 case
}
}
break;
}
}
list.add(supplier);
}
}
} catch (IOException e) {
e.printStackTrace();
}
//返回搜集好數(shù)據(jù)的List
return list;
}
在數(shù)據(jù)導(dǎo)入接口中調(diào)用上述方法
- 代碼流程:獲取數(shù)據(jù)集合抓艳,插入數(shù)據(jù)庫,代碼如下:
//上傳Excel請求
@PostMapping("/ImportSup")
public void importSup(MultipartFile file){
//獲取數(shù)據(jù)集合
List<Supplier> suppliers = ExceLIO.excel2Supplier(file);
//插入數(shù)據(jù)庫
supplierService.addSuppliers(suppliers);
}
保存數(shù)據(jù)集合
- 上述代碼中調(diào)用的Service層函數(shù)addSuppliers() 帚戳,將數(shù)據(jù)集合插入數(shù)據(jù)庫玷或;
- 實(shí)現(xiàn)方法:循環(huán)單條逐一插入,調(diào)用插入一條數(shù)據(jù)的函數(shù)addSup() 片任;
//添加多條信息(Excel導(dǎo)入)
public void addSuppliers(List<Supplier> suppliers) {
Integer num = suppliers.size();
for(Integer i=0 ; i<num ; i++){
addSup(suppliers.get(i));
}
}
2.前端實(shí)現(xiàn)
- 直接采用 Element 的文件上傳控件偏友,代碼如下:
<!--上傳資料-->
<el-upload
:show-file-list="false"
accept="application/vnd.ms-excel"
:before-upload="beforeUpload"
:on-success="onSuccess"
:on-error="onError"
:disabled="importDataDisabled"
style="display: inline-flex;margin-right: 0"
:action="actionup">
<el-button :disabled="importDataDisabled" type="success" :icon="importDataBtnIcon">
導(dǎo)入
</el-button>
</el-upload>
其中,accept為接收文件類型对供;action為上傳接口位他;
data中定義 actionup : this.HOST + "/ImportSup" ,解決了跨域訪問的問題犁钟。
相關(guān)回調(diào)函數(shù)如下:
beforeUpload() {
this.importDataBtnText = '正在導(dǎo)入';
this.importDataBtnIcon = 'el-icon-loading';
this.importDataDisabled = true;
},
onError(err, file, fileList) {
this.importDataBtnText = '導(dǎo)入數(shù)據(jù)';
this.importDataBtnIcon = 'el-icon-upload2';
this.importDataDisabled = false;
},
onSuccess(response, file, fileList) {
this.importDataBtnText = '導(dǎo)入數(shù)據(jù)';
this.importDataBtnIcon = 'el-icon-upload2';
this.importDataDisabled = false;
this.initEmps();
}
以上完整的實(shí)現(xiàn)了“Springboot+Vue后臺管理系統(tǒng)”的Excel資料導(dǎo)入功能棱诱,這一過程中常遇到的BUG及解決方案請移步閱讀:
Springboot上傳文件報(bào)錯:java.lang.NullPointerException
如果有其他問題泼橘,歡迎留言討論~