Columnify を使って Node.js スクリプトのコンソール出力をテーブルっぽく整形する

Node.js スクリプトでコンソール出力を整形する際、最も手軽なのは console.table() だろう。

$ node -e "console.table([ { id: 1, name: 'testA' }, { id: 2, name: 'testB' } ]);"

┌─────────┬────┬─────────┐
│ (index)id │  name   │
├─────────┼────┼─────────┤
│    01'testA' │
│    12'testB' │
└─────────┴────┴─────────┘

(コンソールからコピペしただけなので、閲覧環境によっては横棒の罫線が長く見えているかもしれない。コンソール上では綺麗に見えている)

console.table() は組み込み済なので手軽ではあるが、細かな出力仕様の調整が効かないので、他にコンソール出力をテーブルっぽく整形してくれるライブラリがないか探した。すると、Columnify という npm パッケージが使いやすかったので、コレを試してみた。

目次

インストール

いつもどおり。

$ npm install --save columnify

基礎1 : 単にオブジェクトを渡してみる

const columnify = require('columnify');

console.log(columnify({
  hoge: 'HOGE value',
  fugafuga: 'FUGA value'
}));

コレを実行してみると、以下のようになる。

$ node columnify.js

KEY      VALUE
hoge     HOGE value
fugafuga FUGA value

オブジェクトを渡せば、KEYVALUE という列名で上手く表示してくれる。

基礎2 : 複数オブジェクトを持つ配列を渡してみる

次に、サンプルコードを以下のように修正してみる。

console.log(columnify([
  { id: 1, name: 'テスト 太郎', gender: 'Male' },
  { id: 99, name: 'Test', gender: 'Feale', flag: 'Administrator' }
]));

配列に、2つのオブジェクトが格納されている。idnamegender プロパティは同じだが、flag プロパティは2つ目の要素しか持っていない。このようなデータはどう表示されるかというと…。

$ node columnify.js

ID NAME        GENDER FLAG
1  テスト 太郎 Male
99 Test        Feale  Administrator

注目すべきは、テスト 太郎 のように全角文字を含んでいても列の整形が上手くできている点だ。また、flag プロパティのように一部の要素しか持っていないプロパティも上手く表示できた。

カスタマイズ色々

Columnify は出力形式を色々とカスタマイズできるので、いくつか試してみる。

列ごとの区切り線を入れてみる

列ごとの区切り線を入れるには、columnSplitter プロパティを使う。

console.log(columnify([
  { id: 1, name: 'テスト 太郎', gender: 'Male' },
  { id: 99, name: 'Test', gender: 'Feale', flag: 'Administrator' }
], {
  columnSplitter: ' | '  // ← こんな風に縦線を入れてもらう
}));
$ node columnify.js

ID | NAME        | GENDER | FLAG
1  | テスト 太郎 | Male   |
99 | Test        | Feale  | Administrator

このとおり。

値を中央揃えや右揃えにしてみる

CSS でいう text-align のように、値を中央揃えや右揃えにできる。config プロパティは列名ごとに個別の指定ができるモノ。

console.log(columnify([
  { id: 1, name: 'テスト 太郎', gender: 'Male' },
  { id: 99, name: 'Test', gender: 'Feale', flag: 'Administrator' }
], {
  columnSplitter: ' | ',
  config: {
    id: {
      align: 'right'
    },
    name: {
      align: 'center'
    }
  }
}));

ココでは id 列を右揃え、name 列を中央揃えにした。

$ node columnify.js

ID |    NAME     | GENDER | FLAG
 1 | テスト 太郎 | Male   |
99 |    Test     | Feale  | Administrator

上手く文字揃えが設定されている。

列の見出し文言を変える

列の見出しは、プロパティを大文字にしたモノが使われる。コレに固定されるのは嫌なので、見出しを自由に変えてみる。

console.log(columnify([
  { id: 1, name: 'テスト 太郎', gender: 'Male' },
  { id: 99, name: 'Test', gender: 'Feale', flag: 'Administrator' }
], {
  columnSplitter: ' | ',
  config: {
    id: {
      headingTransform: (heading) => `ユーザ ${heading.toUpperCase()}`,
      align: 'right'
    },
    name: {
      headingTransform: (heading) => '氏名',
      align: 'center'
    }
  }
}));

列ごとの設定 (config) にて、headingTransform というプロパティを定義し、そこに文字列を返す関数を用意する。仮引数 heading には、大文字に変換される前のプロパティがそのまま入っている。

{
  config: {
    id: {
      // アロー関数を省略せず書くとこのとおり
      headingTransform: (heading) => {
        return `ユーザ ${heading.toUpperCase()}`;
      }
    }
  }
}

name プロパティの方は、仮引数 heading を使わず、問答無用で '氏名' という見出しにするようにした。

結果は以下のとおり。

$ node columnify.js
ユーザ ID |    氏名     | GENDER | FLAG
        1 | テスト 太郎 | Male   |
       99 |    Test     | Feale  | Administrator

IDNAME となっていた見出し文言が ユーザ ID氏名 に変わっているのが分かるだろう。

以上

割と柔軟にカスタマイズできるので、あとは公式の README を見ながら自由にコンソール出力を整形してみよう。