vue專案中匯入excel表格
阿新 • • 發佈:2021-10-28
upload 元件
<template> <div class="upload-excel"> <div class="btn-upload"> <el-button :loading="loading" size="mini" type="primary" @click="handleUpload" > 點選上傳 </el-button> </div> <input type="file" accept=".xlsx, .xls" @change="handleClick" ref="excel-upload-input" class="excel-upload-input" /> <div class="drop" @drop="handleDrop" @dragover="handleDragover" @dragenter="handleDragover" > <i class="el-icon-upload" /> <span>將檔案拖到此處</span> </div> </div> </template> <script> import XLSX from "xlsx"; export default { props: { beforeUpload: Function, // eslint-disable-line onSuccess: Function, // eslint-disable-line }, data() { return { loading: false, excelData: { header: null, results: null, }, }; }, methods: { generateData({ header, results }) { this.excelData.header = header; this.excelData.results = results; this.onSuccess && this.onSuccess(this.excelData); }, handleDrop(e) { e.stopPropagation(); e.preventDefault(); if (this.loading) return; const files = e.dataTransfer.files; if (files.length !== 1) { this.$message.error("Only support uploading one file!"); return; } const rawFile = files[0]; // only use files[0] if (!this.isExcel(rawFile)) { this.$message.error( "Only supports upload .xlsx, .xls, .csv suffix files" ); return false; } this.upload(rawFile); e.stopPropagation(); e.preventDefault(); }, handleDragover(e) { e.stopPropagation(); e.preventDefault(); e.dataTransfer.dropEffect = "copy"; }, handleUpload() { this.$refs["excel-upload-input"].click(); //觸發 input的click事件 開啟 檔案選擇框 }, // input 的changge事件處理函式 獲取選擇的 檔案 handleClick(e) { const files = e.target.files; //files是個陣列 const rawFile = files[0]; // only use files[0] if (!rawFile) return; this.upload(rawFile); }, upload(rawFile) { //如果 清除value的值 value的值一直是上次選擇的檔案 下次選擇相同的檔案時 就不會觸發change事件 this.$refs["excel-upload-input"].value = null; if (!this.beforeUpload) { this.readerData(rawFile); return; } //可以在beforeUpload中檢查檔案的型別 大小 等 如果不滿足 就不進行後續操作 const before = this.beforeUpload(rawFile); if (before) { this.readerData(rawFile); } }, readerData(rawFile) { this.loading = true; return new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = (e) => { const data = e.target.result; const workbook = XLSX.read(data, { type: "array" }); const firstSheetName = workbook.SheetNames[0]; const worksheet = workbook.Sheets[firstSheetName]; const header = this.getHeaderRow(worksheet); const results = XLSX.utils.sheet_to_json(worksheet); this.generateData({ header, results }); this.loading = false; resolve(); }; reader.readAsArrayBuffer(rawFile); }); }, getHeaderRow(sheet) { const headers = []; const range = XLSX.utils.decode_range(sheet["!ref"]); let C; const R = range.s.r; /* start in the first row */ for (C = range.s.c; C <= range.e.c; ++C) { /* walk every column in the range */ const cell = sheet[XLSX.utils.encode_cell({ c: C, r: R })]; /* find the cell in the first row */ let hdr = "UNKNOWN " + C; // <-- replace with your desired default if (cell && cell.t) hdr = XLSX.utils.format_cell(cell); headers.push(hdr); } return headers; }, isExcel(file) { return /\.(xlsx|xls|csv)$/.test(file.name); }, }, }; </script> <style scoped lang="scss"> .upload-excel { display: flex; justify-content: center; margin-top: 100px; .excel-upload-input { display: none; z-index: -9999; } .btn-upload, .drop { border: 1px dashed #bbb; width: 350px; height: 160px; text-align: center; line-height: 160px; } .drop { line-height: 80px; color: #bbb; i { font-size: 60px; display: block; } } } </style>