/**
* o------------------------------------------------------------------------------o
* | This package is dual licensed as QPL (NOT GPL) and a commercial license. |
* | If you use the code commercially (or if you don't want to be restricted by |
* | the QPL license), you will need the commercial license. It's only £49 (GBP - |
* | roughly $98 depending on the exchange rate) and helps me out a lot. Thanks. |
* o------------------------------------------------------------------------------o
*
* © Copyright Richard Heyes
*/
/**
* Usage
* =====
*
* ConsoleTable myTable = new ConsoleTable();
*
* myTable.Append(new string[] {"foo", "bar"}); // Could use a predefined string array
* myTable.Append(new string[] {"One", "Two"}); // or an ArrayList here
* myTable.Prepend(new string[] {}); // Inserts an empty row
*
* myTable.SetHeaders(new string[] {"Column 1", "Column 2"});
*
* Console.WriteLine(myTable.ToString()); // Prints the table
*/
using System;
using System.Collections;
namespace HLib
{
///
/// Handles building of Console Tables
///
public class ConsoleTable
{
#region Fields
private ArrayList headers;
private ArrayList footers;
private ArrayList data;
private int maxCols;
private int maxRows;
private ArrayList cellLengths;
private int padding;
#endregion
#region Constructor(s)
///
/// Instanciates new copy of object
///
public ConsoleTable()
{
this.headers = new ArrayList();
this.footers = new ArrayList();
this.data = new ArrayList();
this.cellLengths = new ArrayList();
this.padding = 1;
}
#endregion
#region Public instance methods
///
/// Adds headers to the table.
///
/// An IList collection of the headers
public void SetHeaders(IList headers)
{
this.headers = new ArrayList(headers);
this.UpdateRowsCols(this.headers);
}
///
/// Adds footers to the table.
///
/// An IList collection of the headers
public void SetFooters(IList footers)
{
this.footers = new ArrayList(footers);
this.UpdateRowsCols(this.footers);
}
///
/// Adds a row of data to the table.
///
/// An IList of the row data
public void AppendRow(IList rowData)
{
this.data.Add(new ArrayList(rowData));
this.UpdateRowsCols((ArrayList)this.data[this.data.Count - 1]);
}
///
/// Prepends a row of data to the table.
///
/// An IList of the row data
public void PrependRow(IList rowData)
{
this.data.Insert(0, new ArrayList(rowData));
this.UpdateRowsCols((ArrayList)this.data[0]);
}
///
/// Inser the given row data at the beginning of the table.
/// Much the same as PrependRow().
///
/// An IList of the row data
public void InsertRow(IList rowData)
{
this.InsertRow(rowData, 0);
}
///
/// Insert the given row data at the given row index.
///
/// An IList of the row data
/// Row index to insert at
public void InsertRow(IList rowData, int rowIndex)
{
while (this.data.Count < rowIndex) {
this.data.Add(new ArrayList());
}
this.data.Insert(rowIndex, new ArrayList(rowData));
this.UpdateRowsCols((ArrayList)this.data[rowIndex]);
}
public override string ToString()
{
this.ValidateTable();
return this.BuildTable();
}
#endregion
#region Private instance methods
private void ValidateTable()
{
for (int i = 0; i
/// Creates the table
///
/// The string representation of the table
private string BuildTable()
{
string[] retVal = new string[this.maxRows];
ArrayList rowData = this.data;
// Go thru every row
for (int i=0; i 0) {
returnStr = this.GetHeaderLine() + "\r\n" + returnStr;
}
// Add footers
if (this.footers.Count > 0) {
returnStr = returnStr + this.GetFooterLine() + "\r\n";
}
return returnStr;
}
///
/// Returns a string composed of a separator line
///
/// The separator line
private string GetSeparator()
{
ArrayList retVal = new ArrayList();
foreach (int width in this.cellLengths) {
retVal.Add("-".PadRight(width, '-'));
}
string rowBegin = "+" + "-".PadRight(this.padding, '-');
string rowEnd = "-".PadRight(this.padding, '-') + "+";
string implode = "-".PadRight(this.padding, '-') + "+" + "-".PadRight(this.padding, '-');
return rowBegin + String.Join(implode, (string[])retVal.ToArray(typeof(string))) + rowEnd;
}
///
/// Returns a string composed of the headers for the table
///
/// The headerline
private string GetHeaderLine()
{
for (int i=0; i
/// Returns a string composed of the footers for the table
///
/// The headerline
private string GetFooterLine()
{
for (int i=0; i
/// Updates maxrows and maxcols values
///
/// The row data to check
private void UpdateRowsCols(ArrayList rowData)
{
this.maxCols = Math.Max(this.maxCols, rowData.Count);
this.maxRows = this.data.Count;
}
///
/// Calculates the maximum cell length for each column
/// and stores it in the cellLengths array.
///
private void CalculateCellLengths(ArrayList rowData)
{
for (int i=0; i i) {
this.cellLengths[i] = Math.Max(this.headers[i].ToString().Length, (int)this.cellLengths[i]);
}
}
}
#endregion
}
}