当前位置: 首页 > news >正文

前端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)}}

相关文章:

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

目录 1.前言2.数据定义3. 页面布局4.上传之前的事件5.解析excel文件,并组装系统表头与excel表头的对应关系6.下拉框改变事件 1.前言 最近有一个需求&#xff0c;就是用户可以任意导入一个自定义的excel文件&#xff0c;让用户可以自己选择&#xff0c;组装表头的对应关系&…...

RabbitMQ集群配置以及负载均衡配置

RabbitMQ集群配置以及负载均衡配置 环境配置集群配置安装rabbitmq启动rabbitmq开启远程登录添加用户并且授权用户添加数据存放目录和日志存放目录查看端口拷⻉erlang.cookie将mq-2、mq-3作为内存节点加⼊mq-1节点集群中查看集群状态添加一个新的队列 RabbitMq负载均衡配置-HAPr…...

Leetcode Hot100之六:42.接雨水

题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 提示&#xff1a; n height.length 1 < n < 2 * 10^4 0 < height[i] < 10^5 思路 暴力循环&#xff1a; 原本的思路是左边界i从左到…...

electron 主进程 和 渲染进程通信 ipcRenderer 和 mainWindow.webContents

electron 开发时最麻烦就是electron版本和node版本的选择和正确安装 electron 用npm安装时太慢容易报错&#xff0c;建议用cnpm i 进行安装 注意最新版渲染进程使用node nodeIntegration: true, // 渲染进程可用node contextIsolation: false, // 这个值影响nodeIntegration是…...

关于VUE启动内存溢出

安装node v10.14.2 后 启动公司的VUE项目 使用命令npm run dev 命令 报错&#xff1a; <--- Last few GCs --->[20940:00000244699848E0] 215872 ms: Scavenge 1690.2 (1836.4) -> 1679.6 (1836.4) MB, 5.4 / 0.7 ms (average mu 0.266, current mu 0.253) a…...

HBase学习笔记(1)—— 知识点总结

目录 HBase概述 HBase 基本架构 HBase安装部署启动 HBase Shell HBase数据读写流程 HBase 优化 HBase概述 HBase是以 hdfs 为数据存储的&#xff0c;一种分布式、非关系型的、可扩展的 NoSQL 数据库 关系型数据库和非关系型数据库的区别&#xff1a; 关系型数据库和非关…...

【Linux】 awk命令使用

AWK 是一种处理文本文件的语言&#xff0c;是一个强大的文本分析工具。 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho&#xff0c;Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。 语法 awk [选项] [文件] awk [选项] [程序] [文件] awk命令 -Linux手…...

Sentinel网关限流

背景 在微服务架构下&#xff0c;每个服务的性能都不同&#xff0c;为避免出现流量洪峰将服务冲垮&#xff0c;需要依赖限流工具来保护服务的稳定性。sentinel是阿里提供的限流工具&#xff0c;社区活跃&#xff0c;功能也很全面&#xff0c;包含实时监控、流控、熔断等功能。…...

solidworks对电脑要求高吗?2023solidworks配置要求

solidworks对电脑要求高吗&#xff1f;SolidWorks是一款功能强大的三维CAD软件&#xff0c;对电脑配置有一定的要求。一般来说&#xff0c;运行SolidWorks需要的电脑配置包括较高的处理器性能、足够的内存和存储空间&#xff0c;以及一块性能良好的显卡。此外&#xff0c;对于大…...

搭建神经网络(torch.nn的用法)

零零碎碎总结了一些torch框架里面nn模块的用法&#xff0c;尤其是关于搭建神经网络的 nn.ModuleList nn.Module nn.Sequential nn.Linear nn.Dropout nn.Embedding nn.DataParallel() 将模型封装起来&#xff0c;便于在多个gpu上并行计算&#xff0c;训练或者推理 nn.…...

卡码网语言基础课 | 11. 句子缩写

目录 一、 字符串大小的比较 二、 ASCII码值 三、 基本框架代码 四、 解题思路 4.1 首字母问题 4.2 判定小写字母 4.3 小写字母转换为大写字母 五、空格判断 六、 代码模块化 6.1 满足的条件 6.2 代码完善 七、 题目解答 7.1 原始代码 7.2 改进代码 八、 拓展与…...

Surface RT 安装 Linux

零&#xff1a;起因 在家无事找出来一台老旧设备 Surface RT 一代的&#xff0c;系统最新是 Windows 8.1 arm版&#xff0c;应用商店都已经打不开了 虽说有破解方法&#xff0c;能运行些软件&#xff0c;但怎么说也不是任意安装&#xff0c;所以局限性还是相当的大&#xff0…...

