淺析Vue3中Excel下載模板并導(dǎo)入數(shù)據(jù)功能的實(shí)現(xiàn)
上傳功能
代碼一
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body> <!-- action 使用 axios 上傳,#號 limit 只允許上傳一個(gè)文件 accept 限制格式 on-progress 上傳中回調(diào)方法,做上傳禁用的功能 disabled 禁用開關(guān) auto-upload 禁止自動(dòng)上傳 on-change 上傳后的處理 --> <el-upload action="#" :limit="1" accept=".xlsx, .xls" :on-progress="handleFileProgress" :disabled="upload.isUploading" :auto-upload="false" drag :on-change="handleChangeUpload"> <!--icon 標(biāo)簽--> <el-icon class="el-icon--upload"> <UploadFilled/> </el-icon> <div class="el-upload__text">將文件拖到此處,或<em>點(diǎn)擊上傳</em></div> <template #tip> <div class="el-upload__tip text-center"> <span>僅允許導(dǎo)入xls、xlsx格式文件。</span> <!--下載模版--> <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate"> 下載模板 </el-link> </div> </template> </el-upload> <template #footer> <div class="dialog-footer"> <!--確定后下載--> <el-button type="primary" @click="submitFileForm">確 定</el-button> <el-button @click="upload.open = false">取 消</el-button> </div> </template> </el-dialog>
代碼二
<el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body> <el-upload :action="upload.url" ref="uploadRef" :limit="1" accept=".xlsx, .xls" :on-progress="handleFileProgress" :disabled="upload.isUploading" :auto-upload="false" drag :headers="upload.headers" :on-success="handleFileSuccess"> <el-icon class="el-icon--upload"> <UploadFilled/> </el-icon> <div class="el-upload__text">將文件拖到此處,或<em>點(diǎn)擊上傳</em></div> <template #tip> <div class="el-upload__tip text-center"> <span>僅允許導(dǎo)入xlsx格式文件。</span> <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;" @click="importTemplate"> 下載模板 </el-link> </div> </template> </el-upload> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="submitFileForm">確 定</el-button> <el-button @click="upload.open = false">取 消</el-button> </div> </template> </el-dialog>
/*** 用戶導(dǎo)入?yún)?shù) */ const upload = ref({ open: false, title: '設(shè)備導(dǎo)入', // 是否禁用上傳 isUploading: false, headers: { Authorization: 'Bearer ' + getToken() }, url: import.meta.env.VITE_APP_BASE_API + '/ar_check/device/importData' }) // 打開導(dǎo)入 function handleTeamImport() { upload.value.open = true } // 文件上傳中 function handleFileProgress() { upload.value.isUploading = true } // 文件上傳完成 function handleFileSuccess(response, file) { upload.value.open = false upload.value.isUploading = false proxy.$refs['uploadRef'].handleRemove(file) proxy.$alert('<div style=\'overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;\'>' + response.msg + '</div>', '導(dǎo)入結(jié)果', { dangerouslyUseHTMLString: true }) getList() } // 下載模板 function importTemplate() { proxy.download('ar_check/device/importTemplate', {}, `device_template_${new Date().getTime()}.xlsx`) } // 確定上傳 async function submitFileForm() { proxy.$refs.uploadRef.submit() }
介紹一下 POI OOXML 的使用
首先需要?jiǎng)?chuàng)建一個(gè)工作薄,這里有幾個(gè)注意事項(xiàng)
- HSSF - 提供讀寫Microsoft Excel XLS格式檔案的功能。
- XSSF - 提供讀寫Microsoft Excel OOXML XLSX格式檔案的功能。
- HWPF - 提供讀寫Microsoft Word DOC97格式檔案的功能。
- XWPF - 提供讀寫Microsoft Word DOC2003格式檔案的功能。
- HSLF - 提供讀寫Microsoft PowerPoint格式檔案的功能。
- HDGF - 提供讀Microsoft Visio格式檔案的功能。
- HPBF - 提供讀Microsoft Publisher格式檔案的功能。
- HSMF - 提供讀Microsoft Outlook格式檔案的功能。
在工作頁創(chuàng)建行以及單元格。
// 新建一個(gè)工作簿 Workbook workbook = new XSSFWorkbook(); // 創(chuàng)建sheet頁 Sheet sheet = workbook.createSheet(); // 在第三行開始寫 Row row = sheet.createRow(3); Cell cell = row.createCell(0); cell.setCellValue("哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈哈"); // 合并行,表示表的第三列,結(jié)束第三列,合并 0 - 6 行 sheet.addMergedRegion(new CellRangeAddress(3, 3, 0, 8)); // 創(chuàng)建單元格樣式 CellStyle cellStyle = workbook.createCellStyle(); // 設(shè)置單元格居中方式---左對齊 cellStyle.setAlignment(HorizontalAlignment.LEFT); // 應(yīng)用單元格樣式 cell.setCellStyle(cellStyle); // 將數(shù)據(jù)寫入到文件中 FileOutputStream fout = new FileOutputStream("D:\\Downloads\\example.xlsx"); workbook.write(fout); fout.close(); workbook.close();
設(shè)置單元格格式以及字體樣式
// 創(chuàng)建單元格樣式 CellStyle cellStyle2 = workbook.createCellStyle(); // 設(shè)置單元格居中方式---居中 cellStyle2.setAlignment(HorizontalAlignment.CENTER); // 設(shè)置單元格顏色--灰色 cellStyle2.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex()); // 使用單一顏色填充 cellStyle2.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 字體格式 Font font = workbook.createFont(); // 加粗 font.setBold(true); // 設(shè)置顏色--白色 font.setColor(IndexedColors.WHITE.getIndex()); // 將字體設(shè)置到樣式上 cellStyle2.setFont(font); // 最后單元格使用樣式 t1.setCellStyle(cellStyle2);
最后輸出到指定位置
// 創(chuàng)建一個(gè)文件輸出流,用于將工作簿寫入文件 FileOutputStream fout = new FileOutputStream("D:\\Downloads\\example.xlsx"); // 將工作簿寫入文件流 workbook.write(fout); // 關(guān)閉文件流 fout.close(); // 關(guān)閉工作簿 workbook.close();
獲取 excel 的圖片
圖片是獨(dú)立的,根據(jù)單元格的位置獲取
InputStream inputStream = Files.newInputStream(Paths.get("D:\\Downloads\\device_template_1714287622392.xlsx")); XSSFWorkbook workbook = new XSSFWorkbook(inputStream); // 獲取第一個(gè) sheet 表 XSSFSheet sheet = workbook.getSheetAt(0); if (sheet == null) { throw new IOException("損壞的文件!"); } // 獲取繪圖包 XSSFDrawing drawing = sheet.getDrawingPatriarch(); if (drawing != null) { // 獲取所有圖形形狀 List<XSSFShape> shapes = drawing.getShapes(); for (XSSFShape shape : shapes) { // 形狀獲取對應(yīng)的圖片數(shù)據(jù) XSSFPicture picture = (XSSFPicture) shape; XSSFPictureData pictureData = picture.getPictureData(); //圖片形狀在工作表中的位置, 所在行列起點(diǎn)和終點(diǎn)位置 XSSFClientAnchor anchor = (XSSFClientAnchor) shape.getAnchor(); // 行 short col1 = anchor.getCol1(); // 列 int row1 = anchor.getRow1(); //文件擴(kuò)展名 String suffix = pictureData.suggestFileExtension(); // 文件格式 String mimeType = pictureData.getMimeType(); // 文件數(shù)據(jù) byte[] data = pictureData.getData(); // 轉(zhuǎn)換成 MultipartFile 進(jìn)行文件上傳,參數(shù)一和參數(shù)二是文件名,參數(shù)三是類型,參數(shù)四是字節(jié)數(shù)據(jù) MultipartFile multipartFile = new MockMultipartFile("", "", mimeType, data); } }
下載模板功能實(shí)現(xiàn)
首先后端完成上面的excel 文件格式內(nèi)容等
前端調(diào)用 SpringMvc 接口
import { saveAs } from 'file-saver' try { const downloadLoadingInstance = ElLoading.service({ text: '正在下載數(shù)據(jù),請稍候', background: 'rgba(0, 0, 0, 0.7)' }) // 發(fā)送 POST 請求到指定的 URL,獲取響應(yīng)數(shù)據(jù) const data = await service.post(url, {}, { // 設(shè)置請求頭為 'application/x-www-form-urlencoded' headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, // 設(shè)置響應(yīng)類型為 Blob responseType: 'blob' }) // 如果響應(yīng)數(shù)據(jù)存在 if (data) { // 檢查響應(yīng)數(shù)據(jù)是否為 Blob 類型---是否是JSON const isBlob = blobValidate(data) if (isBlob) { // 如果是 Blob 類型,則創(chuàng)建 Blob 對象并保存為文件 const blob = new Blob([data]) saveAs(blob, filename) } } // 關(guān)閉加載動(dòng)畫 downloadLoadingInstance.close() } catch (error) { console.error(error) // 顯示下載文件錯(cuò)誤信息 ElMessage.error('下載文件出現(xiàn)錯(cuò)誤,請聯(lián)系管理員!') // 關(guān)閉加載動(dòng)畫 downloadLoadingInstance.close() }
上傳導(dǎo)入
需要?jiǎng)?chuàng)建一個(gè)輸入流來讀取 execel 文件。
getLastRowNum 獲取有文本內(nèi)容的最后一行列的索引,因?yàn)槲疫@里前五行是解釋內(nèi)容,所以 == 5 表示沒有數(shù)據(jù)。
如果是前端傳遞的,要這樣寫 MultipartFile 的 getInputStream 方法獲取流
InputStream inputStream = Files.newInputStream(Paths.get("D:\\Downloads\\team_template_1714287622392.xlsx")); Workbook workbook = WorkbookFactory.create(inputStream); // 獲取第一個(gè) sheet 表 Sheet sheet = workbook.getSheetAt(0); if (sheet == null) { throw new IOException("損壞的文件!"); } if (sheet.getLastRowNum() == 5) { throw new IOException("導(dǎo)入班組數(shù)據(jù)不能為空!"); }
由于 poi ooxml 讀取數(shù)據(jù)需要指定類型很麻煩,我做了一個(gè)方法轉(zhuǎn)換
/** * 將單元格的值以字符串形式返回。 * * @param cell 單元格對象 * @return 字符串形式的單元格值,如果單元格為 null,則返回空字符串 */ public static String getCellValueAsString(Cell cell) { if (cell == null) { return ""; } switch (cell.getCellType()) { case NUMERIC: // 如果單元格類型為數(shù)字,將數(shù)字轉(zhuǎn)換為字符串并去除空格 return String.valueOf((long) cell.getNumericCellValue()).trim(); case BOOLEAN: // 如果單元格類型為布爾值,將布爾值轉(zhuǎn)換為字符串并去除空格 return String.valueOf(cell.getBooleanCellValue()).trim(); case STRING: // 如果單元格類型為字符串,直接返回字符串并去除空格 return cell.getStringCellValue().trim(); case FORMULA: // 如果單元格是公式,將計(jì)算結(jié)果作為字符串返回,并去除空格 return cell.getCellFormula().trim(); case BLANK: // 如果單元格為空,返回空字符串 return ""; case ERROR: // 如果單元格是錯(cuò)誤類型,返回錯(cuò)誤碼作為字符串 return String.valueOf(cell.getErrorCellValue()); default: // 其他類型的單元格返回空字符串 return ""; } }
以上就是淺析Vue3中Excel下載模板并導(dǎo)入數(shù)據(jù)功能的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Vue3 Excel下載模板并導(dǎo)入數(shù)據(jù)的資料請關(guān)注腳本之家其它相關(guān)文章!
- vue3導(dǎo)入excel并解析excel數(shù)據(jù)渲染到表格中(純前端實(shí)現(xiàn))
- vue3中利用Export2Excel將數(shù)據(jù)導(dǎo)出為excel表格
- Vue3實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)入Excel表格數(shù)據(jù)的方法詳解
- 在Vue中導(dǎo)入并讀取Excel數(shù)據(jù)的操作步驟
- Vue實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入的四種方法(resource、Axios、Fetch、Excel導(dǎo)入)
- 如何使用vue實(shí)現(xiàn)前端導(dǎo)入excel數(shù)據(jù)
相關(guān)文章
在vant中使用時(shí)間選擇器和popup彈出層的操作
這篇文章主要介紹了在vant中使用時(shí)間選擇器和popup彈出層的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11關(guān)于vue利用postcss-pxtorem進(jìn)行移動(dòng)端適配的問題
這篇文章主要介紹了關(guān)于vue利用postcss-pxtorem進(jìn)行移動(dòng)端適配的問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11在vite項(xiàng)目中使用@進(jìn)行文件的引入方式
這篇文章主要介紹了在vite項(xiàng)目中使用@進(jìn)行文件的引入方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03vue3+elementPlus二次封裝表單的實(shí)現(xiàn)代碼
最近使用Vue3+ElementPlus開發(fā)項(xiàng)目,從整體上構(gòu)思組件的封裝。能寫成組件的內(nèi)容都進(jìn)行封裝,方便多個(gè)地方使用,這篇文章給大家介紹了vue3+elementPlus二次封裝表單的實(shí)現(xiàn),并通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-03-03