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值,更新当前newServer
        if (serverInfo[keys[3]]) {
            currentNewServer = serverInfo[keys[3]];
            // 初始化数组并添加当前server
            result[currentNewServer] = [serverInfo[keys[2]]];
        }
        // 如果当前有活跃的newServer且当前项没有newServer,添加到数组
        else if (currentNewServer) {
            result[currentNewServer].push(serverInfo[keys[2]]);
        }
    }

    return result;
}

四、页面代码部分

复制代码
<template>
<el-dialog
  title="提示"
  :visible.sync="dialogVisible"
  width="500"
  :before-close="handleClose">
    <el-upload
        class="upload-demo"
        drag
        action="''"
        :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 结构,只需调整边界识别逻辑和表头映射规则即可适配不同场景。

相关推荐
wtsolutions2 小时前
Sheet-to-Doc二维码生成功能:让文档自动化更智能
json
hhzz2 小时前
EasyPoi的核心映射工具:@Excel注解详解
java·服务器·excel·springboot·easypoi
R-sz4 小时前
如何将json行政区划导入数据库,中国行政区域数据(省市区县镇乡村五级联动)
java·数据库·json
持续前行4 小时前
vscode 中找settings.json 配置
前端·javascript·vue.js
JosieBook4 小时前
【Vue】11 Vue技术——Vue 中的事件处理详解
前端·javascript·vue.js
安逸点4 小时前
Vue项目中使用xlsx库解析Excel文件
vue.js
一只小阿乐4 小时前
vue 改变查询参数的值
前端·javascript·vue.js·路由·router·网文·未花中文网
小妖6664 小时前
excel 本地sheet往服务器上粘贴时,表格宽度没有粘过来
excel
小酒星小杜5 小时前
在AI时代下,技术人应该学会构建自己的反Demo地狱系统
前端·vue.js·ai编程
Code知行合壹5 小时前
Pinia入门
vue.js