Vue + Flask 小知识(二)

简介: 今天继续分享 Vue.js 学习笔记,结合 handsontable。前面基础的如何使用 Flask + VUE 搭建环境,可以戳这里查看。Vue + Flask 小知识(一)传送门

Handsontable



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

漂亮的布局:

image.png

支持右键:

image.png

支持下拉菜单:

image.png


与 Vue 结合


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

安装

npm install handsontable @handsontable/vue

基本使用

<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 文件

<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>

布局效果:

image.png

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

script 脚本

<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 中,定义了表格所拥有的列

const xHred = {
    "ID": "ID",
    "账号": "账号",
    "用户名": "用户名",
    "爱好": "爱好",
    "能力": "能力",
    "频率": "频率",
    "颜值": "颜值"
    };
export default xHred;

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

下面,来看看 impt 函数

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

对于 down,其实也差不多

把页面表格中的数据导入到内存中,然后调用 onExport 函数,导出到本地。

我们来看看导入时的效果

image.png

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

希望大家喜欢这个 Vue 系列

相关文章
|
4月前
|
JavaScript NoSQL 前端开发
Vue + Flask 小知识(七)
Vue + Flask 小知识(七)
|
4月前
|
JavaScript 前端开发 API
Vue + Flask 小知识(一)
Vue + Flask 小知识(一)
|
JSON JavaScript 数据格式
FLASK+VUE+axios前后端交互
FLASK+VUE+axios前后端交互
366 0
|
4月前
|
JavaScript 前端开发 API
Vue + Flask 实现单页面应用
Vue + Flask 实现单页面应用
|
4月前
|
JavaScript 前端开发 Python
Vue + Flask 小知识(六)
Vue + Flask 小知识(六)
|
4月前
|
缓存 JSON JavaScript
Vue + Flask 小知识(五)
Vue + Flask 小知识(五)
|
4月前
|
存储 JavaScript 前端开发
Vue + Flask 小知识(四)
Vue + Flask 小知识(四)
|
4月前
|
JavaScript API Python
Vue + Flask 小知识(三)
Vue + Flask 小知识(三)
|
4月前
|
JavaScript 数据库 Python
Vue + Flask 小知识(二)
Vue + Flask 小知识(二)
|
JavaScript 前端开发 Python
Vue前后端页面下载功能实现演示,Python+flask提供后台下载服务
Vue前后端页面下载功能实现演示,Python+flask提供后台下载服务
246 0