将excel表格转换为element table(上)

53 篇文章 0 订阅
13 篇文章 0 订阅

最近有个功能需要将excel展示到html 界面里面,看是简单的一个需求也是需要费尽心思才完得成

原始数据
原始文件

想要把excel 读取出来,于是使用xlsl的插件

npm i xlsx

哔哩哔哩使用介绍 https://b23.tv/KJ3PUgH

通过插件可以获取到已经分析好的数据
在这里插入图片描述

然后使用sheet_to_html将数据转换为html 再使用v-html加载数据

<div v-html="rowsHtml"
       class="continertable"></div>

预览效果
预览

由于行列内容太多看起来有些乱,这效果的确不是想要的,于是想到了使用element ui 的table 来加载

案例
于是根据这个案例开始重新组织xlsx 加载返回的数据

首先要将数据行列重新组装

 dealTableData (worksheet) {
      // const worksheet = workbook.Sheets[sheetNames[0]];
      // 拿到这张表中表格数据的范围,
      const range = utils.decode_range(worksheet['!ref']);
      // console.log(worksheet['!ref']);  // A1:E5
      //保存数据范围数据
      const row_start = range.s.r; // 表格范围,开始行的数据
      const row_end = range.e.r; // 表格范围,结束行的数据
      const col_start = range.s.c; // 表格范围,开始列的数据
      const col_end = range.e.c; // 表格范围,结束行的数据
      const tableMerge = worksheet['!merges'] || []; // 表格中进行单元格合并操作的数据
      var oo = [];
      var tableArr = []; // 存储所以的td 数组
      var preamble = "<tr>"; // 转 html 时进行拼接
      // let rows = [], row_data, i, addr, cell;
      //按行对 sheet 内的数据循环
      //首先读取当前对象内的所有行数据,从开始到结束
      for (var R = row_start; R <= row_end; ++R) {
        var innerRow = []
        var innerRowJson = []
        // out.push(make_html_row(ws, r, R, o));
        // 读取列数据,开始到结束
		省略部分................

      // 组装表头
      this.assemblyTableData(tableArr);

      this.asseblyTableColumn(tableArr);
    },

再是组装行列,增加asseblyTableColumn 方法

这里由于是多级表头,所以需要一个二维数组

    // 组装一个表单类字段
    asseblyTableColumn (arr) {
      const firstArr = arr[0];
      const secondArr = arr[1];
      const thirdArr = arr[2];
      const secondChildren = []
      let thirdObj = {}
      const thirdChildren = []
      // 数组第一个为表头
      const resArr = [{
        label: firstArr[0]['name'],
        ...firstArr[0]
      }];

      thirdArr.forEach(e => {
        let propStr = e.id.match(propRegex)
        thirdChildren.push({
          label: e.name,
          prop: propStr[0],
          ...e
        })
      })
      secondArr.forEach(e => {
        let propStr = e.id.match(propRegex)
        // 包含colspan为下一个表头
        if (e.hasOwnProperty('colspan')) {
          thirdObj = {
            label: this.removeHTMLTags(e.name),
            ...e,
            children: thirdChildren,
          }
        } else {

          secondChildren.push({
            label: e.name,
            prop: propStr[0],
            ...e
          })
        }
      })
      secondChildren['children'] = [thirdObj];
      resArr[0]['children'] = secondChildren;
      this.tableHeadArr = resArr
    },

再增加一个重构表单数据的方法assemblyTableData

    assemblyTableData (arr) {
      this.categoryCN = [];
      /**
       * 合并信息
       * [{
       * rowNum:0,
       * colNum:0,
       * rowspan:0,
       * colspan:0,
       * }]
       */
      const spInfo = [];
      this.resTableData = [];
      // 从第三一个开始
      for (let i = 3; i < arr.length; i++) {
        let eachObj = {}
        let rowcolObj = {}
        arr[i].forEach(e => {
          let propStr = e.id.match(propRegex)
          eachObj[propStr[0]] = this.removeHTMLTags(e.name);
          const colName = propStr[0].match(/\w$/)[0];
          const rowNum = e.id.match(rowNumRegex)[0]

          if (e.hasOwnProperty('rowspan') && e.hasOwnProperty('colspan')) {
            spInfo.push({
              rowspan: e['rowspan'],
              colspan: e['colspan'],
              rowNum,
              colNum: colNumArr.findIndex(e => e === colName)
            })
          } else if (e.hasOwnProperty('rowspan')) {
            spInfo.push({
              rowspan: e['rowspan'],
              rowNum,
              colNum: colNumArr.findIndex(e => e === colName)
            })
          } else if (e.hasOwnProperty('colspan')) {
            spInfo.push({
              colspan: e['colspan'],
              rowNum,
              colNum: colNumArr.findIndex(e => e === colName)
            })
          }

        })
        this.resTableData.push(eachObj)
      }
      const categoryCN = this.categoryCN;
      // 根据colNum进行分组,便于合并
      spInfo.forEach(cn => {
        if (categoryCN[cn.colNum]) {
          categoryCN[cn.colNum].push(cn)
        } else {
          categoryCN[cn.colNum] = [cn];
        }
      })
省略部分......

    },

最后效果

效果
看起来是要好很多了,接下来就是进行行列合并的操作了

待续…

要将Vue 3中的el-table导出为Excel,你可以使用以下步骤: 1. 首先,你需要安装`xlsx`和`file-saver`包。在终端中运行以下命令: ``` npm install xlsx file-saver ``` 2. 在你的Vue组件中,导入所需的库: ```javascript import XLSX from 'xlsx'; import { saveAs } from 'file-saver'; ``` 3. 创建一个方法来导出表格数据为Excel文件: ```javascript exportData() { // 获取表格数据 const tableData = this.$refs.table.data; // 创建一个工作簿 const workbook = XLSX.utils.book_new(); // 创建一个工作表 const worksheet = XLSX.utils.json_to_sheet(tableData); // 将工作表添加到工作簿中 XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1'); // 将工作簿转换Excel文件的二进制数据 const excelData = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' }); // 创建一个Blob对象,并保存为Excel文件 const blob = new Blob([excelData], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); saveAs(blob, 'table_data.xlsx'); } ``` 4. 在el-table组件上添加一个导出按钮,并调用`exportData`方法: ```html <el-table ref="table"> <!-- 表格内容 --> </el-table> <el-button @click="exportData">导出为Excel</el-button> ``` 以上代码将会将el-table中的数据导出为名为`table_data.xlsx`的Excel文件。请确保在`<el-table>`标签上设置了ref属性,以便在`exportData`方法中引用表格数据。 这是使用Vue 3和Element Plus的示例,如果你在项目中使用了其他UI库或版本,请相应地调整代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔跑的痕迹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值