From a3f10283848486a4f50f0460d4a99397505e4bdc Mon Sep 17 00:00:00 2001 From: Bruno Van Thournout <> Date: Tue, 9 Dec 2025 16:54:06 +0100 Subject: [PATCH 1/6] Fix code examples --- ConsoleTable.Text.Examples/Program.cs | 3 ++- README.md | 21 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/ConsoleTable.Text.Examples/Program.cs b/ConsoleTable.Text.Examples/Program.cs index 2d18ed7..94213cf 100644 --- a/ConsoleTable.Text.Examples/Program.cs +++ b/ConsoleTable.Text.Examples/Program.cs @@ -78,7 +78,8 @@ private static void WriteDefaultTableWithProperties() new string[] { "Alice Cooper", "30", "New York" }, new string[] { "Bob", "25", "Los Angeles" }, new string[] { "Charlie Brown", "47", "Chicago" } - } + }, + Footers = new string[] { "Total: 3", "Total Age: 102" } }; Console.WriteLine(table.ToTable()); diff --git a/README.md b/README.md index 87903ad..5e2813f 100644 --- a/README.md +++ b/README.md @@ -282,6 +282,27 @@ Output: Total: 3 Total Age: 102 ``` +## Using only public properties +If you want just a fast and easy setup using only properties. + +```csharp +using ConsoleTable.Text; + +var table = new Table +{ + Headers = new string[] { "Name", "Age", "City" }, + Rows = new List + { + new string[] { "Alice Cooper", "30", "New York" }, + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + }, + Footers = new string[] { "Total: 3", "Total Age: 102" } +}; + +Console.WriteLine(table.ToTable()); +``` + ### Header only ```csharp From db6f782291be394b26d86dafc21eb7e437d35c41 Mon Sep 17 00:00:00 2001 From: Bruno Van Thournout <> Date: Mon, 15 Dec 2025 13:21:33 +0100 Subject: [PATCH 2/6] Add more styling to example --- ConsoleTable.Text.Examples/Program.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ConsoleTable.Text.Examples/Program.cs b/ConsoleTable.Text.Examples/Program.cs index 94213cf..44e4f1a 100644 --- a/ConsoleTable.Text.Examples/Program.cs +++ b/ConsoleTable.Text.Examples/Program.cs @@ -4,6 +4,12 @@ class Program { static void Main(string[] args) { + Console.ForegroundColor = ConsoleColor.Black; + Console.BackgroundColor = ConsoleColor.White; + Console.Clear(); + Console.WriteLine(); + Console.WriteLine(); + WriteDefaultTable(); WriteDefaultTableWithProperties(); @@ -32,8 +38,10 @@ static void Main(string[] args) WriteTableFluent(); - WriteBigTable(); + //WriteBigTable(); + Console.WriteLine(); + Console.WriteLine(); Console.Read(); } From b64fa4dfa4ffd8c28a157370bcd5ee0d2ed862cd Mon Sep 17 00:00:00 2001 From: Bruno Van Thournout <> Date: Thu, 15 Jan 2026 23:21:07 +0100 Subject: [PATCH 3/6] ShowBorders property (default true) --- ChangeLogs/2.1.0-ChangeLog.md | 44 +++++++++++++ ConsoleTable.Text.Examples/Program.cs | 32 ++++++++++ ConsoleTable.Text/ConsoleTable.Text.csproj | 2 +- ConsoleTable.Text/Table.cs | 71 +++++++++++++++------ ConsoleTable.Text/TableDrawing.cs | 1 + ConsoleTable.slnx | 1 + README.md | 54 ++++++++++++++-- Tests/ConsoleTable.Text.Tests/TableTests.cs | 35 ++++++++++ 8 files changed, 216 insertions(+), 24 deletions(-) create mode 100644 ChangeLogs/2.1.0-ChangeLog.md diff --git a/ChangeLogs/2.1.0-ChangeLog.md b/ChangeLogs/2.1.0-ChangeLog.md new file mode 100644 index 0000000..0c8ac4d --- /dev/null +++ b/ChangeLogs/2.1.0-ChangeLog.md @@ -0,0 +1,44 @@ +# V2.0.0 + +## New Properties + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `ShowBorders` | `bool` | `true` | When `false`, the table is drawn without borders for a more minimalist style | + + +```csharp +using ConsoleTable.Text; + +// Setup the table +var table = new Table +{ + ShowBorders = false +}; + +// Set headers +table.SetHeaders("Name", "Age", "City"); + +// Add rows +table.AddRow("Alice Cooper", "30", "New York"); +table.AddRows(new string[][] +{ + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } +}); + +// Set footers +table.SetFooters("Total: 3", "Total Age: 102"); + +// Display the table +Console.WriteLine(table.ToTable()); +``` + +Output: +``` + Name Age City + Alice Cooper 30 New York + Bob 25 Los Angeles + Charlie Brown 47 Chicago + Total: 3 Total Age: 102 +``` diff --git a/ConsoleTable.Text.Examples/Program.cs b/ConsoleTable.Text.Examples/Program.cs index 44e4f1a..80c0249 100644 --- a/ConsoleTable.Text.Examples/Program.cs +++ b/ConsoleTable.Text.Examples/Program.cs @@ -38,6 +38,8 @@ static void Main(string[] args) WriteTableFluent(); + WriteTableWithoutBorders(); + //WriteBigTable(); Console.WriteLine(); @@ -254,6 +256,36 @@ private static void WriteTableFluent() Console.WriteLine(); } + private static void WriteTableWithoutBorders() + { + Console.WriteLine(); + Console.WriteLine("Table without borders:"); + + // Setup the table + var table = new Table + { + ShowBorders = false + }; + + // Set headers + table.SetHeaders("Name", "Age", "City"); + + // Add rows + table.AddRow("Alice Cooper", "30", "New York"); + table.AddRows(new string[][] + { + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } + }); + + // Set footers + table.SetFooters("Total: 3", "Total Age: 102"); + + // Display the table + Console.WriteLine(table.ToTable()); + Console.WriteLine(); + } + private static void WriteBigTable() { Console.WriteLine(); diff --git a/ConsoleTable.Text/ConsoleTable.Text.csproj b/ConsoleTable.Text/ConsoleTable.Text.csproj index bb38db6..e2c001c 100644 --- a/ConsoleTable.Text/ConsoleTable.Text.csproj +++ b/ConsoleTable.Text/ConsoleTable.Text.csproj @@ -5,7 +5,7 @@ ConsoleTable.Text - 2.0.0 + 2.1.0 Bruno Van Thournout A library for creating a formatted string table with customizable headers, footers, rows and easy to use styling options. https://github.com/BrunoVT1992/ConsoleTable diff --git a/ConsoleTable.Text/Table.cs b/ConsoleTable.Text/Table.cs index 84a111c..8fcbbca 100644 --- a/ConsoleTable.Text/Table.cs +++ b/ConsoleTable.Text/Table.cs @@ -100,10 +100,10 @@ public bool HeaderTextAlignmentRight } } + private bool _rowTextAlignmentRight; /// /// Gets or sets a value indicating whether the row text is aligned to the right or left /// - private bool _rowTextAlignmentRight; public bool RowTextAlignmentRight { get => _rowTextAlignmentRight; @@ -114,10 +114,10 @@ public bool RowTextAlignmentRight } } + private bool _footerTextAlignmentRight; /// /// Gets or sets a value indicating whether the footer text is aligned to the right or left /// - private bool _footerTextAlignmentRight; public bool FooterTextAlignmentRight { get => _footerTextAlignmentRight; @@ -128,6 +128,20 @@ public bool FooterTextAlignmentRight } } + private bool _showBorders = true; + /// + /// Gets or sets a value indicating whether the table borders are visible. Default is true. + /// + public bool ShowBorders + { + get => _showBorders; + set + { + _showBorders = value; + ClearCache(); + } + } + /// /// Sets the headers of the table. Overwrites them each time. /// @@ -194,8 +208,6 @@ public Table ClearRows() return this; } - - /// /// Clears the cached generated table string /// @@ -238,10 +250,13 @@ public string ToTable() if (Headers?.Any() == true) { - formattedTable = CreateTopLine(maximumCellWidths, Headers.Count(), formattedTable); - topLineCreated = true; + if (ShowBorders) + { + formattedTable = CreateTopLine(maximumCellWidths, Headers.Count(), formattedTable); + topLineCreated = true; + } - formattedTable = CreateValueLine(maximumCellWidths, Headers, HeaderTextAlignmentRight, TableDrawing.VerticalLine, formattedTable); + formattedTable = CreateValueLine(maximumCellWidths, Headers, HeaderTextAlignmentRight, ShowBorders ? TableDrawing.VerticalLine : TableDrawing.EmptySpace, formattedTable); previousRow = Headers; @@ -249,17 +264,23 @@ public string ToTable() if (Rows?.Any() == true) { nextRow = Rows.First(); - formattedTable = CreateSeperatorLine(maximumCellWidths, previousRow.Count(), nextRow.Count(), TableDrawing.HorizontalHeaderLine, formattedTable); + if (ShowBorders) + { + formattedTable = CreateSeperatorLine(maximumCellWidths, previousRow.Count(), nextRow.Count(), TableDrawing.HorizontalHeaderLine, formattedTable); + } } else { - formattedTable = CreateBottomLine(maximumCellWidths, Headers.Count(), TableDrawing.HorizontalHeaderLine, formattedTable); + if (ShowBorders) + { + formattedTable = CreateBottomLine(maximumCellWidths, Headers.Count(), TableDrawing.HorizontalHeaderLine, formattedTable); + } } } if (Rows?.Any() == true) { - if (!topLineCreated) + if (!topLineCreated && ShowBorders) { formattedTable = CreateTopLine(maximumCellWidths, Rows.First().Count(), formattedTable); topLineCreated = true; @@ -272,7 +293,7 @@ public string ToTable() { var row = CleanupRow(Rows[i]); - formattedTable = CreateValueLine(maximumCellWidths, row, RowTextAlignmentRight, TableDrawing.VerticalLine, formattedTable); + formattedTable = CreateValueLine(maximumCellWidths, row, RowTextAlignmentRight, ShowBorders ? TableDrawing.VerticalLine : TableDrawing.EmptySpace, formattedTable); previousRow = row; @@ -280,13 +301,19 @@ public string ToTable() { nextRow = CleanupRow(Rows[rowIndex + 1]); - formattedTable = CreateSeperatorLine(maximumCellWidths, previousRow.Count(), nextRow.Count(), TableDrawing.HorizontalLine, formattedTable); + if (ShowBorders) + { + formattedTable = CreateSeperatorLine(maximumCellWidths, previousRow.Count(), nextRow.Count(), TableDrawing.HorizontalLine, formattedTable); + } } rowIndex++; } - formattedTable = CreateBottomLine(maximumCellWidths, previousRow.Count(), TableDrawing.HorizontalLine, formattedTable); + if (ShowBorders) + { + formattedTable = CreateBottomLine(maximumCellWidths, previousRow.Count(), TableDrawing.HorizontalLine, formattedTable); + } } if (Footers?.Any() == true) @@ -411,8 +438,16 @@ private StringBuilder CreateValueLine(int[] maximumCellWidths, string[] row, boo if (Padding > 0) paddingString = string.Concat(Enumerable.Repeat(' ', Padding)); - foreach (var column in row) + for (int i = 0; i < row.Length; i++) { + var column = row[i]; + + var leftVerticlaLine = verticalLine; + if (i == 0 && !ShowBorders) + { + leftVerticlaLine = TableDrawing.Empty; + } + var restWidth = maximumCellWidths[cellIndex]; if (Padding > 0) restWidth -= Padding * 2; @@ -420,13 +455,13 @@ private StringBuilder CreateValueLine(int[] maximumCellWidths, string[] row, boo var cellValue = alignRight ? column.PadLeft(restWidth, ' ') : column.PadRight(restWidth, ' '); if (cellIndex == 0 && cellIndex == lastCellIndex) - formattedTable.AppendLine(string.Format("{0}{1}{2}{3}{4}", verticalLine, paddingString, cellValue, paddingString, verticalLine)); + formattedTable.AppendLine(string.Format("{0}{1}{2}{3}{4}", leftVerticlaLine, paddingString, cellValue, paddingString, verticalLine)); else if (cellIndex == 0) - formattedTable.Append(string.Format("{0}{1}{2}{3}", verticalLine, paddingString, cellValue, paddingString)); + formattedTable.Append(string.Format("{0}{1}{2}{3}", leftVerticlaLine, paddingString, cellValue, paddingString)); else if (cellIndex == lastCellIndex) - formattedTable.AppendLine(string.Format("{0}{1}{2}{3}{4}", verticalLine, paddingString, cellValue, paddingString, verticalLine)); + formattedTable.AppendLine(string.Format("{0}{1}{2}{3}{4}", leftVerticlaLine, paddingString, cellValue, paddingString, verticalLine)); else - formattedTable.Append(string.Format("{0}{1}{2}{3}", verticalLine, paddingString, cellValue, paddingString)); + formattedTable.Append(string.Format("{0}{1}{2}{3}", leftVerticlaLine, paddingString, cellValue, paddingString)); cellIndex++; } diff --git a/ConsoleTable.Text/TableDrawing.cs b/ConsoleTable.Text/TableDrawing.cs index d729daf..c9f60d0 100644 --- a/ConsoleTable.Text/TableDrawing.cs +++ b/ConsoleTable.Text/TableDrawing.cs @@ -15,5 +15,6 @@ internal static class TableDrawing public const char HorizontalHeaderLine = '═'; public const string VerticalLine = "│"; public const string EmptySpace = " "; + public const string Empty = ""; } } \ No newline at end of file diff --git a/ConsoleTable.slnx b/ConsoleTable.slnx index b907c3e..7b05515 100644 --- a/ConsoleTable.slnx +++ b/ConsoleTable.slnx @@ -9,6 +9,7 @@ + diff --git a/README.md b/README.md index 5e2813f..71bbbaf 100644 --- a/README.md +++ b/README.md @@ -5,14 +5,14 @@ A lightweight .NET library for creating beautifully formatted console tables wit ## Features - Create formatted tables as a string with styled headers, footers and rows -- Unicode box-drawing characters for clean borders +- Unicode box-drawing characters for clean borders (borders are optional and can be disabled if you want a minimalist style) - Automatic column width calculation - Configurable cell padding - Text alignment options (left/right) for headers, footers and rows - Easy clearing and reusing of tables - Simple and intuitive API - Optimized for performance -- Support for varying column counts across rows (each row can have its own number of cells). +- Support for varying column counts across rows (each row can have its own number of cells) ## Releases Check releases for the changelog here [https://github.com/BrunoVT1992/ConsoleTable/releases/](https://github.com/BrunoVT1992/ConsoleTable/releases/) @@ -92,6 +92,7 @@ Output: | `RowTextAlignmentRight` | `bool` | `false` | When `true`, row text is right-aligned otherwise left aligned | | `FooterTextAlignmentRight` | `bool` | `false` | When `true`, footer text is right-aligned otherwise left aligned | | `CachingEnabled` | `bool` | `true` | When `true`, the generated table string is cached when the ToTable method is called. Cache will be cleared on any property change or method call. | +| `ShowBorders` | `bool` | `true` | When `false`, the table is drawn without borders for a more minimalist style | ### Methods @@ -154,7 +155,12 @@ Output: using ConsoleTable.Text; // Setup the table -var table = new Table { HeaderTextAlignmentRight = true, RowTextAlignmentRight = true, FooterTextAlignmentRight = true }; +var table = new Table +{ + HeaderTextAlignmentRight = true, + RowTextAlignmentRight = true, + FooterTextAlignmentRight = true +}; // Set headers table.SetHeaders("Name", "Age", "City"); @@ -249,13 +255,51 @@ Output: Footer 1 Footer 2 ``` +### Table without borders + +```csharp +using ConsoleTable.Text; + +// Setup the table +var table = new Table +{ + ShowBorders = false +}; + +// Set headers +table.SetHeaders("Name", "Age", "City"); + +// Add rows +table.AddRow("Alice Cooper", "30", "New York"); +table.AddRows(new string[][] +{ + new string[] { "Bob", "25", "Los Angeles" }, + new string[] { "Charlie Brown", "47", "Chicago" } +}); + +// Set footers +table.SetFooters("Total: 3", "Total Age: 102"); + +// Display the table +Console.WriteLine(table.ToTable()); +``` + +Output: +``` + Name Age City + Alice Cooper 30 New York + Bob 25 Los Angeles + Charlie Brown 47 Chicago + Total: 3 Total Age: 102 +``` + ### Write a Table Fluent ```csharp using ConsoleTable.Text; - var tableString = new Table() +var tableString = new Table() .SetHeaders("Name", "Age", "City") .AddRow("Alice Cooper", "30", "New York") .AddRows( @@ -326,7 +370,7 @@ Output: ```csharp using ConsoleTable.Text; - var table = new Table(); +var table = new Table(); for (int i = 1; i <= 5; i++) { diff --git a/Tests/ConsoleTable.Text.Tests/TableTests.cs b/Tests/ConsoleTable.Text.Tests/TableTests.cs index 25499be..1851e24 100644 --- a/Tests/ConsoleTable.Text.Tests/TableTests.cs +++ b/Tests/ConsoleTable.Text.Tests/TableTests.cs @@ -537,6 +537,41 @@ public void FooterTextAlignRight_True_AlignsToDifferentPosition() Assert.Contains("F", resultRight); Assert.NotEqual(resultLeft, resultRight); } + + [Fact] + public void ShowBorders_DefaultValue_IsTrue() + { + var table = new Table(); + + Assert.True(table.ShowBorders); + } + + [Fact] + public void ShowBorders_False_RemovesBorderCharacters() + { + var table = new Table { ShowBorders = false }; + table.SetHeaders("Name", "Age"); + table.AddRow("John", "30"); + table.AddRow("Jane", "25"); + table.SetFooters("Footer1", "Footer2"); + + var result = table.ToTable(); + + // Should NOT contain border characters + Assert.DoesNotContain("│", result); // Vertical line + Assert.DoesNotContain("─", result); // Horizontal line + Assert.DoesNotContain("├", result); // Left joint + Assert.DoesNotContain("┤", result); // Right joint + Assert.DoesNotContain("┌", result); // Top left corner + Assert.DoesNotContain("┐", result); // Top right corner + Assert.DoesNotContain("└", result); // Bottom left corner + Assert.DoesNotContain("┘", result); // Bottom right corner + Assert.DoesNotContain("┼", result); // Middle joint + + // Should still contain the actual content + Assert.Contains("Header", result); + Assert.Contains("Value", result); + } #endregion #region Cache From e1f33b9effc3570c1741f4b468b57e2b17a5dadb Mon Sep 17 00:00:00 2001 From: Bruno Van Thournout <> Date: Thu, 15 Jan 2026 23:25:00 +0100 Subject: [PATCH 4/6] Fix tests --- Tests/ConsoleTable.Text.Tests/TableTests.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Tests/ConsoleTable.Text.Tests/TableTests.cs b/Tests/ConsoleTable.Text.Tests/TableTests.cs index 1851e24..2462fb6 100644 --- a/Tests/ConsoleTable.Text.Tests/TableTests.cs +++ b/Tests/ConsoleTable.Text.Tests/TableTests.cs @@ -569,8 +569,14 @@ public void ShowBorders_False_RemovesBorderCharacters() Assert.DoesNotContain("┼", result); // Middle joint // Should still contain the actual content - Assert.Contains("Header", result); - Assert.Contains("Value", result); + Assert.Contains("Name", result); + Assert.Contains("Age", result); + Assert.Contains("John", result); + Assert.Contains("30", result); + Assert.Contains("Jane", result); + Assert.Contains("25", result); + Assert.Contains("Footer1", result); + Assert.Contains("Footer2", result); } #endregion From 1699afab5758fb6760c7d7c1a2a4dd84bf3e9147 Mon Sep 17 00:00:00 2001 From: Bruno Van Thournout <> Date: Thu, 15 Jan 2026 23:26:05 +0100 Subject: [PATCH 5/6] Fix spelling --- ConsoleTable.Text/Table.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ConsoleTable.Text/Table.cs b/ConsoleTable.Text/Table.cs index 8fcbbca..6e26810 100644 --- a/ConsoleTable.Text/Table.cs +++ b/ConsoleTable.Text/Table.cs @@ -442,10 +442,10 @@ private StringBuilder CreateValueLine(int[] maximumCellWidths, string[] row, boo { var column = row[i]; - var leftVerticlaLine = verticalLine; + var leftVerticalLine = verticalLine; if (i == 0 && !ShowBorders) { - leftVerticlaLine = TableDrawing.Empty; + leftVerticalLine = TableDrawing.Empty; } var restWidth = maximumCellWidths[cellIndex]; @@ -455,13 +455,13 @@ private StringBuilder CreateValueLine(int[] maximumCellWidths, string[] row, boo var cellValue = alignRight ? column.PadLeft(restWidth, ' ') : column.PadRight(restWidth, ' '); if (cellIndex == 0 && cellIndex == lastCellIndex) - formattedTable.AppendLine(string.Format("{0}{1}{2}{3}{4}", leftVerticlaLine, paddingString, cellValue, paddingString, verticalLine)); + formattedTable.AppendLine(string.Format("{0}{1}{2}{3}{4}", leftVerticalLine, paddingString, cellValue, paddingString, verticalLine)); else if (cellIndex == 0) - formattedTable.Append(string.Format("{0}{1}{2}{3}", leftVerticlaLine, paddingString, cellValue, paddingString)); + formattedTable.Append(string.Format("{0}{1}{2}{3}", leftVerticalLine, paddingString, cellValue, paddingString)); else if (cellIndex == lastCellIndex) - formattedTable.AppendLine(string.Format("{0}{1}{2}{3}{4}", leftVerticlaLine, paddingString, cellValue, paddingString, verticalLine)); + formattedTable.AppendLine(string.Format("{0}{1}{2}{3}{4}", leftVerticalLine, paddingString, cellValue, paddingString, verticalLine)); else - formattedTable.Append(string.Format("{0}{1}{2}{3}", leftVerticlaLine, paddingString, cellValue, paddingString)); + formattedTable.Append(string.Format("{0}{1}{2}{3}", leftVerticalLine, paddingString, cellValue, paddingString)); cellIndex++; } From 87f4ed9ef88ac36e843d36217cec8d21a5063ab1 Mon Sep 17 00:00:00 2001 From: Bruno Van Thournout <> Date: Thu, 15 Jan 2026 23:26:48 +0100 Subject: [PATCH 6/6] Fix version --- ChangeLogs/2.1.0-ChangeLog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChangeLogs/2.1.0-ChangeLog.md b/ChangeLogs/2.1.0-ChangeLog.md index 0c8ac4d..50f4579 100644 --- a/ChangeLogs/2.1.0-ChangeLog.md +++ b/ChangeLogs/2.1.0-ChangeLog.md @@ -1,4 +1,4 @@ -# V2.0.0 +# V2.1.0 ## New Properties