数据结构为对象数组形式的handsontable插件如何增加和删除列

782 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情

分析

handsontable插件的详细使用方法 中,我们说过如果 handsontable 插件绑定的数据结构为对象数组形式,那么表格的右键菜单栏中对于列的操作将失效。但是在项目中,我们并不能够避免不使用对象数组,所以既然不能使用菜单面板中的操作项,那么我们可以用其他的办法来达到相同的效果,通过分析 handsontable 插件的使用方式,可以知道,该表格插件的实现无非就是有以下几点:

  • 绑定数据(data:对象数组形式的数据)
  • 设置表头(colHeaders)
  • 设置表格列(columns)
  • 其他的配置项

那么其实我们只需要改变 data、colHeaders、columns 就可以实现增加和删除列的操作了。

实现

HTML

页面结构渲染,在这里主要增加了“新增列”和“删除列”两个按钮来实现我们要的功能。

<template>
  <div class="app-container">
    <div style="margin-bottom: 10px">
      <el-button size="small" type="success" @click="addCombVaribles">新增列</el-button>
      <el-select
        v-model="selectedColumn"
        placeholder="请选择"
        style="width: 15%; margin: 0 10px"
      >
        <el-option
          v-for="(option_item, i) in hotSettings.colHeaders"
          :key="i"
          :label="option_item"
          :value="option_item"
          :disabled="i === 0 ? true : false"
        />
      </el-select>
      <el-button
        size="small"
        type="danger"
        :disabled="selectedColumn === '' ? true : false"
        @click="removeCombVaribles"
        >删除列</el-button>
    </div>

    <HotTable ref="hotTableComponent2" :settings="hotSettings" />
  </div>
</template>

JS

js中的操作主要有以下几点:

  • 引入插件资源(import)
  • 注册插件组件(components)
  • 插件需渲染的数据(excelData2)
  • 下拉框选中的需要删除的列名(selectedColumn)
  • 插件配置项(hotSettings)
  • 数据初始化加载(created)
  • 增加列功能实现的方法(addCombVaribles)
  • 删除列功能实现的方法(removeCombVaribles)
<script>
import { HotTable } from "@handsontable/vue";
import Handsontable from 'handsontable'
import "handsontable/languages"; // 语言设置
import "../../../../node_modules/handsontable/dist/handsontable.full.css"; // 样式

