formatTable method

String formatTable(
  1. List<String> headers,
  2. List<List<String>> rows, {
  3. List<ColumnAlignment>? alignment,
  4. bool border = true,
})

Formats a table with aligned columns and optional borders.

Implementation

String formatTable(
  List<String> headers,
  List<List<String>> rows, {
  List<ColumnAlignment>? alignment,
  bool border = true,
}) {
  final colCount = headers.length;
  final widths = List<int>.filled(colCount, 0);
  for (var c = 0; c < colCount; c++) {
    widths[c] = headers[c].length;
    for (final row in rows) {
      if (c < row.length && row[c].length > widths[c]) {
        widths[c] = row[c].length;
      }
    }
  }

  String pad(String text, int width, ColumnAlignment align) {
    switch (align) {
      case ColumnAlignment.right:
        return text.padLeft(width);
      case ColumnAlignment.center:
        final total = width - text.length;
        final left = total ~/ 2;
        return ' ' * left + text + ' ' * (total - left);
      case ColumnAlignment.left:
        return text.padRight(width);
    }
  }

  final aligns = alignment ?? List.filled(colCount, ColumnAlignment.left);

  final buf = StringBuffer();
  final separator = border
      ? widths.map((w) => '─' * (w + 2)).join(border ? '┼' : '')
      : '';

  // Header row.
  final headerCells = <String>[];
  for (var c = 0; c < colCount; c++) {
    headerCells.add(' ${pad(headers[c], widths[c], aligns[c])} ');
  }
  buf.writeln(headerCells.join(border ? '│' : ' '));
  if (border) buf.writeln(separator);

  // Data rows.
  for (final row in rows) {
    final cells = <String>[];
    for (var c = 0; c < colCount; c++) {
      final val = c < row.length ? row[c] : '';
      cells.add(' ${pad(val, widths[c], aligns[c])} ');
    }
    buf.writeln(cells.join(border ? '│' : ' '));
  }
  return buf.toString().trimRight();
}