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

vue excel转json功能 xlsx

在这里插入图片描述

需求:

  1. 完成excel表格内容转json,excel表格内可能存在多个表格,要求全部解析出来。
  2. 完成表格内合服功能,即:提取表格内老服务器与新服务器数据,多台老服务器对应合并到一台新服务器上
    3.最终输出结果为:[{‘10086-l’:[‘10086-1’,‘10086-2’,…]}] …

一、前置准备

安装依赖

首先确保安装 xlsx 库:

npm install xlsx
核心思路

嵌套表格通常通过空行、固定标题或特定标识分隔,且子表格结构一致(如列数、表头相同)。需通过遍历行数据,识别子表格的边界(起始行、结束行),再提取每个子表格的内容并转换为 JSON。

二、实现步骤及代码

假设 Excel 结构如下(示例):
包含 3 个子表格,以空行分隔,每个子表格有表头(name、id、老服务器,新服务器)和数据行。

1. 读取 Excel 文件并解析工作表
return new Promise((resolve, reject) => {const reader = new FileReader();// 开始读取文件内容reader.readAsArrayBuffer(raw);reader.onload = (e) => {// 将文件内容读取为ArrayBuffer并解析为workbook对象const data = e.target?.result;// 第一行开始 第五行结束const workbook = XLSX.read(data, { type: "array" });// 获取第一个工作表数据并转换为JSON格式const sheetName = workbook.SheetNames[0];const worksheet = workbook.Sheets[sheetName];const rows = XLSX.utils.sheet_to_json(worksheet, {header: 1,raw: false, // 保留原始值(字符串)});};// 处理文件读取错误reader.onerror = (error) => {reject(error);};});
2. 识别子表格边界

通过空行(元素全为 undefined 或空字符串)分隔子表格,记录每个子表格的起始行和结束行:

// 存储所有子表格的范围:{ start: 行索引, end: 行索引 }
const tableRanges = [];
let currentStart = null;// 遍历所有行,识别子表格边界
for (let i = 0; i < rows.length; i++) {const row = rows[i];// 判断是否为空行(过滤全空或仅含空字符串的行)const isEmptyRow = row.every(cell => cell === undefined || cell === null || cell === '');if (!isEmptyRow) {// 非空行:若未记录起始行,则标记为子表格开始if (currentStart === null) {currentStart = i;}} else {// 空行:若已记录起始行,则标记为子表格结束if (currentStart !== null) {tableRanges.push({ start: currentStart, end: i - 1 });currentStart = null;}}
}// 处理最后一个子表格(若文件末尾无空行)
if (currentStart !== null) {tableRanges.push({ start: currentStart, end: rows.length - 1 });
}
3. 提取子表格数据并转换为 JSON

假设每个子表格的第一行为表头,后续为数据行:

// 存储最终结果:键为子表格索引,值为数据数组// 存储最终结果:键为子表格索引,值为数据数组const result = [];tableRanges.forEach((range, tableIndex) => {const { start, end } = range;// 表头行(子表格起始行)const headers = rows[start].filter(cell => cell !== undefined && cell !== ''); // 过滤空单元格// 数据行(从表头下一行到结束行)const tableData = [];for (let i = start + 1; i <= end; i++) {const row = rows[i];const rowData = {};// 映射表头与数据(忽略超出表头列数的单元格)headers.forEach((header, colIndex) => {rowData[header] = row[colIndex] || ''; // 空单元格用空字符串代替});tableData.push(rowData);}tableData.forEach(rowData => {if (rowData.newServer) {}});let data = transformServers(tableData)if (Object.keys(data).length) {result.push(data)}});

三、关键处理说明

1. 边界识别优化

若子表格通过特定标题(如 “表格 1 开始”)分隔,可修改空行判断逻辑,例如:

// 假设子表格以 "表格x" 开头
const isTableHeader = row[0]?.startsWith('表格');
if (isTableHeader) { /* 标记子表格开始 */ }
  1. 合并单元格处理
    若存在合并单元格,xlsx 会仅在合并区域的首个单元格保留值,其他为 undefined。可通过以下方式填充合并单元格数据:
// 先获取合并单元格信息
const merges = worksheet['!merges'] || [];
// 遍历合并区域,复制首个单元格的值到其他位置
merges.forEach(merge => {const { s, e } = merge; // s: 起始行/列, e: 结束行/列const value = rows[s.r][s.c];for (let r = s.r; r <= e.r; r++) {for (let c = s.c; c <= e.c; c++) {rows[r][c] = value;}}
});

数据类型转换

默认输出为字符串,可根据需求自行格式化

function transformServers(servers) {const result = {};let currentNewServer = null;let keys = Object.keys(servers[0]);for (const serverInfo of servers) {// 如果当前项有newServer值,更新当前newServerif (serverInfo[keys[3]]) {currentNewServer = serverInfo[keys[3]];// 初始化数组并添加当前serverresult[currentNewServer] = [serverInfo[keys[2]]];}// 如果当前有活跃的newServer且当前项没有newServer,添加到数组else if (currentNewServer) {result[currentNewServer].push(serverInfo[keys[2]]);}}return result;
}

四、页面代码部分

<template>
<el-dialogtitle="提示":visible.sync="dialogVisible"width="500":before-close="handleClose"><el-uploadclass="upload-demo"dragaction="''":multiple="false":auto-upload="false":file-list="fileList":on-change="handleChange":on-remove="beforeUpload"ref="upload":limit="1"accept=".xlsx,.xls"><i class="el-icon-upload"></i><div class="el-upload__text"><div>将文件拖到此处,或<em>点击上传</em></div><div class="el-upload__tip">上传excel文件,请勿超过5M,每次最多只能上传1个文件</div></div></el-upload><span slot="footer" class="dialog-footer"><el-button type="primary" @click="toJson">tojson</el-button><el-button @click="dialogVisible = false">取 消</el-button><el-button type="primary" @click="dialogVisible = false">确 定</el-button></span>
</el-dialog>
</template>
<script>import {excelToJson} from '../../../utils/excel2json'export default {data() {return {dialogVisible: false,fileList: [],};},methods: { handleChange(file, fileList){console.log(fileList,file,'---');this.fileList = fileList; },beforeUpload(file,fileList){console.log(fileList,'--');this.fileList = fileList; },handleClose(done) {this.$confirm('确认关闭?').then(_ => {done();}).catch(_ => {});},toJson(){console.log(this.fileList);excelToJson(this.fileList[0].raw)}},};
</script>
<style lang="scss">
.upload-demo{
.el-upload {width:100%;
}
.el-upload-dragger{width:100%;
}width:100%;
}
</style>
五、总结

通过上述步骤,可实现对嵌套规律表格的解析:

读取 Excel 并转换为行数组;
根据空行或特定标识识别子表格范围;
提取每个子表格的表头和数据,映射为 JSON 对象;
按需处理合并单元格和数据类型。
根据实际 Excel 结构,只需调整边界识别逻辑和表头映射规则即可适配不同场景。

http://www.xdnf.cn/news/1286515.html

相关文章:

  • 正则表达式解析(二)
  • Python 标准库模块shutil
  • 升级 Docker,避免执行 docker compose 时报错
  • Java 大视界 -- Java 大数据在智能教育学习效果评估指标体系构建与精准评估中的应用(394)
  • 实现一个二维码让 iOS 和 Android 用户自动跳转到对应下载链接
  • MySQL——MySQL引擎层BufferPool工作过程原理
  • 3 Abp 核心框架(Core Framework)
  • 京东方 DV133FHM-NN1 FHD13.3寸 工业液晶模组技术档案
  • 在Colab上复现LoRA相关论文实验的完整指南
  • 跨设备开发不再难:HarmonyOS 分布式任务管理应用全解析
  • 人机交互:连接人类与数字世界的桥梁
  • 基于柔性管控终端的新能源汽车充电站有序充电系统设计与实现
  • Docker容器部署论坛和网上商城(小白的“升级打怪”成长之路)
  • 1 JQ6500语音播报模块详解(STM32)
  • 电机极数2极、4极、6极、8极的区别
  • 电子电路原理学习笔记---第5章特殊用途二极管---第2天
  • PaddlePaddle 模型训练技巧
  • Myqsl建立库表练习
  • Spark on K8s 在vivo大数据平台的混部实战
  • Go 语言 里 `var`、`make`、`new`、`:=` 的区别
  • 深入解析ArrayList与LinkedList的区别:如何正确选择?
  • 游戏中角色持枪:玩家操控角色,角色转向时枪也要转向
  • Java集合学习之forEach()遍历方法的底层原理
  • 【Unity3D实例-功能-下蹲】角色下蹲(二)穿越隧道
  • 人工智能+虚拟仿真,助推医学检查技术理论与实践结合
  • Linux环境gitlab多种部署方式及具体使用
  • [论文阅读] (41)JISA24 物联网环境下基于少样本学习的攻击流量分类
  • 完整多端口 Nginx Docker部署 + GitLab Runner注册及标签使用指南
  • 使用 NetBird 创建安全的私有网络,简化远程连接!
  • 【论文阅读】从表面肌电信号中提取神经信息用于上肢假肢控制:新兴途径与挑战