export default {
  name: "App",
  components: {
    HotTable,
  },
  data() {
    return {
      selectedColumn: "",
      excelData2: [
        {
          column0: 1,
          column1: "EUR",
          column2: "Euro",
          column3: 0.9033,
          column4: "EUR / USD",
          column5: "08/19/2019",
          column6: 0.0026,
        },
        {
          column0: 2,
          column1: "JPY",
          column2: "Japanese Yen",
          column3: 124.387,
          column4: "JPY / USD",
          column5: "08/19/2019",
          column6: 0.0001,
        },
        {
          column0: 3,
          column1: "GBP",
          column2: "Pound Sterling",
          column3: 0.6396,
          column4: "GBP / USD",
          column5: "08/19/2019",
          column6: 0.0,
        },
      ],
      hotSettings: {
        language: 'zh-CN', // 语言设置
        licenseKey: 'non-commercial-and-evaluation', // 隐藏版权文字
        width: 'auto', // 表格宽度
        height: '400', // 表格高度、设置以后才会出现scroll
        data: [],
        startRows: 1, // 初始化行数,无data属性时生效(该值小于minRows时,以minRows为准)
        startCols: 2, // 初始化列数,无data属性时生效(该值小于minCols时,以minCols为准)
        minRows: 1, // 最少行数(当初始化数据小于该值时,以该值为准)
        minCols: 2, // 最少列数(当初始化数据小于该值时,以该值为准)
        minSpareCols: 0, // 列的最小留白数
        minSpareRows: 0, // 行的最小留白数
        colHeaders: [
          "column0",
          "column1",
          "column2",
          "column3",
          "column4",
          "column5",
          "column6",
        ], // 是否展示列表头,默认是A,B,C等字母,可以['列1','列2']进行自定义展示
        rowHeaders: true, // 是否展示行表头,默认是1,2,3等数据,可以['行1','行2']进行自定义展示
        columns: [
          {
            data: "column0",
          },
          {
            data: "column1",
          },
          {
            data: "column2",
          },
          {
            data: "column3",
          },
          {
            data: "column4",
          },
          {
            data: "column5",
          },
          {
            data: "column6",
          },
        ],
        // colWidths: 205, // 列宽度
        stretchH: 'all', // 自适应列宽,默认值none,last 将最后一列拉伸到最大,all 将所有列均匀拉伸
        dropdownMenu: false, // 表头展示下拉菜单,可以自定义展示
        className: 'htCenter', // 单元格文字对齐方式(htLeft,htRight,htCenter)
        currentRowClassName: 'my-selectRow', // 给选中行添加自定义class类名
        currentColClassName: 'my-selectCol', // 给选中列添加自定义class类名
        autoWrapRow: true, // 文字是否自动换行(当没有设置colWidths时生效)
        fixedRowsTop: 0, // 列表内容从上面开始,固定定位的行数(不包含行表头)
        fixedColumnsLeft: 1, // 列表内容从左面开始,固定定位的列数(不包含列表头)
        fillHandle: true, // 是否开启拖拽复制操作(true,false,'horizontal'水平复制,'vertical'垂直复制)
        trimWhitespace: true, // 过滤掉空格
        contextMenu: { // 单元格右击展示菜单
          items: {
            col_left: {
              name: '左侧插入一列'
            },
            col_right: {
              name: '右侧插入一列'
            },
            remove_col: {
              name: '移除本列'
            },
            alignment: {
              name: '对齐方式'
            },
            make_read_only: {
              name: '只读'
            },
            copy: {
              name: '复制'
            },
            cut: {
              name: '剪切'
            },
            separator: Handsontable.plugins.ContextMenu.SEPARATOR,
            clear_custom: {
              name: '清空所有单元格数据',
              callback: function() {
                this.clear()
              }
            }
          }
        }
      },
    };
  },
  created() {
    // 所有 Dom 渲染完才能拿到ref组件里的属性
    this.$nextTick(function() {
      this.$refs.hotTableComponent2.hotInstance.loadData(this.excelData2)
    })
  },
  methods: {
    addCombVaribles() {
      var excelData1 = this.$refs.hotTableComponent2.hotInstance.getData();
      var num = Number(this.hotSettings.colHeaders[this.hotSettings.colHeaders.length - 1].replace("column", "")) + 1;
      this.hotSettings.colHeaders.push("column" + num);
      this.hotSettings.columns.push({
        data: "column" + num,
      });

      var excelData2 = [];
      for (var i = 0; i < excelData1.length; i++) {
        excelData2.push({});
        for (var index in this.hotSettings.colHeaders) {
          if (Number(index) < excelData1[i].length) {
            excelData2[i][this.hotSettings.colHeaders[index]] = excelData1[i][index];
          } else {
            excelData2[i][this.hotSettings.colHeaders[index]] = null;
          }
        }
      }

      // 所有 Dom 渲染完才能拿到ref组件里的属性
      this.$nextTick(function () {
        this.$refs.hotTableComponent2.hotInstance.loadData(excelData2);
      });
    },
    removeCombVaribles() {
      var excelData1 = this.$refs.hotTableComponent2.hotInstance.getData();
      this.hotSettings.colHeaders.splice(this.hotSettings.colHeaders.indexOf(this.selectedColumn), 1);

      for (var index1 in this.hotSettings.columns) {
        if (this.hotSettings.columns[index1]["data"] === this.selectedColumn) {
          this.hotSettings.columns.splice(index1, 1);
          for (var i = 0; i < excelData1.length; i++) {
            excelData1[i].splice(index1, 1);
          }
          break;
        }
      }

      var excelData2 = [];
      for (var j = 0; j < excelData1.length; j++) {
        excelData2.push({});
        for (var index in this.hotSettings.colHeaders) {
          excelData2[j][this.hotSettings.colHeaders[index]] = excelData1[j][index];
        }
      }

      // 所有 Dom 渲染完才能拿到ref组件里的属性
      this.$nextTick(function () {
        this.$refs.hotTableComponent2.hotInstance.loadData(excelData2);
      });
      this.selectedColumn = "";
    },    
  },
};
</script>

效果展示

1.gif