前端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…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...

Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...