<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
用input 匯入 excel ,然後生成表格,然後呼叫介面上傳到後臺
<el-button v-waves :loading='downloadLoading' class='filter-item' type='primary' icon='el-icon-download' @click='daoru'> 匯入 </el-button> <el-dialog title="匯入檔案" :visible.sync="excelImportShow"> <a href="javascript:;" rel="external nofollow" class="file"> <input id="upload" type="file" @change="importfxx(this)" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" /> </a> <div id="demo"></div> <div slot="footer" class="dialog-footer"> <el-button @click.native="excelImportShow = false">取消</el-button> <el-button type="primary" @click.native="submit">提交</el-button> </div> </el-dialog>
excelImportShow: false, //匯入檔案的彈框 uploadArr: [], // 上傳給後臺的資料 realname: '', // 以下都是我要轉換的資料,因人而異 gender: '', age: '', minzu: '', wenhua: '', shengfenzheng: '', job: '', mobile: '', mark: ''
daoru() { this.excelImportShow = true },
// 匯入 importfxx(obj) { let _this = this; let inputDOM = this.$refs.inputer; // 通過DOM取檔案資料 this.file = event.currentTarget.files[0]; var rABS = false; //是否將檔案讀取為二進位制字串 var f = this.file; var reader = new FileReader(); FileReader.prototype.readAsBinaryString = function(f) { var binary = ""; var rABS = false; //是否將檔案讀取為二進位制字串 var pt = this; var wb; //讀取完成的資料 var outdata; var reader = new FileReader(); reader.onload = function(e) { var bytes = new Uint8Array(reader.result); var length = bytes.byteLength; for (var i = 0; i < length; i++) { binary += String.fromCharCode(bytes[i]); } var XLSX = require('xlsx'); if (rABS) { wb = XLSX.read(btoa(fixdata(binary)), { //手動轉化 type: 'base64' }); } else { wb = XLSX.read(binary, { type: 'binary' }); } outdata = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]); //outdata就是你想要的東西 this.da = [...outdata] let arr = [] let nameArr = outdata[1] for (let v in nameArr) { // 拿到 excel 裡面的列名,根據列名得到裡面的鍵名 let title = nameArr[v] switch (title){ case '姓名': console.log('這是姓名',nameArr[v]); _this.realname = v console.log('這是realname',v); break; case '性別': console.log('這是性別',nameArr[v]); _this.gender = v console.log('這是gender',v); break; case '年齡': console.log('這是年齡',nameArr[v]); _this.age = v console.log('這是age',v); break; case '民族': console.log('這是民族',nameArr[v]); _this.minzu = v console.log('這是minzu',v); break; case '學歷': console.log('這是性別',nameArr[v]); _this.wenhua = v console.log('這是job',v); break; case '身份證號': console.log('這是身份證號',nameArr[v]); _this.shengfenzheng = v console.log('這是shenfengzheng',v); break; case '工作單位/學校/社群': console.log('"工作單位/學校/社群"',nameArr[v]); _this.job = v console.log('這是job',v); break; case '手機/電話': console.log('這是手機/電話',nameArr[v]); _this.mobile = v console.log('這是mobile',v); break; case '備註': console.log('這是備註',nameArr[v]); _this.mark = v console.log('這是mark',v); break; default: break; } } let obj let uploadArr = [] // 這裡是一個excel裡面會有多個sheets,把裡面的惡資料整個到這個陣列裡面一起上傳 let leng = Object.keys(wb.Sheets).length // 用for迴圈,leng 是sheets的個數,用來回圈次數 for (var i = 0; i < leng+1; i++) { XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[i]]) let arrr = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[i]]) arrr = arrr.slice(2) //如果從第三行開始是資料,那這裡就是1,如果從第四行開始是資料,那這裡就是2 uploadArr.push.apply(uploadArr,arrr) _this.uploadArr = uploadArr } this.da.map(v => { let obj = {} obj.id = v.id obj.status = v.status arr.push(obj) }) let para = { withList: arr } _this.$message({ message: '請耐心等待匯入成功', type: 'success' }); } reader.readAsArrayBuffer(f); } if (rABS) { reader.readAsArrayBuffer(f); } else { reader.readAsBinaryString(f); } },
(其實這裡就是上傳到後臺介面的,存到資料庫裡面才能儲存)
// 確認匯入 submit() { let uploadArr = this.uploadArr this.excelImportShow = false let obj for (let v in uploadArr) { obj = {realname:uploadArr[v][""+this.realname+""], age:uploadArr[v][""+this.age+""], gender: uploadArr[v][""+this.gender+""]=='男'?'MALE':'FEMALE', minzu: uploadArr[v][""+this.minzu+""], wenhua: uploadArr[v][""+this.wenhua+""], shengfenzheng: uploadArr[v][""+this.shengfenzheng+""], job: uploadArr[v][""+this.job+""], wenhua: uploadArr[v][""+this.wenhua+""], mobile:uploadArr[v][""+this.mobile+""], mark:uploadArr[v][""+this.mark+""], place: "00"} // 這裡的obj 就是後臺需要的引數,用變數表示鍵名 [""+此處是你的變數+""] createUser(obj).then((res) => { 這是後臺新增的方法 if (res.data.return_code === '200') { this.dialogFormVisible = false } else { this.$notify.error(res.data.return_msg) } }) if (parseInt(v) === parseInt(uploadArr.length)-1) { console.log(v+'和'+uploadArr.length); setTimeout(()=>{ this.$notify({ title: '成功', message: '建立成功', type: 'success', duration: 2000 }) this.getList({ page: 1,limit: 20 }) // 新增成功之後呼叫list 介面,展示所新增的資料 },1500) } } },
最近遇到前端匯入並處理excel表格的情況,趁此機會剛好研究一下vue匯入並處理excel資料;當然自己手擼一個工具沒有那麼多時間,本文只是藉助現有的工具來做一下工具使用總結。
vue匯入Excel表格主要有兩種常用的方法,一個是藉助ElementUI檔案上傳進行表格匯入,另一個是自帶的input做檔案上傳;以下對兩個方法做詳細介紹;
1.1 使用ElementUI中的upload元件 安裝ElementUI
npm i element-ui -S
安裝Excel表格解析外掛
npm i xlsx -S
匯入需要用的工具包
import Vue from "vue"; import ElementUI from "element-ui"; import "element-ui/lib/theme-chalk/index.css"; import { read, utils } from "xlsx"; // 注意處理方法引入方式 Vue.use(ElementUI);
引入元件
<el-upload action="https://jsonplaceholder.typicode.com/posts/" :on-success="handleChange" :file-list="fileList" class="el-upload" >
新增處理邏輯
// 匯入成功時執行 handleChange(res, file, fileList) { // 將檔案放入 for (let i = 0; i < fileList.length; i++) { if (file.name != fileList[i].name) { this.fileList.push({ name: file.name, url: "", uid: file.uid }); } } const files = { 0: file }; this.readExcel(files); }, readExcel(file) { const fileReader = new FileReader(); fileReader.onload = ev => { try { const data = ev.target.result; const workbook = read(data, { type: "binary" }); const params = []; // 取對應表生成json表格內容 workbook.SheetNames.forEach(item => { this.tableData.push(utils.sheet_to_json(workbook.Sheets[item])); }); // 該演演算法僅針對表頭無合併的情況 if (this.tableData.length > 0) { // 獲取excel中第一個表格資料tableData[0][0],並且將表頭提取出來 for (const key in this.tableData[0][0]) { this.tableHead.push(key); } } // 重寫資料 } catch (e) { console.log("error:" + e); return false; } }; fileReader.readAsBinaryString(file[0].raw); }
以上處理的資料我這邊用元件展示在了頁面上,效果如下圖:
1.2 使用input檔案上傳 安裝Excel表格解析外掛
npm i xlsx -S
匯入需要用的工具包
import { read, utils } from "xlsx"; // 注意處理方法引入方式
使用input
<div class="flex-display"> <div class="left-box">檔案上傳(input):</div> <input type="file" v-on:change="onChange" class="file-ipt" /> </div>
新增處理邏輯
基本與上面處理邏輯相同
onChange(e) { const file = e.target.files[0]; const fileReader = new FileReader(); fileReader.onload = ev => { try { const data = ev.target.result; const workbook = read(data, { type: "binary" }); const params = []; // 取對應表生成json表格內容 workbook.SheetNames.forEach(item => { params.push({ name: item, dataList: utils.sheet_to_json(workbook.Sheets[item]) }); this.tableData.push(utils.sheet_to_json(workbook.Sheets[item])); }); // 該演演算法僅針對表頭無合併的情況 if (this.tableData.length > 0) { // 獲取excel中第一個表格資料tableData[0][0],並且將表頭提取出來 for (const key in this.tableData[0][0]) { this.tableHead.push(key); } } return params; // 重寫資料 } catch (e) { console.log("error:" + e); return false; } }; fileReader.readAsBinaryString(file); }
效果如下:
總的樣式以及程式碼如下:
<template> <div> <div class="flex-display"> <div class="left-box">表格上傳(ElementUI):</div> <el-upload action="https://jsonplaceholder.typicode.com/posts/" :on-success="handleChange" :file-list="fileList" class="el-upload" > <el-button size="small" type="primary" class="el-btn" >點選上傳</el-button > <div slot="tip" class="el-upload-tip"> 只能上傳xlsx檔案,且不超過5MB </div> </el-upload> </div> <el-table v-if="tableHead.length" :data="tableData[0]" style="width: 100%"> <el-table-column v-for="(data, key) in tableHead" :prop="data" :label="data" :key="key" width="180" > </el-table-column> </el-table> <div class="flex-display"> <div class="left-box">檔案上傳(input):</div> <input type="file" v-on:change="onChange" class="file-ipt" /> </div> </div> </template>
<script> import Vue from "vue"; import ElementUI from "element-ui"; import "element-ui/lib/theme-chalk/index.css"; import { read, utils } from "xlsx"; Vue.use(ElementUI); export default { data() { return { fileList: [], //上傳檔案列表 tableHead: [], //表頭 tableData: [] // 表資料 }; }, methods: { onChange(e) { const file = e.target.files[0]; const fileReader = new FileReader(); fileReader.onload = ev => { try { const data = ev.target.result; const workbook = read(data, { type: "binary" }); const params = []; // 取對應表生成json表格內容 workbook.SheetNames.forEach(item => { params.push({ name: item, dataList: utils.sheet_to_json(workbook.Sheets[item]) }); this.tableData.push(utils.sheet_to_json(workbook.Sheets[item])); }); // 該演演算法僅針對表頭無合併的情況 if (this.tableData.length > 0) { // 獲取excel中第一個表格資料tableData[0][0],並且將表頭提取出來 for (const key in this.tableData[0][0]) { this.tableHead.push(key); } } return params; // 重寫資料 } catch (e) { console.log("error:" + e); return false; } }; fileReader.readAsBinaryString(file); }, handleChange(res, file, fileList) { // 將檔案放入 for (let i = 0; i < fileList.length; i++) { if (file.name != fileList[i].name) { this.fileList.push({ name: file.name, url: "", uid: file.uid }); } } // this.fileList = fileList.slice(-3); const files = { 0: file }; this.readExcel(files); }, readExcel(file) { const fileReader = new FileReader(); fileReader.onload = ev => { try { const data = ev.target.result; const workbook = read(data, { type: "binary" }); const params = []; // 取對應表生成json表格內容 workbook.SheetNames.forEach(item => { params.push({ name: item, dataList: utils.sheet_to_json(workbook.Sheets[item]) }); this.tableData.push(utils.sheet_to_json(workbook.Sheets[item])); }); // 該演演算法僅針對表頭無合併的情況 if (this.tableData.length > 0) { // 獲取excel中第一個表格資料tableData[0][0],並且將表頭提取出來 for (const key in this.tableData[0][0]) { this.tableHead.push(key); } } return params; // 重寫資料 } catch (e) { console.log("error:" + e); return false; } }; fileReader.readAsBinaryString(file[0].raw); } } }; </script>
<style lang="scss" scoped> .upload-demo { width: 100%; } .flex-display { margin: 50px 30px; width: 100%; display: flex; justify-content: flex-start; .left-box { margin: 20 30; height: 36px; line-height: 36px; } } .el-upload { margin-left: 40px; .el-btn { font-size: 16px; } .el-upload-tip { display: inline; font-size: 12px; } } .file-ipt { width: 200px; height: 36px; line-height: 36px; button { background-color: #409eff; } } input #file-upload-button { background-color: #409eff; } </style>
總結:較為容易踩坑的點就是xlsx這個包的匯入方式,這個包處理excel表格功能時相當強大的,除了匯入與資料解析,還有匯出為excel等功能,在我們日常網站開發中非常常用。其次容易踩坑的就是vue中事件的監聽與處理方式,我們可以看到使用元件賀不使用元件區別還是比較大的,當然使用現有元件往往能獲得更好的效果,所以這裡還是推薦大家使用方法一去實現這個功能。
最後本文僅對資料做簡單處理,若要處理更為複雜的表格資料,就需要研究更強大的演演算法,不喜勿碰。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45