C++中的函数重载:多功能而强大的特性

引言 函数重载是C编程语言中的一项强大特性&#xff0c;它允许在同一个作用域内定义多个同名函数&#xff0c;但这些函数在参数类型、个数或顺序上有所不同。本文将深入探讨函数重载的用法&#xff0c;以及它的优势和应用场景。 正文 在C中&#xff0c;函数重载是一项非常有…...

数据分析实战 | K-means算法——蛋白质消费特征分析

目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 ​编辑 八、模型评价 九、模型调参与预测 一、数据及分析对象 txt文件——“protein.txt”&#xff0c;主要记录了25个国家的9个属性&#xff0c;主…...

HTTP协议详解-下(Tomcat)

如何构造 HTTP 请求 对于 GET 请求 地址栏直接输入点击收藏夹html 里的 link script img a…form 标签 通过 form 标签构造GET请求 <body><!-- 表单标签, 允许用户和服务器之间交互数据 --><!-- 提交的数据报以键值对的结果来组织 --><form action&quo…...

acwing算法基础之搜索与图论--prim算法

目录 1 基础知识2 模板3 工程化 1 基础知识 朴素版prim算法的关键步骤&#xff1a; 初始化距离数组dist&#xff0c;将其内的所有元素都设为正无穷大。定义集合S&#xff0c;表示生成树。循环n次&#xff1a;找到不在集合S中且距离集合S最近的结点t&#xff0c;用它去更新剩余…...

Amazon EC2 Serial Console 现已在其他亚马逊云科技区域推出

即日起&#xff0c;交互式 EC2 Serial Console 现也在以下区域推出&#xff1a;中东&#xff08;巴林&#xff09;、亚太地区&#xff08;雅加达&#xff09;、非洲&#xff08;开普敦&#xff09;、中东&#xff08;阿联酋&#xff09;、亚太地区&#xff08;香港&#xff09;…...

hdlbits系列verilog解答(100输入逻辑门)-39

文章目录 一、问题描述二、verilog源码三、仿真结果一、问题描述 构建一个具有 100 个输入in[99:0]的组合电路。 有 3 个输出: out_and: output of a 100-input AND gate. out_or: output of a 100-input OR gate. out_xor: output of a 100-input XOR gate. 二、verilog源…...

Python 中 Selenium 的屏幕截图

文章目录 使用 save_screenshot() 函数在 Python 中使用 selenium 捕获屏幕截图使用 get_screenshot_as_file() 函数在 Python 中使用 selenium 捕获屏幕截图使用 Screenshot-Selenium 包在 Python 中使用 selenium 捕获屏幕截图总结我们可以使用 Selenium 在自动化 Web 浏览器…...

scrapy发json的post请求

一 、scrapy发json的post请求&#xff1a; def start_requests(self):self.headers {Content-Type: application/json}json_data {"productName": "", "currentPage": "1", "recordNumber": "10", "langua…...

uniapp 对接腾讯云IM群组成员管理(增删改查)

UniApp 实战&#xff1a;腾讯云IM群组成员管理&#xff08;增删改查&#xff09; 一、前言 在社交类App开发中&#xff0c;群组成员管理是核心功能之一。本文将基于UniApp框架&#xff0c;结合腾讯云IM SDK&#xff0c;详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

【Linux】shell脚本忽略错误继续执行

在 shell 脚本中&#xff0c;可以使用 set -e 命令来设置脚本在遇到错误时退出执行。如果你希望脚本忽略错误并继续执行&#xff0c;可以在脚本开头添加 set e 命令来取消该设置。 举例1 #!/bin/bash# 取消 set -e 的设置 set e# 执行命令&#xff0c;并忽略错误 rm somefile…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

【JVM面试篇】高频八股汇总——类加载和类加载器

目录 1. 讲一下类加载过程&#xff1f; 2. Java创建对象的过程&#xff1f; 3. 对象的生命周期&#xff1f; 4. 类加载器有哪些&#xff1f; 5. 双亲委派模型的作用&#xff08;好处&#xff09;&#xff1f; 6. 讲一下类的加载和双亲委派原则&#xff1f; 7. 双亲委派模…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...

数据分析六部曲?

引言 上一章我们说到了数据分析六部曲&#xff0c;何谓六部曲呢&#xff1f; 其实啊&#xff0c;数据分析没那么难&#xff0c;只要掌握了下面这六个步骤&#xff0c;也就是数据分析六部曲&#xff0c;就算你是个啥都不懂的小白&#xff0c;也能慢慢上手做数据分析啦。 第一…...