跳到主要內容

Angular Third Party : create an editable table using Handsontable


這次來介紹一個很棒的Table第三方套件Handsontable,其功能相當豐富像是編輯、排序、查詢、欄位驗證、匯出Excel等需求通通難不倒Handsontable,甚至可以直接將Excel的表格內容直接貼到Handsontable或者是將Handsontable的表格內容直接貼Excel,並且不會造成跑版和亂碼的問題。此外,前端三大主流框架(React、Angular、Vue)它都支援。

接下來,我們來簡單示範一下如何在Angular使用Handsontable。

1. 首先安裝Handsontable套件。
npm install @handsontable/angular handsontable
2. 在angular.json內匯入相關css。
"styles": [
            "node_modules/handsontable/dist/handsontable.full.css",
            "src/styles.css"
          ]
3. 匯入Handsontable Module
import { HotTableModule } from '@handsontable/angular';
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    HotTableModule,
    ...
  ]
})
export class AppModule { }
4. 使用hot-table元件且並設定settings,其常用屬性如下:
  • colHeaders : 設定欄位的表頭名稱
  • data : 設定資料
  • dataSchema : 設定資料結構
  • columns : 可用於設定欄位的型別(text、autocomplete、dropdown、checkbox、password、date)、呈現方式(renderer)以及資料驗證(validator) ※客製化的呈現方式與資料驗證需要撰寫renderer callback 與validator callback
5. 如果需要對hot-table進行存取或是DOM做操作,則需要給予hot-table一個獨特的id,並且注入HotTableRegisterer Service,以便取得hot-table instance進行存取或是DOM做操作。

<hot-table  [hotId]="this.TableId" [settings]=" this.TableSettings"></hot-table>
<input style="width: 100%;margin:10px ;" type="button" (click)="this.ShowData()" value="convert to json" />
<div style="background-color: yellow">{{this.Data|json}}</div>
import { Component, OnInit } from '@angular/core';
import { HotTableRegisterer } from '@handsontable/angular';
import * as Handsontable from 'handsontable';
import { GridSettings } from 'handsontable';
@Component({
  providers: [HotTableRegisterer],
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  Data: any[] = [];
  TableId = 'TableId';
  TableSettings: GridSettings;
  constructor(private tableReg: HotTableRegisterer) {
  }
  ngOnInit() {
    this.TableSettings = this.GetTableSettings();
  }
  ShowData(): void {
    this.Data = this.tableReg.getInstance(this.TableId).getData();
  }
  GetTableSettings(): GridSettings {
    return {
      data:[],
      contextMenu: true,
      allowInsertColumn: true,
      allowRemoveColumn: true,
      rowHeaders: true,
      minRows: 5,
      colHeaders: ['Text', 'Autocomplete', 'Dropdown', 'Checkbox', 'Numeric', 'Password', 'Date', 'Custom'],
      dataSchema: { Text: null, Autocomplete: null, Dropdown: null, Checkbox: null, Numeric: null, Password: null, Date: null, Custom: null },
      columns: [
        { data: 'Text', type: 'text' },
        { data: 'Autocomplete', type: 'autocomplete', source: ['A', 'B', 'C'] },
        { data: 'Dropdown', type: 'dropdown', source: ['A', 'B', 'C'] },
        { data: 'Checkbox', type: 'checkbox' },
        { data: 'Numeric', type: 'numeric' },
        { data: 'Password', type: 'password' },
        { data: 'Date', type: 'date' },
        { data: 'Custom', renderer: this.CustomRenderer, validator: this.EmailValidator } // 客製化Renderer、Validator
      ],
      allowEmpty: false,
      manualColumnResize: true,
      manualRowResize: true,
      manualRowMove: true,
      manualColumnMove: true,
      autoColumnSize: true,
      autoRowSize: true,
      stretchH: 'all'
    };
  }
  CustomRenderer(instance: any, td: any, row: any, col: any, prop: any, value: any, cellProperties: any): void {
    Handsontable.renderers.TextRenderer.apply(this, arguments);
    td.style.backgroundColor = 'yellow';
  }
  EmailValidator(val, callback): void {
    setTimeout(() => {
      if (/.+@.+/.test(val)) {
        callback(true);
      } else {
        callback(false);
      }
    }, 1000);
  }
}
執行結果如下所示:

留言