DEV Community

Miguel MV
Miguel MV

Posted on • Edited on

Flexible Table Printing for Arrays: A Dev’s Border Toolkit

Recently, while discovering some of the magic in .NET — especially when working with lists, arrays, and practicing some LINQ magic (which I already love, especially as part of extension methods) — I found myself needing a quick way to print this data. And why not make it beautiful too?

That’s how I came up with this IEnumerable-based table printer (mainly focused on IEnumerable for now, but thinking in expanding it to support more types).

So, here we are. The main idea is to make the terminal output easier to read. To do that, we need to wrap the data inside a border, so it looks more like a table.

For the style, I started with two options:

  • Squared – with straight corners
  • Rounded – with smooth corners

So, let’s put it in a dictionary to make it easier to choose and access when setting the table style.

public static readonly Dictionary<string, dynamic> tableStyles = new Dictionary<string, dynamic>
{
    {
        "rounded", new
        {
            rightTop = '╮',
            leftTop = '╭',
            bottomLeft = '╰',
            bottomRight = '╯'
        }
    },
    {
        "squared", new
        {
            rightTop = '┐',
            leftTop = '┌',
            bottomLeft = '└',
            bottomRight = '┘'
        }
    },
    {
        "custom", new
        {
            rightTop = '+',
            leftTop = '+',
            bottomLeft = '+',
            bottomRight = '+'
        }
    }
};
Enter fullscreen mode Exit fullscreen mode

This comes inside a class, will be in the full code section,
Here a preview with the default border style:

╭---------┬------------------┬---------------╮
| StoreId | StoreName        | TotalProducts |
├---------┼------------------┼---------------┤
| 1       | Santa Cruz Bikes | 313           |
| 2       | Baldwin Bikes    | 313           |
| 3       | Rowlett Bikes    | 313           |
╰---------┴------------------┴---------------╯
Enter fullscreen mode Exit fullscreen mode

If squared wanted:

// Calling the method squared syle
BorderSyledTable(getTotalProductsByStore, "squared");
Enter fullscreen mode Exit fullscreen mode

Saying less — here’s the full code, fully commented and explained. But honestly, even without the comments, it should be pretty self-explanatory, right? After all, we named the variables like real seniors 😁😅.

Finally, here’s the full code:

public static void BorderSyledTable(IEnumerable<object> items, string style = "rounded")
{
    if (items == null || !items.Any())
    {
        Console.WriteLine("No items to print.");
        return;
    }

    var selectedStyle = tableStyles[style];

    var itemProperties = items.First().GetType().GetProperties();

    var columnWidths = itemProperties.Select(p => p.Name.Length).ToArray();

    foreach (var item in items)
    {
        for (int i = 0; i < itemProperties.Length; i++)
        {
            // Get the value of the property and update the column width to the maximum
            var value = itemProperties[i].GetValue(item)?.ToString() ?? string.Empty;
            columnWidths[i] = Math.Max(columnWidths[i], value.Length);
        }
    }

    Console.WriteLine(selectedStyle.leftTop + string.Join("┬", columnWidths.Select(w => new string('-', w + 2))) + selectedStyle.rightTop);
    Console.WriteLine("| " + string.Join(" | ", itemProperties.Select((p, i) => p.Name.PadRight(columnWidths[i]))) + " |");
    Console.WriteLine("├" + string.Join("┼", columnWidths.Select(w => new string('-', w + 2))) + "┤");

    foreach (var item in items)
    {
        Console.WriteLine("| " + string.Join(" | ", itemProperties.Select((p, i) =>
        {
            var value = p.GetValue(item)?.ToString() ?? string.Empty;
            return value.PadRight(columnWidths[i]);
        })) + " |");
    }

    Console.WriteLine(selectedStyle.bottomLeft + string.Join("┴", columnWidths.Select(w => new string('-', w + 2))) + selectedStyle.bottomRight);
}
Enter fullscreen mode Exit fullscreen mode

What is next?

Fancier the table, maybe style the borders too, for what we should replace the '-' sections in the code and replace it with char of election.

Will keep doing the console fun, so later maybe a write about aliases for powershell so handle git cmds, run your projects will be easier, etc. 👋.

Top comments (0)