Rendering text tables with NodeJS

A recent data project required the program to emit data tables from node which could be piped to other processes. easy-table is one such package which provided a nice way to output text tables in the console.

Installation is using npm.

$ npm install easy-table

A small example code is given below.

var Table = require('easy-table')
 
var data = [
  { id: 123123, desc: 'Something awesome', price: 1000.00 },
  { id: 245452, desc: 'Very interesting book', price: 11.45},
  { id: 232323, desc: 'Yet another product', price: 555.55 }
]
 
var t = new Table
 
data.forEach(function(product) {
  t.cell('Product Id', product.id)
  t.cell('Description', product.desc)
  t.cell('Price, USD', product.price, Table.number(2))
  t.newRow()
})
 
console.log(t.toString())

The output is shown below.

Product Id  Description            Price, USD
----------  ---------------------  ----------
123123      Something awesome         1000.00
245452      Very interesting book       11.45
232323      Yet another product        555.55

The primary method which prints the table cells is the ‘.cell’ method. The signature of which is:

.cell(column, value, printer)

The first 2 parameters are self explanatory. The third parameter, printer, allows you to define how that column cell is printed or formatted. In the above example we have used the ‘Table.number(2)’ format to print the price column. So for example we can create a ‘noDecimal’ printer that return a zero decimal numeric value.

function noDecimal(val, width) {
    var str = val.toFixed(0)
    return width ? Table.padLeft(str, width) : str
  }

Which you can use as below. Rendering of the printer occurs as below in two phases. At the first phase printer is called to get the minimal width required to fit the cell content. At the second phase, printer is called again with additional width parameter to get actual string to render.

var t = new Table
 
data.forEach(function(product) {
  t.cell('Product Id', product.id)
  t.cell('Description', product.desc)
  t.cell('Price, USD', product.price, noDecimal)
  t.newRow()
})

There is also a shortcut that allows you to print the data table directly. This is useful if you do no need to do any processing of the data further in the loop.

console.log(Table.print(data))

It is possible to pass some options

Table.print(data, {
  desc: {name: 'description'}
  price: {printer: Table.number(2)}
})
id      description            price
------  ---------------------  -------
123123  Something awesome      1000.00
245452  Very interesting book    11.45
232323  Yet another product     555.55

You can sort a table by calling the ‘sort()’ method, and optionally passing in a list of column names to sort on (default uses all columns), or a custom comparator function. It is also possible to specify the sort order. For example:

t.sort(['Price, USD|des']) // will sort in descending order
t.sort(['Price, USD|asc']) // will sort in ascending order
t.sort(['Price, USD']) // sorts in ascending order by default

Easy table can also help to calculate and render totals:

t.total('Price, USD')

Which return the following:

Product Id  Description            Price, USD
----------  ---------------------  ----------
245452      Very interesting book       11.45
232323      Yet another product        555.55
123123      Something awesome         1000.00
----------  ---------------------  ----------
                                         1567

Note that total does not have a decimal part. We can remedy that by passing a printer option.

t.total('Price, USD',{
  printer:  Table.number(2)
})

Which now renders correctly.

Product Id  Description            Price, USD
----------  ---------------------  ----------
123123      Something awesome         1000.00
245452      Very interesting book       11.45
232323      Yet another product        555.55
----------  ---------------------  ----------
                                      1567.00

Leave a Reply

Your email address will not be published. Required fields are marked *