中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
SpringBoot + Ant Design Vue 實(shí)現(xiàn) excel 導(dǎo)入功能

實(shí)現(xiàn)導(dǎo)入功能主要還是使用 Ant Design Vue 中的 upload 樣式組件

upload 組件官網(wǎng):https://www.antdv.com/components/upload-cn/

前端實(shí)現(xiàn)

  1. <a-upload
  2. accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
  3. :customRequest="customRequest"
  4. @change="customChange"
  5. :disabled="uploadDisabled">
  6. <a-button type="primary" :icon="uploadIcon" :disabled="uploadDisabled">導(dǎo)入</a-button>
  7. </a-upload>

代碼解讀:這段代碼中 a-upload 標(biāo)簽表示是在頁(yè)面中引入了導(dǎo)入組件
accept 中這段代碼表示導(dǎo)入的文件只能是 excel 導(dǎo)入[.xlsx 或 .xls 都支持]
customRequest 表示自定義方法代替默認(rèn)方法去實(shí)現(xiàn)文件導(dǎo)入/上傳操作
@change 事件是在文件上傳中、完成、失敗都會(huì)調(diào)用這個(gè)函數(shù)
disabled 是否禁用上傳組件
a-button 創(chuàng)建一個(gè)操作按鈕,type 為 primary 表示這是一個(gè)主要按鈕,icon 表示為按鈕設(shè)置一個(gè)圖標(biāo)
disabled是否禁用此按鈕

屬性定義

將上面自定義的屬性在data中定義好
to-top 的樣式為這個(gè):這個(gè)樣式也是用的 Ant Design Vue 中的 icon圖標(biāo)庫(kù)

  1. export default {
  2. data() {
  3. return {
  4. // 導(dǎo)入excel時(shí)的icon圖標(biāo)
  5. uploadIcon: 'to-top',
  6. // 導(dǎo)入excel時(shí)是否禁用上傳按鈕
  7. uploadDisabled: false
  8. }
  9. }
  10. }

方法實(shí)現(xiàn)

自定義實(shí)現(xiàn)方法,參數(shù) data 就是上傳文件的信息
data.file 是上傳至后臺(tái)的 excel 文件
上傳文件必須要通過(guò)創(chuàng)建 FormData 對(duì)象進(jìn)行傳參
batchImportGetRecord 是我的項(xiàng)目中自定義上傳文件的方法,是利用 axios 請(qǐng)求封裝好的方法,也可以使用 ajax ,實(shí)際代碼編寫(xiě)需要按照自己項(xiàng)目中封裝好的網(wǎng)絡(luò)請(qǐng)求來(lái)進(jìn)行編寫(xiě)
finally 塊表示請(qǐng)求成功或是失敗都會(huì)執(zhí)行的操作

  1. /**
  2. * 自定義導(dǎo)入文件方法
  3. * @param data 上傳的 excel 文件
  4. */
  5. customRequest(data) {
  6. const file = data.file; // 需要上傳的 excel 文件
  7. const formData = new FormData();
  8. formData.append('file', file);
  9. data.onProgress();
  10. batchImportGetRecord(formData).then(res => {
  11. if (res) {
  12. this.$message.success('導(dǎo)入成功');
  13. } else {
  14. this.$message.error('導(dǎo)入失敗');
  15. }
  16. }).finally(() => {
  17. this.switchIconAndStatus(false);
  18. });
  19. }

上傳中、完成、失敗都會(huì)調(diào)用這個(gè)函數(shù)
data.file.status 是文件上傳的一些狀態(tài)

文件上傳狀態(tài) 描述
uploading 上傳中
done 上傳成功
error 上傳失敗
removed 取消上傳
  1. /**
  2. * 導(dǎo)入功能的 change 事件
  3. * @param data 上傳文件過(guò)程中的文件狀態(tài)信息
  4. */
  5. customChange(data) {
  6. if (data.file.status === 'uploading') {
  7. this.switchIconAndStatus(true);
  8. } else if (data.file.status === 'done') {
  9. this.switchIconAndStatus(false);
  10. } else if (data.file.status === 'error') {
  11. this.switchIconAndStatus(false);
  12. }
  13. }

按照程序設(shè)計(jì),重復(fù)代碼過(guò)多就需要進(jìn)行封裝,方便使用
通過(guò)上傳成功/失敗的情況更改上傳按鈕的圖標(biāo)和按鈕禁用的樣式
uploadIcon = loading 表示切換按鈕的圖標(biāo)為如下圖:


這樣做的好處就是在導(dǎo)入大數(shù)據(jù)量的 excel 時(shí),后臺(tái)處理較慢,添加了此圖標(biāo)及對(duì)應(yīng)的按鈕禁用可以防止用戶不停的點(diǎn)擊,給使用者制造一個(gè)正在處理數(shù)據(jù)的過(guò)程中,讓使用者稍等片刻...

  1. /**
  2. * 導(dǎo)入按鈕的圖片和狀態(tài)切換
  3. * @param flag 根據(jù)此標(biāo)識(shí)來(lái)區(qū)分正在導(dǎo)入還是導(dǎo)入成功或未導(dǎo)入的圖標(biāo)及禁用情況
  4. */
  5. switchIconAndStatus(flag) {
  6. if (flag) {
  7. this.uploadIcon = 'loading';
  8. this.uploadDisabled = true;
  9. } else {
  10. this.uploadIcon = 'to-top';
  11. this.uploadDisabled = false;
  12. }
  13. }

后端實(shí)現(xiàn)

控制層 Controller 實(shí)現(xiàn)

