Handsontable使用教程 含授权码LicenseKey

目前使用的Vue做的项目,就讲下 Handsontable 在Vue中的使用吧

Installation

npm install @handsontable/vue handsontable

Basic usage

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

Render Result

Handsontable使用教程 含授权码LicenseKey_第1张图片

到这里有些小伙伴会说,诶,我这里没有获取到许可证,导致表格下面会有一行提示并且控制台警告了,那么我们就生成个 licenseKey 吧,(本文仅作为技术测试范畴,商业用途请购买正版 https://handsontable.com/pricing)

// Warning!

The license key for Handsontable is missing. Use your purchased key to activate the product. Alternatively, you can activate Handsontable to use for non-commercial purposes by passing the key: 'non-commercial-and-evaluation'. Read more about it in the documentation or contact us at [email protected].

Generate LicenseKey

  <script>
    function generateKey() {

      function random(min, max) {
        let n = max - min + 1
        return Math.ceil((Math.random() * n)) - 1 + min
      }


      function randomString(length) {
        let r = ''
        for (let i = 0; i < length; i++) {
          r += random(0, 15).toString(16)
        }
        return r
      }

      function calcFF(x) {
        /*
            计算所有可能 取一种 概率准 效率高
            当 y ∈ [0, 100)
            则 (100x + y) % 97 = 1
            y % 97 = 97 - 100x % 97 + 1
            y % 97 = 98 - 100x % 97
            y = a * 97 + (98 - 100x % 97)
            ∵ y ∈ [0, 100) , 98 - 100x % 97 ∈ [2, 98]
            ∴ 当 98 - 100x % 97 <= 2 时 a ∈ [0, 1]
               当 98 > 98 - 100x % 97 > 2 时 a = 0
               当 98 - 100x % 97 = 98 时 a ∈ [-1, 0]
            ∵ y  < 100
            ∴ 当 98 - 100x % 97 <= 2 的时候 y的最小值为 98 - 100x % 97
               当 98 > 98 - 100x % 97 > 2 的时候 y的最小值也为 98 - 100x % 97
               当 98 - 100x % 97 = 98 的时候 y的最小值为 1
            ∴ 当 98 > 98 - 100x % 97  的时候 y的最小值为 98 - 100x % 97
               当 98 = 98 - 100x % 97  的时候 y的最小值为 1
            当 y ∈ [100, 255]
            则 (1000x + y) % 97 = 1
            y % 97 = 97 - 1000x % 97 + 1
            y % 97 = 98 - 1000x % 97
            y = a * 97 + (98 - 1000x % 97)
            ∵ y ∈ [100, 255] , 98 - 1000x % 97 ∈ [2, 98]
            ∴ 98 - 1000x % 97 < 3 时 a = 2
               3 <= 98 - 1000x % 97 <= 61 时 a ∈ [1, 2]
            ∵ y 的最大值肯定 > 100
            ∴ 当 98 - 1000x % 97 < 3 时 y 的最大值为 98 - 1000x % 97 + 97 * 2
               当 98 - 1000x % 97 > 61 时 y 的最大值为 98 - 1000x % 97 + 97 * 1
               当 3 <= 98 - 1000x % 97 <= 61 时 y 的最大值为 98 - 1000x % 97 + 97 * 2
            ∴ 当 98 - 1000x % 97 <= 61 时 y 的最大值为 98 - 1000x % 97 + 97 * 2
               当 98 - 1000x % 97 > 61 时 y 的最大值为 98 - 1000x % 97 + 97 * 1
        */

        let min, max, ys = [],
          y

        if (98 - 100 * x % 97 === 98) {
          min = 1
        } else {
          min = 98 - 100 * x % 97
        }

        if (98 - 1000 * x % 97 > 61) {
          max = 98 - 1000 * x % 97 + 97 * 1
        } else {
          max = 98 - 1000 * x % 97 + 97 * 2
        }

        let i = 0

        do {
          ys.push(max - i * 97)
          i++
        } while (max - i * 97 >= 100)


        if (min + 97 < 100) {
          ys.push(min + 97)
        }
        ys.push(min)

        y = ys[random(0, ys.length - 1)]

        return y.toString(16).padStart(2, '0')
      }

      function calcFF_2(x) {

        /*  
            //这个方法概率不准 因为只是简单的假设y 并没有由x推导 效率高
            若要使  0 <= y < 100  
            则 (100x + y) % 97 = 1
            y % 97 = 97 - 100x % 97 + 1
            y % 97 = 98 - 100x % 97
            y = a * 97 + (98 - 100x % 97)
            ∵ y ∈ [0, 100) , 98 - 100x % 97 ∈ [2, 98]
            ∴ 当 98 - 100x % 97 <= 2 时 a ∈ [0, 1]
               当 98 > 98 - 100x % 97 > 2 时 a = 0
               当 98 - 100x % 97 = 98 时 a ∈ [-1, 0]
            若要使 100 <= y <= 255 
            则 (1000x + y) % 97 = 1
            y % 97 = 97 - 1000x % 97 + 1
            y % 97 = 98 - 1000x % 97
            y = a * 97 + (98 - 1000x % 97)
            ∵ y ∈ [100, 255] , 98 - 1000x % 97 ∈ [2, 98]
            ∴ 98 - 1000x % 97 < 3 时 a = 2
               3 <= 98 - 1000x % 97 <= 61 时 a ∈ [1, 2]
        */

        let y = 0

        if (random(0, 255) < 100) {
          let z = 98 - 100 * x % 97
          if (z <= 2) {
            y = random(0, 1) * 97 + z
          } else if (z == 98) {
            y = random(-1, 0) * 97 + z
          } else {
            y = z
          }
        } else {
          let z = 98 - 1000 * x % 97
          if (z < 3) {
            y = 2 * 97 + z
          } else if (z > 61) {
            y = 97 + z
          } else {
            y = random(1, 2) * 97 + z
          }
        }
        return y.toString(16).padStart(2, '0')
      }

      function calcFF_3(x) {
        /*
            取所有可能一个个随机试 效率最差 但是实现最简单 效率低100倍
        */
        let arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
          27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
          53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78,
          79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103,
          104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
          125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145,
          146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166,
          167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187,
          188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208,
          209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229,
          230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250,
          251, 252, 253, 254, 255
        ]
        let y
        do {
          let i = random(0, arr.length - 1)
          y = arr.splice(i, 1)[0]
        } while (((y > 100 ? (1000 * x) : (100 * x)) + y) % 97 !== 1)
        return y.toString(16).padStart(2, '0')
      }

      function build(day = 365) {
        //根据验证需求 day需小于 45000
        //随机生成的 1-6 9-14 17-18 位 除了第二位为时间因数 其他数字可自定义 成为用户信息标识符
        for (let i = 0; i < 3; i++) {
          if (i === 0) {
            //第 1-6 位任意 第二位为时间校验码的因数
            v = randomString(6)

            //第 1-6 位与第 7-8 位 各自转成十进制再转成字符串相连转整数 需要能被97除余1

            //取 7-8 位
            v += calcFF(parseInt(v.substr(0, 6), 16))
          } else if (i === 1) {
            //第 9-14 位随机生成
            v += randomString(6)
            //第 7-14 位与第 15-16 位 各自转成十进制再转成字符串相连转整数 需要能被97除余1

            //取 15-16 位
            v += calcFF(parseInt(v.substr(6, 8), 16))
          } else {
            //第 17-18 位随机生成
            v += randomString(2)

            //第 19-23 位时间校验码
            //当前时间戳的天数 + 有效天数 乘以第2位校验因数 如果为0 就乘以9 转16进制
            let n = (parseInt((new Date()) / 8.64e7) + day) * (parseInt(v.substr(1, 1), 16) || 9)
            if (n > parseInt('fffff', 16)) {
              //如果时间校验码超过五位 为错误
              //理论上不可能 就算有效期至100年以后因数取最大都不会超过这个数
              return ""
            }
            v += n.toString(16).padStart(5, '0')

            //第 15-23 位与第 24-25 位各自转成十进制再转成字符串相连转整数 需要能被97除余1

            //取 24-25 位
            v += calcFF(parseInt(v.substr(14, 9), 16))
          }
        }
        let r = []
        for (let i = 0; i < 5; i++) {
          r.push(v.substr(i * 5, 5))
        }
        return r.join('-')
      }

      function _checkKeySchema(v) {
        //验证有效性
        let p = 0;
        if (v.length !== 25) {
          return false;
        }
        for (let item of [
            [0, 6, 6],
            [6, 8, 14],
            [14, 9, 23]
          ]) {
          if (parseInt(parseInt(v.substr(item[0], item[1]), 16) + String(parseInt(v.substr(item[2], 2), 16)).padStart(
              2, '0')) % 97 !== 1) {

            return false
          }
        }
        return true
      }

      function _extractTime(v) {
        //获取有效期时间戳
        return parseInt(v.substr(18, 5), 16) / (parseInt(v.substr(1, 1), 16) || 9)
      }

      function vaild(k) {
        //验证函数
        let v = k.replace(/\-/g, '')
        let keyGenTime = _extractTime(v)
        if (keyGenTime > 45000 || keyGenTime !== parseInt(keyGenTime, 10)) {
          return false
        }
        let releaseTime = Math.floor((new Date()) / 8.64e7)
        if (releaseTime > keyGenTime + 1) {
          return false
        }
        return _checkKeySchema(v)
      }
      return build()

    }

    for (let i = 0; i < 10; i++) {
      console.log('licenseKey-' + (i + 1) + ': ', generateKey())
    }
  </script>

