前端Vue 结合xlxs库实现解析excel文件,并动态组装表头!

目录

    • 1.前言
    • 2.数据定义
    • 3. 页面布局
    • 4.上传之前的事件
    • 5.解析excel文件,并组装系统表头与excel表头的对应关系
    • 6.下拉框改变事件

1.前言

最近有一个需求,就是用户可以任意导入一个自定义的excel文件,让用户可以自己选择,组装表头的对应关系,这样做的目的是为了解决模板的局限性,更加的灵活的导入

2.数据定义

data() {return {file: null,excelHeaders: [],tableData: [],page: {},scanPage: {},list: [],total: 0,scanList: [],scanTotal: 0,excelLimit: 0,dataLoading: false,visible: false,importDescVisible: false,importVisible: false,uploadLoading: false,fileName: '',users: [],selectedHeaders: [],headerOptions: [],excelData: [],tempExcelData: [],headerMappings: [],systemHeaders: [{title: '编号',isRequire: true},{title: '交易日期',isRequire: true},{title: '付款人',isRequire: true},{title: '付款人账号',isRequire: true},// {//     title: '收款人',//     isRequire: true// },// {//     title: '收款人账号',//     isRequire: true// },{title: '金额',isRequire: true},{title: '摘要',isRequire: false},{title: '备注',isRequire: false},],initSystemHeaders: [{title: '编号',isRequire: true},{title: '交易日期',isRequire: true},{title: '付款人',isRequire: true},{title: '付款人账号',isRequire: true},// {//     title: '收款人',//     isRequire: true// },// {//     title: '收款人账号',//     isRequire: true// },{title: '金额',isRequire: true},{title: '摘要',isRequire: false},{title: '备注',isRequire: false},],fileFormat: ['xlsx', 'xlc', 'xlm', 'xls', 'xlt', 'xlw', 'csv'],batchStatus: '',headerMap: new Map,scanLoading: false,batchNumber: '',tableSize: 0,showTableSize: 0,}}

3. 页面布局

<div><el-uploadaction=""accept=".xlsx":limit="1":before-upload="beforeUpload":on-exceed="handleExceed":on-success="handleUploadSuccess":on-error="handleUploadError"><el-button type="primary" plain>选择文件</el-button></el-upload><div slot="tip" class="el-upload__tip">只能上传xlsx/xls文件,且不超过5MB</div><div v-if="this.fileName !==''" style="margin-top: 10px;font-size: 15px;">本次导入文件名:<span style="margin-right: 15px;color: #dd1100">{{ this.fileName }}</span>导入数据条数:<span style="margin-right: 15px;color: #dd1100">{{this.tableSize -1}}</span>展示数据条数: <span style="margin-right: 15px;color: #dd1100">{{this.tableData.length}}</span></div><div style="overflow-x: auto;"><table  class="text-center"  cellspacing="0" cellpadding="0" border="1"style="margin-top: 10px;width: 3000px"><thead style="height: 35px;background-color: #f2dae2"><tr><th colspan="1" rowspan="1" style="width: 1500px"v-for="(header, index) in systemHeaders":key="index":style="header.isRequire ? { color: 'red' } : {}">{{ header.title }}</th></tr></thead><tbody v-if="tableData.length >0" class="text-center"><tr style="height: 35px"><td v-for="(header, index) in excelHeaders" :key="index"><select v-model="selectedHeaders[index]"@change="handleHeaderChange(index)":disabled="systemHeaders[index].title === '-'"style="height: 35px;width: 100%"><option v-for="option in headerOptions" :key="option" :value="option">{{ option }}</option></select></td></tr><tr v-for="(row, rowIndex) in tableData" :key="rowIndex"   style="min-height: 35px"><td v-for="(cell, cellIndex) in row":key="cellIndex":style="cellIndex >= systemHeaders.length ? { 'width': '1500px' }: '' ">{{ cell }}</td></tr></tbody></table></div><el-button type="warning" plain @click="handleRemove" :disabled="this.fileName === ''">移除文件</el-button><el-button type="success" plain @click="confirmImport" style="margin-top: 15px":disabled="this.excelLimit === 0" :loading="this.uploadLoading">确认导入</el-button>
</div>

4.上传之前的事件

 beforeUpload(file) {this.file = file;this.fileName = file.namelet fileSize = file.sizeconst FIVE_M = 5 * 1024 * 1024//不允许上传大于5Mif (fileSize > FIVE_M) {this.$message.error("最大上传5MB")return false}const suffix = file.name.split('.').reverse()[0];if (!this.fileFormat.includes(suffix)) {this.$message.error('只能上传.xlsx或者.xls文件')return false}this.handleFileUploaded(file)this.excelLimit = 1return false; // 阻止默认上传行为}

5.解析excel文件,并组装系统表头与excel表头的对应关系

 handleFileUploaded(file) {console.log("==============>>开始解析excel文件<<==============")let reader = new FileReader()let _this = this;reader.onload = (e) => {const data = new Uint8Array(e.target.result)const workbook = XLSX.read(data, {type: 'array',cellDates: true})const worksheet = workbook.Sheets[workbook.SheetNames[0]]const jsonData = XLSX.utils.sheet_to_json(worksheet, {header: 1})_this.tableSize = jsonData.lengthconst regex = /^[a-zA-Z]{3} [a-zA-Z]{3} \d{2} \d{4} \d{2}:\d{2}:\d{2} GMT\+\d{4} \(中国标准时间\)$/;const tableData = jsonData.map(row => {return row.map(cell => {if (cell !== '' || cell !== null) {if (regex.test(cell.toString())) {let date = new Date(cell);date.setDate(date.getDate() + 1);const isoDateString = date.toISOString();return isoDateString.slice(0, 10).replace('T', '-');}}return cell;});});// 获取Excel的表头_this.excelHeaders = tableData[0]// 根据系统表头和Excel表头生成下拉框选项for (let index = 0; index < _this.excelHeaders.length; index++) {const excelHeader = _this.excelHeaders[index]_this.headerOptions.push(excelHeader)}if (!_this.objectsAreEqual(_this.systemHeaders, _this.excelHeaders)) {_this.headerOptions.unshift('缺失')}// 初始化选中的表头_this.initSelectHeader();// 获取对应列的数据(这里只展示前5条)_this.tableData = JSON.parse(JSON.stringify(tableData.slice(1, 6)))_this.tempExcelData = JSON.parse(JSON.stringify(tableData.slice(1, 6)))// 初始化表格数据_this.initExcelData()//组装表头初始关系_this.handHeaderMapping()}reader.readAsArrayBuffer(file)},initSelectHeader() {this.systemHeaders.forEach((systemHeader) => {let selectedHeader = '缺失';let _excelHeader = '';for (let index = 0; index < this.excelHeaders.length; index++) {const excelHeader = this.excelHeaders[index]if (excelHeader === systemHeader.title) {_excelHeader = excelHeaderbreak;}}if (_excelHeader !== '') {this.selectedHeaders.push(_excelHeader)} else {this.selectedHeaders.push(selectedHeader)}});if (this.excelHeaders.length > this.systemHeaders.length) {this.selectedHeaders = this.selectedHeaders.concat(this.excelHeaders.slice(this.selectedHeaders.length));const moreLength = this.excelHeaders.length - this.systemHeaders.lengthfor (let index = 0; index < moreLength; index++) {this.systemHeaders.push({title: '-', isRequire: false})}}},initExcelData() {for (let index = 0; index < this.selectedHeaders.length; index++) {this.handleHeaderChange(index)}},objectsAreEqual(obj1, obj2) {return JSON.stringify(obj1) === JSON.stringify(obj2);},handHeaderMapping() {const headerMap = new Map();let filteredSystemHeaders = this.systemHeaders.filter(header => header.title !== '-')filteredSystemHeaders.forEach((item, index) => {let key = this.selectedHeaders[index]headerMap.set(item.title, key)})this.headerMap = headerMap;}

6.下拉框改变事件

handleHeaderChange(index) {const selectedHeader = this.selectedHeaders[index]if (selectedHeader === '缺失') {// 如果选择了缺失,则清空对应列的数据this.tableData.forEach(row => {row[index] = ''})} else {// 如果选择了Excel表头,则将对应列的数据展示到系统表头下this.tableData.forEach((row, _index) => {const rowIndex = this.excelHeaders.findIndex(item => item === selectedHeader);if (rowIndex >= 0) {row[index] = this.tempExcelData[_index][rowIndex]}})}//更新头部映射if (this.systemHeaders[index] !== undefined && this.systemHeaders[index] !== null) {let _systemHeader = this.systemHeaders[index].titlethis.headerMap.set(_systemHeader, selectedHeader)}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/137727.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Adobe ME下载、Media Encoder下载

Media Encoder 2021 是一款可以帮助Adobepremiere pro和Adobe After Effects的用户使用集成视频编码器进行创作的视频和音频编码软件。Media Encoder 2021 mac新版本中针对上一个版本进行了多方面的改进与优化&#xff0c;提升了软件的性能与支持文件格式提升&#xff0c;有需要…

C++:list?自己模拟实现!

目录 1.list的模拟实现 1.1 成员变量和节点 1.2 迭代器实现 1.2.1 非const的迭代器 1.2.2 const的迭代器 1.2.3 一个模板实现 const 与 非const 迭代器 1.3 增删改查的实现 1.4 拷贝构造函数&#xff0c;析构函数与赋值运算符重载 1.5 泛型编程实现打印 2. list 反…

从零开始搭建React+TypeScript+webpack开发环境-基于lerna的webpack项目工程化改造

项目背景 在实际项目中&#xff0c;我们的前端项目往往是一个大型的Webpack项目&#xff0c;结构较为复杂。项目根目录下包含了各种配置文件、源代码、以及静态资源&#xff0c;整体布局相对扁平。Webpack的配置文件分散在不同的部分&#xff0c;包括入口文件、输出目录、加载…

ubuntu使用Parted GPT 创建大于2TB的的分区

问题 加购了一个4TB的ssd用于装载数据&#xff0c;使用fdisk挂载时候遇到一下warning&#xff1a; $ sudo fdisk /dev/sdbWelcome to fdisk (util-linux 2.34). Changes will remain in memory only, until you decide to write them. Be careful before using the write com…

文本生成高精准3D模型,北京智源AI研究院等出品—3D-GPT

北京智源AI研究院、牛津大学、澳大利亚国立大学联合发布了一项研究—3D-GPT&#xff0c;通过文本问答方式就能创建高精准3D模型。 据悉&#xff0c;3D-GPT使用了大语言模型的多任务推理能力,通过任务调度代理、概念化代理和建模代理三大模块&#xff0c;简化了3D建模的开发流程…

Vue3 + ts+ elementUi 实现后台数据渲染到下拉框选项中,滑动加载更多数据效果

前言 功能需求&#xff1a;下拉框中分页加载后端接口返回的人员数据&#xff0c;实现滑动加载更多数据效果&#xff0c;并且可以手动搜索定位数据&#xff0c;此项目使用Vue3 ts elementUi 实现 实现 把此分页滑动加载数据功能封装成vue中的hooks&#xff0c;文件命名为use…

C++ | 继承和多态

目录 继承 继承的概念及用法 继承的作用域 向上转型和向下转型 继承过程中的默认生成函数 菱形继承及其解决方案 - 虚继承 虚继承的原理 - 虚基类表 继承和组合 多态 虚函数 多态的定义及使用 纯虚函数与抽象类 多态的原理 小点补充 虚表的位置 父类指针new一个…

django 批量 serializers listserializers

Django drf 序列化器 序列化器 扩展serializers的有用性是我们想要解决的问题。但是&#xff0c;这不是一个微不足道的问题&#xff0c;而是需要一些严肃的设计工作。— Russell Keith-Magee, Django用户组 序列化器允许把像查询集和模型实例这样的复杂数据转换为可以轻松渲染…

conda修改虚拟环境名称

conda 修改虚拟环境名称 conda 不能直接更改名称&#xff0c;但是可以通过克隆环境解决 新建环境&#xff08;克隆旧环境&#xff09; conda create --name 新环境名 --clone 旧环境名 删除原环境 conda remove --name 旧环境名 --all 查看现有环境 conda env list conda i…

Spring boot 整合grpc 运用

文章目录 GRPC基础概念&#xff1a;Protocol Buffers&#xff1a;proto 基础语法&#xff1a;调用类型&#xff1a; Spring boot 整合 grpc项目结构&#xff1a;整合代码&#xff1a;父 pomproto 模块服务端&#xff1a;客户端&#xff1a;实际调用&#xff1a; 原生集成 GRPC基…

Java 变量初始化的两种方式和优缺点比较

第一种初始化方式&#xff1a;&#xff08;优先推荐&#xff09; String fileRename null; File fileToSave null; 这种方式将变量的作用域限定在循环外部&#xff0c;即在整个代码块中都可以使用这些变量。初始值为null表示变量在开始时没有具体的数值。 这种方式更好的…

SDN和NFV笔记

目录 SDN SDN的引入 SDN的概念 SDN网络部署的方式 SDN架构 OpenFlow SDN与传统网络的区别 SDN的应用 SDN的优点 NFV NFV的概念&#xff1a; NFV的架构&#xff1a; NFV相比于传统物理网元&#xff1a; NFV与SDN的关系 NFV与SDN的相似点 NFV与SDN的不同 SDN SD…

CVE-2023-25194 Kafka JNDI 注入分析

Apache Kafka Clients Jndi Injection 漏洞描述 Apache Kafka 是一个分布式数据流处理平台&#xff0c;可以实时发布、订阅、存储和处理数据流。Kafka Connect 是一种用于在 kafka 和其他系统之间可扩展、可靠的流式传输数据的工具。攻击者可以利用基于 SASL JAAS 配置和 SASL …

Linux常用命令:find、grep、vim、cat、less、more

目录 我的常用搜索命令 find 命令 grep 命令 vim 常用命令&#xff1a; 1.光标移动命令 2插入命令 3.删除命令 4.复制和粘贴命令 5.撤销和重做命令 6.查找和替换命令 7.文件操作命令 8.其他命令 cat命令 less 命令 more 命令 less和more命令的区别 less和vim命…

前端设计模式之【单例模式】

文章目录 前言介绍实现单例模式优缺点&#xff1f;后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;前端设计模式 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出…

计算机毕业设计 基于Web的视频及游戏管理平台的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

低于1.5kg轻薄笔记本不完全汇总(2023年11月)

本文对一些轻薄笔记本&#xff08; < 1.5kg &#xff09;的基本信息进行了汇总&#xff0c;仅供参考。其中“容量”列只记录了该机型的一种配置&#xff0c;不代表该机型只有这种配置。“屏幕”列中&#xff0c;除特殊说明外&#xff0c;OLED一般为镜面屏&#xff0c;IPS和L…

OSG交互:选中场景模型并高亮显示

1、目的 可以在osg视图中选中指定模型实体,并高亮显示。共分为两种,一种鼠标点选,一种框选。 2、鼠标点选 2.1 功能说明 生成两组对象,一组cow对象可以被选中,另一组robot不能被选中;点击cow对象被选中高亮,点击robot被选中不高亮;点击空白处,弹出“select nothing!…

【Git】Git的GUI图形化工具ssh协议IDEA集成Git

一、GIT的GUI图形化工具 1、介绍 Git自带的GUI工具&#xff0c;主界面中各个按钮的意思基本与界面文字一致&#xff0c;与git的命令差别不大。在了解自己所做的操作情况下&#xff0c;各个功能点开看下就知道是怎么操作的。即使不了解&#xff0c;只要不做push操作&#xff0c;…

Java,多线程,线程的两种创建方式

首先是多线程的一些相关概念&#xff1a; 相关概念&#xff1a; 程序&#xff08;program&#xff09;&#xff1a;为完成特定任务&#xff0c;用某种语言编写的一组指令的集合。即指一段静态&#xff08;指不在执行中&#xff09;的代码。 进程&#xff08;process&#xf…