Vue環境でJspreadsheet CEを使う

とあるWebアプリケーションをVueで作っている際に、ブラウザ上でわかりやすく表を編集する方法がないか調べました。そこで[Jspreadsheet CE](https://bossanova.uk/jspreadsheet/v4/)にたどり着きました。


いろんなフレームワークに対応していて、かつ多機能で使いやすそうだなと思いましたが、ちょっと導入で躓いたので備忘録。
大体[こちらのサンドボックス](https://codesandbox.io/embed/vue-default-template-p4hwn)と一緒。


## 導入
プロジェクト内で以下を実行  
  
~~~
npm install jspreadsheet-ce
~~~
  
使うコンポーネント内でインポートする。

~~~js
import "jsuites/dist/jsuites.js"
import "jsuites/dist/jsuites.css"
import "jspreadsheet-ce/dist/jspreadsheet.css" 
import jSpreadSheet from "jspreadsheet-ce"
~~~
旧名称が jexcelで新名称がspreadsheet-ce のようです。ところどころ旧名称がでてきて紛らわしい。上記のサンドボックスも旧名称でした。


コンポーネント全体

~~~Vue
<template>
  <div class="wrapper">
    <input
      type="button"
      value="行を追加"
      @click="jspreadsheetObj.insertRow()"
    /><br />
    <input 
      type="button" 
      value="ヘッダー一覧を取得" 
      @click="getHeaders()"
    /><br />
    <div id="HeadSetSpreadSheet" ref="refspreadsheet"></div>
    <br>
    <input 
      type="button" 
      value="csvをダウンロード" 
      @click="jspreadsheetObj.download()"
    /><br />
  </div>
</template>

<script>
import "jsuites/dist/jsuites.js"
import "jsuites/dist/jsuites.css"
import "jspreadsheet-ce/dist/jspreadsheet.css"
import jSpreadSheet from "jspreadsheet-ce"

export default {
  name: "sheet",
  data() {
    return {
        //表の初期値を入れておく
        //画像なども可能
        VRHeadSets: [
        [
          "HTC",
          "VIVE",
          "2016-12-1",
          "2160x1200",
          true
        ],
        [
          "Oculus", 
          "Rift S", 
          "2019-05-20",
          "2560×1440",
          false
        ],
        [
          "Valve", 
          "Index", 
          "2019-06-28", 
          "2880×1600",
          true
        ],
      ],
    };
  },
  computed: {
    //表の初期値
    jSpreadSheetOptins() {
      return {
        //表の設定等
        //チェックボックスやカレンダー、プルダウンメニューも可能
        data: this.VRHeadSets,
        columns: [
          {
            type: "dropdown",
            title: "Maker",
            width: "150px",
            source: ["HTC", "Oculus", "Valve"],
          },
          { type:"text", title:"Name"},
          { type: "calendar", title: "Release date", width: "250px" },
          { type: "Text", title: "Resolution", width: "250px"},
          { type: "checkbox", title: "Get?", width: "80px" },
        ],
        //INITIALIZATIONはここに書く https://bossanova.uk/jspreadsheet/v4/docs/quick-reference
      
        tableOverflow: true, // スクロールの有効化
        csvFileName: "HeadSetsData" // ダウンロード時のファイル名
        
      };
    },
  },
  methods: {
    //メソッドの使用例 https://bossanova.uk/jspreadsheet/v4/docs/programmatically-changes
    getHeaders: function() {
      alert(this.jspreadsheetObj.getHeaders());
    },
  },
  mounted: function() {
    //インスタンス化
    const jspreadsheetObj = jSpreadSheet(
     //DOM参照
      this.$refs["refspreadsheet"],
      //表の設定データ
      this.jSpreadSheetOptins
    );
    //オブジェクトから thisに対してコピー
    Object.assign(this, { jspreadsheetObj });
  },
};

</script>
~~~

オブジェクト作成の際はimport時の名前を使う。
Vueの環境でDOM直接操作のため$refsを使うので揃えておく(ソース内だと"refspreadsheet")。

## 結果
以下のような感じに。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332214/d4a6c38b-6299-bfc1-884b-8778c0d331d7.png)

ダウンロードしたcsvファイル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332214/dbb34325-d929-f6f4-06b3-9a5c7f7fac1d.png)


使ってみた感想として、操作のインターフェースとして使うものでスクリプト側から内容を操作する場合はほかの手段を併用したほうがよさそうです。表のデータを操作する場合には、ヘッダーの指定ではなく座標指定になるので使いづらく感じました。
ユーザーのインターフェースとしては細かくいろいろ設定できるのでいい感じです。