基于Vue實(shí)現(xiàn)Excel解析與導(dǎo)出功能詳解
前言
最近在整理日常開發(fā)中長涉及到的業(yè)務(wù)需求,正好想到了excel的解析與上傳方面的事情,在開發(fā)中還是比較常見的,趁著周末做一下整理學(xué)習(xí)吧
基本介紹
主要基于Vue+element實(shí)現(xiàn)文件的解析與導(dǎo)出,用的的插件是 xlsx,里面的具體方法,感興趣的去研究一下,基本的樣式,配置就不贅述了,也比較簡單,我們直接上主食
代碼實(shí)現(xiàn)
基本結(jié)構(gòu)
用戶點(diǎn)擊文件上傳,將excel的表格已json的格式顯示在頁面中,用戶進(jìn)行操作,檢查數(shù)據(jù)后對(duì)服務(wù)進(jìn)行提交,上傳操作用的的element中的upload組件
<!-- 上傳文件按鈕 --> <div class="buttonBox"> <el-upload action accept=".xlsx, .xls" :auto-upload="false" :show-file-list="false" :on-change="handle" > <el-button type="primary" slot="trigger">選取EXCEL文件</el-button> </el-upload> <el-button type="success" @click="submit" :disabled="disable">采集數(shù)據(jù)提交</el-button> </div> <!-- 解析出來的數(shù)據(jù) --> <div class="tableBox" v-show="show"> <h3> <i class="el-icon-info"></i> 小主,以下是采集完成的數(shù)據(jù),請您檢查無誤后,點(diǎn)擊“采集數(shù)據(jù)提交”按鈕上傳至服務(wù)器哦! </h3> <el-table :data="tempData" style="width: 100%" :height="height" border> <el-table-column prop="name" label="姓名" min-width="50%"></el-table-column> <el-table-column prop="phone" label="電話" min-width="50%"></el-table-column> </el-table> </div>
上傳解析
通過upload組件可以獲取上傳的文件流(下圖)
將文件流轉(zhuǎn)為二進(jìn)制,這里我們可以在utils文件中增加對(duì)應(yīng)的方法(如下)
// 把文件按照二進(jìn)制進(jìn)行讀取 export function readFile(file) { return new Promise(resolve => { let reader = new FileReader(); reader.readAsBinaryString(file); reader.onload = ev => { resolve(ev.target.result); }; }); }
通過xlsx將二進(jìn)制六轉(zhuǎn)為json,這樣才能顯示
//讀取FILE中的數(shù)據(jù)(變?yōu)镴SON格式) let data = await readFile(file); let workbook = xlsx.read(data, { type: "binary" }), worksheet = workbook.Sheets[workbook.SheetNames[0]]; data = xlsx.utils.sheet_to_json(worksheet); // 打印結(jié)果加下圖 console.log(workbook);
把讀取出來的數(shù)據(jù)變?yōu)樽詈罂梢詡鬟f給服務(wù)器的數(shù)據(jù),我們需要先封裝一個(gè)映射表來對(duì)應(yīng)傳給后端的格式(如下)
// 字段對(duì)應(yīng)表 export let character = { name: { text: "姓名", type: 'string' }, phone: { text: "電話", type: 'string' } };
轉(zhuǎn)換數(shù)據(jù)格式
let arr = []; data.forEach(item => { let obj = {}; for (let key in character) { if (!character.hasOwnProperty(key)) break; let v = character[key], text = v.text, type = v.type; v = item[text] || ""; type === "string" ? (v = String(v)) : null; type === "number" ? (v = Number(v)) : null; obj[key] = v; } arr.push(obj); });
發(fā)送給服務(wù)器
這里要看服務(wù)器支持多條文件一起發(fā)送,如果不支持我們前端就可以采用遞歸逐條發(fā)送的方式進(jìn)行發(fā)送,具體情況可以與后端進(jìn)行溝通,我們這采用遞歸的方式進(jìn)行傳輸
// 提交數(shù)據(jù)給服務(wù)器 async submit() { if (this.tempData.length <= 0) { this.$message({ message: "小主,請您先選擇EXCEL文件!", type: "warning", showClose: true }); return; } this.disable = true; let loadingInstance = Loading.service({ text: "小主,請您稍等片刻,奴家正在玩命處理中!", background: "rgba(0,0,0,.5)" }); // 完成后處理的事情 let complate = () => { this.$message({ message: "小主,奴家已經(jīng)幫您把數(shù)據(jù)上傳了!", type: "success", showClose: true }); this.show = false; this.disable = false; loadingInstance.close(); }; // 需要把數(shù)據(jù)一條條傳遞給服務(wù)器 let n = 0; let send = async () => { if (n > this.tempData.length - 1) { // 都傳遞完了 complate(); return; } let body = this.tempData[n]; // 走接口 let result = await createAPI(body); if (parseInt(result.code) === 0) { // 成功 n++; } send(); }; send(); }
以上就是對(duì)Excel文件的解析與上傳的總結(jié),其實(shí)并不是很難,都是日常開發(fā)常常涉及的業(yè)務(wù),接下來一起看下Excel的導(dǎo)出吧
Excel的導(dǎo)出
基本結(jié)構(gòu)
一進(jìn)來頁面獲取剛剛上傳的文件,然后顯示在表格中,然后做個(gè)分頁.......這些就不說了,我們直接從點(diǎn)擊導(dǎo)出excel按鈕開始,先看下頁面結(jié)構(gòu)
<div class="container"> <!-- 上傳按鈕 --> <div class="buttonBox"> <router-link to="/upload"> <el-tooltip content="EXCEL數(shù)據(jù)采集" placement="top"> <el-button type="primary" icon="el-icon-edit" circle></el-button> </el-tooltip> </router-link> </div> <!-- 搜索區(qū)域 --> <div class="searchBox"> <el-input v-model="search" placeholder="基于姓名、手機(jī)模糊搜索" @change="searchHandle"></el-input> <el-button type="success" @click="submit" :disabled="disabled">導(dǎo)出選中的數(shù)據(jù)</el-button> </div> <!-- 列表區(qū)域 --> <div class="tableBox"> <el-table :data="tableData" :height="height" style="width: 100%" v-loading="loading" element-loading-text="小主,奴家正在努力加載中..." @selection-change="selectionChange" > <el-table-column type="selection" width="50" align="center"></el-table-column> <el-table-column prop="id" label="編號(hào)" min-width="10%"></el-table-column> <el-table-column prop="name" label="姓名" min-width="20%"></el-table-column> <el-table-column prop="phone" label="電話" min-width="20%"></el-table-column> <el-table-column prop="time" label="創(chuàng)建時(shí)間" min-width="25%" :formatter="formatter"></el-table-column> </el-table> </div> <!-- 分頁區(qū)域 --> <div class="pageBox"> <el-pagination background hide-on-single-page layout="total, sizes, prev, pager, next" :page-size="pageSize" :current-page="page" :total="total" @size-change="sizeChange" @current-change="prevNext" @prev-click="prevNext" @next-click="prevNext" ></el-pagination> </div> </div>
導(dǎo)出Excel
將json數(shù)據(jù)變?yōu)閟heet數(shù)據(jù),新建表格,在表格中插入一個(gè)sheet,通過xlsx的writeFile方法將文件寫入
// 導(dǎo)出數(shù)據(jù) submit() { if (this.selectionList.length <= 0) { this.$message({ message: "小主,請您先選擇要導(dǎo)出的數(shù)據(jù)哦!", type: "warning", showClose: true }); return; } this.disabled = true; let loadingInstance = Loading.service({ text: "小主,請您稍等片刻,奴家正在玩命處理中...", background: "rgba(0,0,0,.5)" }); let arr = this.selectionList.map(item => { return { 編號(hào): item.id, 姓名: item.name, 電話: item.phone }; }); // 將json數(shù)據(jù)變?yōu)閟heet數(shù)據(jù) let sheet = xslx.utils.json_to_sheet(arr), // 新建表格 book = xslx.utils.book_new(); // 在表格中插入一個(gè)sheet xslx.utils.book_append_sheet(book, sheet, "sheet1"); // 通過xlsx的writeFile方法將文件寫入 xslx.writeFile(book, `user${new Date().getTime()}.xls`); loadingInstance.close(); this.disabled = false; }
**以上是對(duì)Excele的相關(guān)操作,文件上傳解析是常見的需求,如果前端小伙伴們對(duì)大文件上傳以及斷電續(xù)傳感興趣的可以參考一下我的這篇文章大文件上傳與斷點(diǎn)續(xù)傳
總結(jié)
到此這篇關(guān)于基于Vue實(shí)現(xiàn)Excel解析與導(dǎo)出功能的文章就介紹到這了,更多相關(guān)Vue Excel解析與導(dǎo)出內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue中tab選項(xiàng)卡的實(shí)現(xiàn)思路
今天給大家分享vue中tab 選項(xiàng)卡的一些套路,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-11-11vue3 element-plus二次封裝組件系列之伸縮菜單制作
這篇文章主要介紹了vue3 element-plus二次封裝組件系列之伸縮菜單制作,是基于vue3 vite element-plus搭建的,值的注意的時(shí)候,里面的圖標(biāo)組件是經(jīng)過處理的,結(jié)合實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01vue3使用elementPlus進(jìn)行table合并處理的示例詳解
虛擬數(shù)據(jù)中公司下有多個(gè)客戶,公司一樣的客戶,公司列需要合并,客戶如果一樣也需要合并進(jìn)行展示,所以本文給大家介紹了vue3使用elementPlus進(jìn)行table合并處理的實(shí)例,文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02Vue實(shí)現(xiàn)調(diào)節(jié)窗口大小時(shí)觸發(fā)事件動(dòng)態(tài)調(diào)節(jié)更新組件尺寸的方法
今天小編就為大家分享一篇Vue實(shí)現(xiàn)調(diào)節(jié)窗口大小時(shí)觸發(fā)事件動(dòng)態(tài)調(diào)節(jié)更新組件尺寸的方法。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-09-09vue使用xlsx庫和xlsx-style庫導(dǎo)入導(dǎo)出excel、設(shè)置單元格背景色、文字居中、合并單元格、設(shè)置列寬
xlsx是由SheetJS開發(fā)的一個(gè)處理excel文件的npm庫,適用于前端開發(fā)者實(shí)現(xiàn)導(dǎo)入導(dǎo)出excel文件的經(jīng)典需求,這篇文章主要介紹了vue使用xlsx庫和xlsx-style庫導(dǎo)入導(dǎo)出excel、設(shè)置單元格背景色、文字居中、合并單元格、設(shè)置列寬,需要的朋友可以參考下2023-11-11