notebook

都内でWEB系エンジニアやってます。

ag-GridでCSVとグリッドで出力内容を変えたい

業務で凝ったグリッドを作っていくと大体言われるのが「CSVで落としたい」ですよね

結局CSVか!なんて思ったりもするのですがあったらあったでやはり便利なものです

今回はag-gridでCSVダウンロード機能に関して

  • 公式ドキュメント

CSV Export: Core Feature of our Datagrid

www.ag-grid.com

  • 動作環境
Angular: 6.1.4
ag-grid: 18.0.1

ダウンロード自体は数行書くだけでサクッとやってくれます、便利!

  • component.ts(一部抜粋)

ボタンを用意して

<button type="button" class="btn btn-sm btn-primary" (click)="downloadCsv()">
  Download CSV
</button>
  • component.html(一部抜粋)

対応する関数でAPIを呼ぶだけです

  ngOnInit() {
    this.gridOptions = <GridOptions>{};
  }
  downloadCsv() {
    const params = {fileName: 'filename.csv'};
    this.gridOptions.api.exportDataAsCsv(params);
  }

これでグリッドに表示されている内容と同じデータがCSVとしてダウンロードできるようになります

ここまでだったらとくに難しい話ではないのでまぁ良いのですが

グリッドの中身を作り込んでたり独自のcellRendererを使っていた場合

cellのvalueとしてオブジェクトを使いたいといった要件が発生しやすいかなと思います

gridだとこういう表示のセルがあったとします

f:id:swfz:20181110074254p:plain

実際のデータはこんな感じでtrueの場合のみチェックが付きます

{hoge: true, fuga: false, piyo: true}

CSVでダウンロードしてみると当然こうなります

f:id:swfz:20181110074326p:plain

そこでproccessCellCallbackオプションを使います

上記のサンプルコードでparamsに追加します

proccessCellCallbackはコールバック関数を設定してあげれば良いと書いてあるので特定のカラムのときにオブジェクトの中身を抽出してあげれば良さそうですね

  • component.ts

一部関係ない部分もあるので(丸コピだと動かない)ご了承ください

  ngOnInit() {
    this.gridOptions = <GridOptions>{};
    this.columnDefs = [
      {
        headerName: 'スペース',
        field: 'empty',
        cellRenderer: this.linkRenderer,
        width: 100
      },
      {
        headerName: '開始日',
        field: 'startDate',
        width: 120,
        editable: true
      },
      {
        headerName: 'check',
        field: 'check',
        width: 120,
        cellRenderer: this.checkRenderer
      }
    ];

    this.rowData = [
      {
        startDate: '2018-08-01',
        check: { hoge: true, fuga: false, piyo: true }
      },
      {
        startDate: '2018-08-02',
        check: { hoge: false, fuga: false, piyo: true }
      }
    ];
  }

  private checkRenderer(params) {
    const value = params.value;
    return Object.keys(params.value)
      .map(_ => {
        const iconClass = value[_] ? 'check-square-o' : 'square-o';
        return `<i class="fa fa-${iconClass}"></i>`;
      })
      .join('');
  }

  downloadCsv() {
    const params = {
      fileName: 'sample.csv',
      processCellCallback: params => {
        if (params.column.colDef.field === 'check') {
          return Object.keys(params.value)
            .map(_ => `${_}: ${params.value[_]}`)
            .join(',');
        } else {
          return params.value;
        }
      }
    };
    this.gridOptions.api.exportDataAsCsv(params);
  }

checkRendererではグリッド側で表示するためのカスタムコールバック関数を記述します

ハッシュの各要素に対してtrue/falseがありtrueの場合はチェックが入ったアイコンを表示するようなHTMLを返すようなコードになっています

チェックボックス風のアイコンを表示させるためにハッシュの各要素に対して選択済みかどうかといった感じの表現をしています

f:id:swfz:20181110074254p:plain

表示はこのようになります

downloadCsvではCSVダウンロードのAPIへ渡すオプションにprocessCellCallbackを記述します

オブジェクトの内容をよしなにして文字列にしています

CSVダウンロードをしてみるとこうなります

f:id:swfz:20181110074401p:plain

これで表示もリッチに、CSVでもしっかり表示させることができるようになりました

感想

ag-Grid. やりたいことはほぼできる!というくらい高機能ですね

ただなんでもできるもののコールバック関数を渡す系のオプションはすべてのセルの描画時に呼ばれることが多く毎度対応の対象かどうかのチェックをしなくてはならないのでうーん。。。ってなることが多いです

特別対応のカラムが増えるたびに分岐が増えていくので悩ましいです。。。

ここらへんはなにかいい方法がないか模索中です

まだまだag-Gridにはお世話になりそうです