vue3导入excel并解析excel数据渲染到表格中,纯前端实现。

亮晶晶的芋头 2024-06-12 08:03:16 阅读 59

需求

用户将已有的excel上传到系统,并将excel数据同步到页面的表格中进行二次编辑,由于excel数据不是最终数据,只是批量的一个初始模板,后端不需要存储,所以该功能由前端独立完成。

吐槽

系统中文件上传下载预览三部曲走了一遍,万万没想到还要自己实现同步数据。

实际

反手各种资料开始查阅,终于找到了可以完美实现该需求的方法,来记录下我的实现方案。希望对有需要的小伙伴有帮助。

注意以下为正文(重要内容),好好阅读,不要漏掉重要知识点奥~ 


涉及到的主要知识点

插件xlsxelementUI  plus中的Upload 上传组件动态设置 ref

展开说说:

1、插件xlsx

// 在项目根路径 安装xlsxnpm install -S xlsx// 在需要使用的页面引入xlsximport * as xlsx from 'xlsx'

2、upload上传组件

上传组件的自动上传方法,传参方法,详细可翻阅elementUI plus官网

3、动态设置ref

涉及到动态设置ref的原因:

一是由于upload组件在设置了 :limit="1",在上传第一个文件之后,浏览器会保存着我们已经上传的文件,导致我们继续上传文件的时候,页面没有反应;解决该问题需要在on-success钩子函数中通过ref来清除已经上传的文件。

<template> <div> <el-upload ref="importExcelRef" :action="VITE_APP_API_URL" :limit="1" :show-file-list="false" class="uploadExcelContent" :on-success="importSuccess" > <div title="导入excel"> <div class="importExcel"></div> </div> </el-upload> </div></template><script setup> import { ref } from 'vue' const importExcelRef = ref(null) const importSuccess = ()=>{ importExcelRef.value.clearFiles(); }</script>

二是因为表单中存在多个表格需要导入excel作为基础数据进行编辑,且表格数量不固定,是根据后端数据渲染的,所以在清空上传文件的时候,需要处理未知的多个,所以需要动态设置ref。

<template> <div> <el-upload :ref="(el) => handleSetUploadRefMap(el, rowIndex,compIndex)"> <div title="导入excel" > <div class="importExcel"></div> </div> </el-upload> </div></template><script>import { ref } from 'vue'const uploadRefMap = ref({});// 动态设置upload Refconst handleSetUploadRefMap = (el,rowIndex,compIndex) => { if (el) { uploadRefMap.value[`Upload_Ref_${rowIndex}_${compIndex}`] = el }}</script>

需求实现代码

<template> <div> <!-- 上传excel --> <el-upload :ref="(el) => handleSetUploadRefMap(el)" action="" :http-request="httpExcelRequest" :limit="1" :show-file-list="false" class="uploadExcelContent" :data={} > <div title="导入excel" style="cursor: pointer;" > <div>导入excel</div> </div> </el-upload> <!-- 列表 --> <div class="excel-content" v-for="(rowItem,rowIndex) in excelList" :key="rowIndex"> <div class="comp" v-for="(comp,compIndex) in rowItem" :key="compIndex">{ {comp}}</div> </div> </div></template><script setup name="mainContent">import * as xlsx from 'xlsx' import {ElMessage} from 'element-plus'import { ref } from 'vue'const uploadRefMap = ref({});const excelList = ref([])// 动态设置upload Refconst handleSetUploadRefMap = (el) => { if (el) { uploadRefMap.value[`Upload_Ref`] = el }}// 文件上传自定义const httpExcelRequest = async (op) => { // 获取除文件之外的参数,具体根据实际业务需求来 console.log(op.data) // 获取上传的excel 并解析数据 let file = op.file let dataBinary = await readFile(file); let workBook = xlsx.read(dataBinary, { type: "binary", cellDates: true }) let workSheet = workBook.Sheets[workBook.SheetNames[0]] const excelData = xlsx.utils.sheet_to_json(workSheet,{ header: 1 }) excelList.value = excelData console.log(excelData) if(uploadRefMap.value[`Upload_Ref`]){ uploadRefMap.value[`Upload_Ref`].clearFiles(); }}const readFile = (file) => {return new Promise((resolve) => { let reader = new FileReader() reader.readAsBinaryString(file) reader.onload = (ev) => { resolve(ev.target?.result) }})}</script><style lang="scss" scoped>.uploadExcelContent{ display: flex; flex-direction: row;}.excel-content{ display: flex; flex-direction: row; align-items: center; .comp{ width: 200px; font-size: 12px; }}</style>

由于业务需求不同,对表格数据的详细处理逻辑,就不在这里显示了,可根据自己的数据结构进行赋值操作,运行demo后可以直接在控制台查看拿到的excel数据。

今天就到这里了,会继续加油的,是亮晶晶的芋头哟~



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。