Vue + Flask 小知识(二)

2019-07-17 17:35:09 浏览数 (1)

今天继续分享 Vue.js 学习笔记,结合 handsontable。

前面基础的如何使用 Flask VUE 搭建环境,可以戳这里查看。

Vue Flask 小知识(一)传送门

Handsontable

Handsontable 是一个网页版的类 excel 工具,其强大的地方已经不言而喻了。我们来看看官网上的几个例子: 漂亮的布局:

支持右键:

支持下拉菜单:

与 Vue 结合

Handsontable 官方提供了 Vue 支持的版本,安装使用也很简单。 安装

代码语言:javascript复制
npm install handsontable @handsontable/vue

基本使用

代码语言:javascript复制
<template>
  <hot-table :data="data" rowHeaders="true" colHeaders="true"></hot-table>
</template>

<script>
  import { HotTable } from '@handsontable/vue';

  export default {
    data: function() {
      return {
        data: [
          ["", "Ford", "Volvo", "Toyota", "Honda"],
          ["2016", 10, 11, 12, 13],
          ["2017", 20, 11, 14, 13],
          ["2018", 30, 15, 12, 13]
        ],
      };
    },
    components: {
      HotTable
    }
  }
</script>

<style src="../node_modules/handsontable/dist/handsontable.full.css"></style>

这样,就把 Handsontable 与 Vue 框架结合到一起了。 下面我们做一些不一样的,从本地 excel 导入数据,在线编辑,最后再下载到本地

导入本地 excel 数据

页面布局

template 文件

代码语言:javascript复制
<template>
  <div id="hot-preview">
          <div class="controls">
          <input accept=".xlsx" id="pop_file" type="file" value="选择模板" @change="impt(this)" />
          <el-button type="primary" name="save" id="save" class="intext-btn" v-on:click="save()">Save</el-button>
          <el-button type="primary" id="download" name="download" v-on:click="down()" class="intext-btn">Download</el-button>
        </div>
    <HotTable :root="root" ref="testHot" :settings="hotSettings" id="hottable"></HotTable>
  </div>
</template>

布局效果:

对于 save 的处理,我的设想是保存到后台数据库中,暂时还未实现,就留到下次的分享了。

script 脚本

代码语言:javascript复制
<script>
  import { HotTable } from '@handsontable/vue'
    import Handsontable from 'handsontable';
    import utl from '../../utils/utl'
    import xHred from '../../utils/header'

  export default {
    data: function() {
      return {
        root: 'test-hot',
        hotSettings: {
          // data: [['sample', 'data']],
          data: [        //数据可以是二维数组,也可以是数组对象                
          ],

          minRows: 1,  //最小行列

          minCols: 5,

          rowHeaders: true,//行表头,可以使布尔值(行序号),可以使字符串(左侧行表头相同显示内容,可以解析html),也可以是数组(左侧行表头单独显示内容)。

          colHeaders:   [ 'ID','账号', '用户名', '爱好', '能力', '频率','颜值',],//自定义列表头or 布尔值
          autoWrapRow: true, //自动换行
          contextMenu:{
            items:{
                "row_above": {
                  name:'上方插入一行'
                },
                "row_below": {
                  name:'下方插入一行'
                },
                "col_left": {
                  name:'左方插入列'
                },
                "col_right": {
                  name:'右方插入列'
                },
                "hsep1": "---------", //提供分隔线
                "remove_row": {
                  name: '删除行',
                },
                "remove_col": {
                  name: '删除列',
                },
                "make_read_only": {
                  name: '只读',
                },
                "borders":{
                  name:'表格线'
                },
                "copy":{
                  name:'复制'
                },
                "cut":{
                  name:'剪切'
                },
                "commentsAddEdit": {
                  name: '添加备注',
                },
                "commentsRemove": {
                  name: '取消备注',
                },
                "freeze_column": {
                  name: '固定列',
                },
                "unfreeze_column": {
                  name: '取消列固定',
                },
                "hsep2": "---------",
            }
          },
          manualColumnFreeze: true, //手动固定列  ?
          manualColumnMove: true, //手动移动列
          manualRowMove: true,   //手动移动行
          manualColumnResize: true,//手工更改列距
          manualRowResize: true,//手动更改行距
          comments: true, //添加注释  ?
          cell: [  
            {row: 1, col: 1, comment: {value: 'this is test'}},
          ],
          customBorders:[],//添加边框
          columnSorting: true,//排序
                    sortIndicator: true,
                    autoColumnSize: true,
                    dropdownMenu: true,
          stretchH: 'all',//根据宽度横向扩展,last:只扩展最后一列,none:默认不扩展
          fillHandle: true, //选中拖拽复制 possible values: true, false, "horizontal", "vertical"
          fixedColumnsLeft: 2,//固定左边列数
          fixedRowsTop: 2,//固定上边列数
          mergeCells: [   //合并
             // {row: 1, col: 1, rowspan: 3, colspan: 3},  //指定合并,从(1,1)开始行3列3合并成一格
             // {row: 3, col: 4, rowspan: 2, colspan: 2}
          ],
          columns: [     //添加每一列的数据类型和一些配置

            {},
        {},
        {},
        {},
        {},
        {},
            {}

          ],
        }
      };
    },
    methods:{
            // 导入数据
            impt() {
                const file = document.getElementById('pop_file');
                const hotinstance = this.$refs.testHot.hotInstance
                utl.XLSX.onImport(file, function () {
                    var rt = utl.XLSX.getSheetsByIndex();
                    rt.forEach(function (value, index, array) {
                    var myData = new Array();
                    for (var i = 0; i < array.length; i  ) {
                        var inner = [array[i]["ID"], array[i]["账号"], array[i]["用户名"]]
                        myData.push(inner);
                    }
                    hotinstance.loadData(myData);
                    });
                    });
                },
            //下载数据
            down() {
                const hotinstance = this.$refs.testHot.hotInstance
                var d = utl.Object.copyJson(hotinstance.getSourceData());
                var tmp = new Array();
                for (var i = 0; i < d.length; i  ) {
                    var inner = {ID: d[i][0], 账号: d[i][1], 用户名: d[i][2]};
                    tmp.push(inner);
                }
                tmp.unshift(utl.Object.reverse(xHred));
                utl.XLSX.onExport(tmp);
                },
    },
    components: {
      HotTable
    }
  }
</script>

<style src="../../../node_modules/handsontable/dist/handsontable.full.css"></style>

下面我们来逐步看下

首先说下 utl.js 文件,其实是在网上找的佚名大神的代码,哈哈哈,拿来即用。里面封装了对 excel 的相关操作,是核心的核心。 然后在 header.js 中,定义了表格所拥有的列

代码语言:javascript复制
const xHred = {
    "ID": "ID",
    "账号": "账号",
    "用户名": "用户名",
    "爱好": "爱好",
    "能力": "能力",
    "频率": "频率",
    "颜值": "颜值"
    };

export default xHred;

至于 hotSettings 里的内容,都是 Handsontable 官网的内容,通读官方文档很重要哦。

下面,来看看 impt 函数 首先获取到选择文件 input 控件中选择的 .xlsx 文件,然后调用 utl.js 中封装的函数 omImport,把数据导入到内存中,接着再遍历数据,再导入到 Handsontable 实例中,即页面的表格中。

对于 down,其实也差不多 把页面表格中的数据导入到内存中,然后调用 onExport 函数,导出到本地。 我们来看看导入时的效果

对于 download 就不再演示了,小伙伴儿们自行尝试下吧。

希望大家喜欢这个 Vue 系列

0 人点赞