当前位置: 首页 > 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.dtcms.com/a/327524.html

相关文章:

  • 【CV 目标检测】②——NMS(非极大值抑制)
  • springboot+JPA
  • 卓伊凡谈AI编程:历史、现状与未来展望-以前面向搜索引擎现在面向AI机器人-优雅草卓伊凡
  • 解释 Spring MVC 的工作原理
  • web应用服务器——Tomcat
  • C语言中关于普通变量和指针变量、结构体包含子结构体或包含结构体指针的一些思考
  • 车载5G加速,扩产+毛利率保卫战
  • 随身WIFI每个月需要交钱吗?流量卡还是随身WIFI哪个更好用?正规随身WIFI品牌有哪些?谁才是真性价比之王?
  • Linux下命名管道和共享内存
  • 云原生作业(nginx)
  • 云原生环境Prometheus企业级监控实战
  • 将黑客拒之物联网网络之外的竞赛
  • 2.Ansible基本使用
  • 9. React组件生命周期
  • 使用镜像网站 打开克隆 GitHub 网站仓库内容 git clone https://github.com/
  • 跟李沐动手学深度学习---学习笔记之基础篇
  • ForceVLA——将具备力感知的MoE整合进π0的动作专家中:从而融合视觉、语言、力反馈三者实现精密插拔
  • 【USRP】基于LabVIEW的BPSK、QPSK,文本,图片
  • n8n、Workflow实战
  • Redis序列化配置类
  • 【从零开始java学习|第四篇】IntelliJ IDEA 入门指南
  • 采暖管道安装、分类、计量-文字查找快速定位、批量测量一键计算
  • OBOO鸥柏丨智能会议平板教学查询一体机交互式触摸终端招标投标核心标底参数要求
  • 115-基于Flask的医疗保健数据预测分析系统
  • 2025年渗透测试面试题总结-15(题目+回答)
  • 【前端Vue】如何优雅地展示带行号的日志文件或文本内容(log-viewer组件的使用)
  • Java数据结构之ArrayList
  • 《算法导论》第 20 章 - van Emde Boas 树
  • 《前端性能监控深解:从指标捕获到数据洞察的完整脉络》
  • Windows已经安装了一个MySQL8,通过修改配置文件的端口号跑2个或多个Mysql服务方法,并注册为系统服务