前端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.前言 最近有一个需求,就是用户可以任意导入一个自定义的excel文件,让用户可以自己选择,组装表头的对应关系&…...
RabbitMQ集群配置以及负载均衡配置
RabbitMQ集群配置以及负载均衡配置 环境配置集群配置安装rabbitmq启动rabbitmq开启远程登录添加用户并且授权用户添加数据存放目录和日志存放目录查看端口拷⻉erlang.cookie将mq-2、mq-3作为内存节点加⼊mq-1节点集群中查看集群状态添加一个新的队列 RabbitMq负载均衡配置-HAPr…...
Leetcode Hot100之六:42.接雨水
题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 提示: n height.length 1 < n < 2 * 10^4 0 < height[i] < 10^5 思路 暴力循环: 原本的思路是左边界i从左到…...
electron 主进程 和 渲染进程通信 ipcRenderer 和 mainWindow.webContents
electron 开发时最麻烦就是electron版本和node版本的选择和正确安装 electron 用npm安装时太慢容易报错,建议用cnpm i 进行安装 注意最新版渲染进程使用node nodeIntegration: true, // 渲染进程可用node contextIsolation: false, // 这个值影响nodeIntegration是…...
关于VUE启动内存溢出
安装node v10.14.2 后 启动公司的VUE项目 使用命令npm run dev 命令 报错: <--- 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 为数据存储的,一种分布式、非关系型的、可扩展的 NoSQL 数据库 关系型数据库和非关系型数据库的区别: 关系型数据库和非关…...
【Linux】 awk命令使用
AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。 之所以叫 AWK 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。 语法 awk [选项] [文件] awk [选项] [程序] [文件] awk命令 -Linux手…...
Sentinel网关限流
背景 在微服务架构下,每个服务的性能都不同,为避免出现流量洪峰将服务冲垮,需要依赖限流工具来保护服务的稳定性。sentinel是阿里提供的限流工具,社区活跃,功能也很全面,包含实时监控、流控、熔断等功能。…...
solidworks对电脑要求高吗?2023solidworks配置要求
solidworks对电脑要求高吗?SolidWorks是一款功能强大的三维CAD软件,对电脑配置有一定的要求。一般来说,运行SolidWorks需要的电脑配置包括较高的处理器性能、足够的内存和存储空间,以及一块性能良好的显卡。此外,对于大…...
搭建神经网络(torch.nn的用法)
零零碎碎总结了一些torch框架里面nn模块的用法,尤其是关于搭建神经网络的 nn.ModuleList nn.Module nn.Sequential nn.Linear nn.Dropout nn.Embedding nn.DataParallel() 将模型封装起来,便于在多个gpu上并行计算,训练或者推理 nn.…...
卡码网语言基础课 | 11. 句子缩写
目录 一、 字符串大小的比较 二、 ASCII码值 三、 基本框架代码 四、 解题思路 4.1 首字母问题 4.2 判定小写字母 4.3 小写字母转换为大写字母 五、空格判断 六、 代码模块化 6.1 满足的条件 6.2 代码完善 七、 题目解答 7.1 原始代码 7.2 改进代码 八、 拓展与…...
Surface RT 安装 Linux
零:起因 在家无事找出来一台老旧设备 Surface RT 一代的,系统最新是 Windows 8.1 arm版,应用商店都已经打不开了 虽说有破解方法,能运行些软件,但怎么说也不是任意安装,所以局限性还是相当的大࿰…...
C++中的函数重载:多功能而强大的特性
引言 函数重载是C编程语言中的一项强大特性,它允许在同一个作用域内定义多个同名函数,但这些函数在参数类型、个数或顺序上有所不同。本文将深入探讨函数重载的用法,以及它的优势和应用场景。 正文 在C中,函数重载是一项非常有…...
数据分析实战 | K-means算法——蛋白质消费特征分析
目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 编辑 八、模型评价 九、模型调参与预测 一、数据及分析对象 txt文件——“protein.txt”,主要记录了25个国家的9个属性,主…...
HTTP协议详解-下(Tomcat)
如何构造 HTTP 请求 对于 GET 请求 地址栏直接输入点击收藏夹html 里的 link script img a…form 标签 通过 form 标签构造GET请求 <body><!-- 表单标签, 允许用户和服务器之间交互数据 --><!-- 提交的数据报以键值对的结果来组织 --><form action&quo…...
acwing算法基础之搜索与图论--prim算法
目录 1 基础知识2 模板3 工程化 1 基础知识 朴素版prim算法的关键步骤: 初始化距离数组dist,将其内的所有元素都设为正无穷大。定义集合S,表示生成树。循环n次:找到不在集合S中且距离集合S最近的结点t,用它去更新剩余…...
Amazon EC2 Serial Console 现已在其他亚马逊云科技区域推出
即日起,交互式 EC2 Serial Console 现也在以下区域推出:中东(巴林)、亚太地区(雅加达)、非洲(开普敦)、中东(阿联酋)、亚太地区(香港)…...
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请求: def start_requests(self):self.headers {Content-Type: application/json}json_data {"productName": "", "currentPage": "1", "recordNumber": "10", "langua…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