Demo

<template>
  <div>
    <hot-table
      :data="dataObject"
      :columns="columns"
      :stretchH="stretchH"
      :autoWrapRow="autoWrapRow"
      :width="width"
      :manualRowResize="manualRowResize"
      :manualColumnResize="manualColumnResize"
      :rowHeaders="rowHeaders"
      :colHeaders="colHeaders"
      :manualRowMove="manualRowMove"
      :manualColumnMove="manualColumnMove"
      :contextMenu="contextMenu"
      :filters="filters"
      :dropdownMenu="dropdownMenu"
      :hiddenRows="hiddenRows"
      :licenseKey="licenseKey"
    ></hot-table>
  </div>
</template>

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

export default {
  data: function() {
    return {

      dataObject: [
        {
          id: 1,
          flag: "EUR",
          currencyCode: "EUR",
          currency: "Euro",
          level: 0.9033,
          units: "EUR / USD",
          asOf: "08/19/2019",
          onedChng: 0.0026
        },
        {
          id: 2,
          flag: "JPY",
          currencyCode: "JPY",
          currency: "Japanese Yen",
          level: 124.387,
          units: "JPY / USD",
          asOf: "08/19/2019",
          onedChng: 0.0001
        },
        {
          id: 3,
          flag: "GBP",
          currencyCode: "GBP",
          currency: "Pound Sterling",
          level: 0.6396,
          units: "GBP / USD",
          asOf: "08/19/2019",
          onedChng: 0.0
        },
        {
          id: 4,
          flag: "CHF",
          currencyCode: "CHF",
          currency: "Swiss Franc",
          level: 0.9775,
          units: "CHF / USD",
          asOf: "08/19/2019",
          onedChng: 0.0008
        },
        {
          id: 5,
          flag: "CAD",
          currencyCode: "CAD",
          currency: "Canadian Dollar",
          level: 1.3097,
          units: "CAD / USD",
          asOf: "08/19/2019",
          onedChng: -0.0005
        },
        {
          id: 6,
          flag: "AUD",
          currencyCode: "AUD",
          currency: "Australian Dollar",
          level: 1.3589,
          units: "AUD / USD",
          asOf: "08/19/2019",
          onedChng: 0.002
        },
        {
          id: 7,
          flag: "NZD",
          currencyCode: "NZD",
          currency: "New Zealand Dollar",
          level: 1.5218,
          units: "NZD / USD",
          asOf: "08/19/2019",
          onedChng: -0.0036
        },
        {
          id: 8,
          flag: "SEK",
          currencyCode: "SEK",
          currency: "Swedish Krona",
          level: 8.528,
          units: "SEK / USD",
          asOf: "08/19/2019",
          onedChng: 0.0016
        },
        {
          id: 9,
          flag: "NOK",
          currencyCode: "NOK",
          currency: "Norwegian Krone",
          level: 8.2433,
          units: "NOK / USD",
          asOf: "08/19/2019",
          onedChng: 0.0008
        },
        {
          id: 10,
          flag: "BRL",
          currencyCode: "BRL",
          currency: "Brazilian Real",
          level: 3.4806,
          units: "BRL / USD",
          asOf: "08/19/2019",
          onedChng: -0.0009
        },
        {
          id: 11,
          flag: "CNY",
          currencyCode: "CNY",
          currency: "Chinese Yuan",
          level: 6.3961,
          units: "CNY / USD",
          asOf: "08/19/2019",
          onedChng: 0.0004
        },
        {
          id: 12,
          flag: "RUB",
          currencyCode: "RUB",
          currency: "Russian Rouble",
          level: 65.598,
          units: "RUB / USD",
          asOf: "08/19/2019",
          onedChng: 0.0059
        },
        {
          id: 13,
          flag: "INR",
          currencyCode: "INR",
          currency: "Indian Rupee",
          level: 65.3724,
          units: "INR / USD",
          asOf: "08/19/2019",
          onedChng: 0.0026
        },
        {
          id: 14,
          flag: "TRY",
          currencyCode: "TRY",
          currency: "New Turkish Lira",
          level: 2.8689,
          units: "TRY / USD",
          asOf: "08/19/2019",
          onedChng: 0.0092
        },
        {
          id: 15,
          flag: "THB",
          currencyCode: "THB",
          currency: "Thai Baht",
          level: 35.5029,
          units: "THB / USD",
          asOf: "08/19/2019",
          onedChng: 0.0044
        },
        {
          id: 16,
          flag: "IDR",
          currencyCode: "IDR",
          currency: "Indonesian Rupiah",
          level: 13.83,
          units: "IDR / USD",
          asOf: "08/19/2019",
          onedChng: -0.0009
        },
        {
          id: 17,
          flag: "MYR",
          currencyCode: "MYR",
          currency: "Malaysian Ringgit",
          level: 4.0949,
          units: "MYR / USD",
          asOf: "08/19/2019",
          onedChng: 0.001
        },
        {
          id: 18,
          flag: "MXN",
          currencyCode: "MXN",
          currency: "Mexican New Peso",
          level: 16.4309,
          units: "MXN / USD",
          asOf: "08/19/2019",
          onedChng: 0.0017
        },
        {
          id: 19,
          flag: "ARS",
          currencyCode: "ARS",
          currency: "Argentinian Peso",
          level: 9.2534,
          units: "ARS / USD",
          asOf: "08/19/2019",
          onedChng: 0.0011
        },
        {
          id: 20,
          flag: "DKK",
          currencyCode: "DKK",
          currency: "Danish Krone",
          level: 6.7417,
          units: "DKK / USD",
          asOf: "08/19/2019",
          onedChng: 0.0025
        },
        {
          id: 21,
          flag: "ILS",
          currencyCode: "ILS",
          currency: "Israeli New Sheqel",
          level: 3.8262,
          units: "ILS / USD",
          asOf: "08/19/2019",
          onedChng: 0.0084
        },
        {
          id: 22,
          flag: "PHP",
          currencyCode: "PHP",
          currency: "Philippine Peso",
          level: 46.3108,
          units: "PHP / USD",
          asOf: "08/19/2019",
          onedChng: 0.0012
        }
      ],
      currencyCodes: [
        "EUR",
        "JPY",
        "GBP",
        "CHF",
        "CAD",
        "AUD",
        "NZD",
        "SEK",
        "NOK",
        "BRL",
        "CNY",
        "RUB",
        "INR",
        "TRY",
        "THB",
        "IDR",
        "MYR",
        "MXN",
        "ARS",
        "DKK",
        "ILS",
        "PHP"
      ],
      columns: [
        {
          data: "id",
          type: "numeric",
          width: 40
        },
        {
          data: "flag",
          renderer: this.flagRenderer
        },
        {
          data: "currencyCode",
          type: "text"
        },
        {
          data: "currency",
          type: "text"
        },
        {
          data: "level",
          type: "numeric",
          numericFormat: {
            pattern: "0.0000"
          }
        },
        {
          data: "units",
          type: "text"
        },
        {
          data: "asOf",
          type: "date",
          dateFormat: "MM/DD/YYYY"
        },
        {
          data: "onedChng",
          type: "numeric",
          numericFormat: {
            pattern: "0.00%"
          }
        }
      ],

      stretchH: "all",
      width: 1366,
      autoWrapRow: true,
      height: 800,
      manualRowResize: true,
      manualColumnResize: true,
      rowHeaders: true,
      colHeaders: [
        "ID",
        "Country",
        "Code",
        "Currency",
        "Level",
        "Units",
        "Date",
        "Change"
      ],
      manualRowMove: true,
      manualColumnMove: true,
      contextMenu: true,
      filters: true,
      dropdownMenu: true,
      hiddenRows: {
      },
      licenseKey: "4d522-5237a-55f42-6653a-d1494"
    };
  },
  components: {
    HotTable
  },
  methods: {
    flagRenderer(instance, td, row, col, prop, value, cellProperties) {
      var currencyCode = value;
      while (td.firstChild) {
        td.removeChild(td.firstChild);
      }
      if (this.currencyCodes.indexOf(currencyCode) > -1) {
        var flagElement = document.createElement("DIV");
        flagElement.className = "flag " + currencyCode.toLowerCase();
        td.appendChild(flagElement);
      } else {
        var textNode = document.createTextNode(value === null ? "" : value);

        td.appendChild(textNode);
      }
    }
  }
};
</script>

<style lang="scss" scoped>
@import "../../node_modules/handsontable/dist/handsontable.full.css";
</style>

Demo Render Result

Handsontable使用教程 含授权码LicenseKey_第2张图片

文章引用

Handsontable官方网站
handsontable 授权码生成 带备注

你可能感兴趣的:(Handsontable,Handsontable,licenseKey,JavaScript)