后臺(tái)接口,圖片上傳請(qǐng)求默認(rèn)為 post 請(qǐng)求,通過(guò) MultipartFile 類型接收上傳的文件,注意這里的 括號(hào)中的參數(shù)要和前端上傳的參數(shù)名稱一致,不一致后臺(tái)就接收不到這個(gè)參數(shù)

  1. @PostMapping(value = "import")
  2. public Boolean importExcelData(@RequestParam("file") MultipartFile file) {
  3. return studentService.importExcelData(file);
  4. }

服務(wù)層 Service 實(shí)現(xiàn)

這里舉例導(dǎo)入一個(gè)學(xué)生信息表 excel 文件

  1. @Override
  2. @Transactional(rollbackFor = Exception.class)
  3. public boolean importExcelData(MultipartFile file) {
  4. List<Student> list = new ArrayList<Student>();
  5. Student student = null;
  6. try {
  7. // 通過(guò)文件輸入流讀取到對(duì)應(yīng)的 workbook 工作簿
  8. XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());
  9. // 只解析第一張 sheet 工作表
  10. XSSFSheet sheet = workbook.getSheetAt(0);
  11. // 遍歷第一個(gè)工作表的所有行
  12. for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
  13. if (i == 0) continue; // 跳過(guò)標(biāo)題行
  14. XSSFRow row = sheet.getRow(i); // 獲取工作表中的某一行,通過(guò)下標(biāo)獲取
  15. if (row == null) continue; // 跳過(guò)空行
  16. // 構(gòu)造要批量插入的Student對(duì)象
  17. student = new Student();
  18. // 遍歷一個(gè)行中的所有列
  19. for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) {
  20. XSSFCell cell = row.getCell(j); // 獲取一行中的某個(gè)單元格,通過(guò)下標(biāo)獲取
  21. if (cell == null) continue; // 跳過(guò)空單元格
  22. // 獲取單元格中的字符串內(nèi)容
  23. String cellValue = cell.getStringCellValue();
  24. // 獲取單元格中的數(shù)字內(nèi)容
  25. double cellValue2 = cell.getNumericCellValue();
  26. // 判斷單元格是第幾個(gè),從零開(kāi)始
  27. switch (j) {
  28. case 0: // 第一列就是姓名
  29. student.setName(cellValue); // 給實(shí)體類的setter屬性賦值
  30. break;
  31. case 1: // 年齡
  32. student.setAge(cellValue2);
  33. break;
  34. case 2: // 愛(ài)好
  35. student.setHobby(cellValue);
  36. break;
  37. case 3: // 家庭地址
  38. student.setAddress(cellValue);
  39. break;
  40. case 4: // 出生日期
  41. // 如果沒(méi)有特意去定義 excel 中的日期,那么獲取到的日期就是字符串類型
  42. // 這里將字符串日期轉(zhuǎn)換為日期格式 LocalDateTime 或 Date
  43. // 1. 將日期轉(zhuǎn)換為 LocalDateTime
  44. // LocalDateTime time = LocalDateTime.parse(cellValue, DateTimeFormatter.ofPattern("yyyy年M月d日HH:mm:ss"));
  45. // 2. 將日期轉(zhuǎn)換為 Date
  46. SimpleDateFormat sdf = new SimpleDateFormat("yyyy年M月d日HH:mm:ss");
  47. Date date = sdf.parse(cellValue);
  48. student.setBirthday(date);
  49. break;
  50. }
  51. }
  52. list.add(student);
  53. }
  54. // 做一下批量添加學(xué)生信息的操作即可,這里使用 MyBatis-Plus 提供的方法進(jìn)行批量新增
  55. studentService.saveBatch(list);
  56. return true;
  57. } catch (Exception e) {
  58. e.printStackTrace();
  59. System.err.println("導(dǎo)入失敗");
  60. TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); // 手動(dòng)回滾代碼
  61. return false;
  62. }
  63. }

代碼解讀:

  • 通過(guò) file.getInputStream() 構(gòu)建一個(gè) workbook
  • work.getSheetAt(index) 通過(guò)此方法獲取工作表,通過(guò)索引來(lái)獲取,索引從零開(kāi)始
  • sheet.getPhysicalNumberOfRows() 方法可以獲取 sheet 工作表中的所有行的數(shù)量
  • sheet.getRow(index) 通過(guò)下標(biāo)獲取對(duì)應(yīng)的行,下標(biāo)都是從零開(kāi)始
  • row.getPhysicalNumberOfCells() 方法可以獲取到一行中所有單元格的數(shù)量
  • row.getCell(index) 通過(guò)下標(biāo)獲取對(duì)應(yīng)的單元格,下標(biāo)都是從零開(kāi)始
  • cell.getStringCellValue() 此方法用于獲取單元格中為字符串類型的內(nèi)容值,相關(guān)的方法有多種,可以獲取 Boolean,日期類型,數(shù)字類型等….

  • 最后經(jīng)過(guò)讀取所有內(nèi)容后將單元格內(nèi)容一行行的讀取設(shè)置到 實(shí)體類中,并將實(shí)體類經(jīng)過(guò)每次循環(huán)都添加到 list 集合中,最后通過(guò)批量插入表的操作給插入到數(shù)據(jù)庫(kù)中,比起來(lái)一條條的插入,批量插入明顯效率更高,因?yàn)楹笈_(tái)請(qǐng)求數(shù)據(jù)庫(kù)也是在消耗網(wǎng)絡(luò)資源,中間一去一回也是浪費(fèi)時(shí)間,而批量插入明顯網(wǎng)絡(luò)資源消耗的更少。

  • TransactionAspectSupport.currentTransactionStatus().setRollbackOnly() 添加事務(wù)后,當(dāng)導(dǎo)入失敗時(shí),可以進(jìn)行代碼回滾操作`

打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服