private static List <TextColumn <TColumn> > GetTextColumns <TColumn, TRow>( TableInfoProvider <TColumn, TRow> tableInfoProvider ) { var theResult = new List <TextColumn <TColumn> >(); var theColumns = tableInfoProvider.GetColumns(); int theColumnIndex = 0; foreach (TColumn theColumn in theColumns) { ColumnInfo theColumnInfo = tableInfoProvider.GetColumnInfo(theColumn, theColumnIndex); theResult.Add( new TextColumn <TColumn>(theColumnInfo.Header, theColumnIndex, theColumn, theColumnInfo.AlignRight) { SecondaryHeader = theColumnInfo.SecondaryHeader, DataType = theColumnInfo.DataType, Seperator = theColumnInfo.Seperator } ); if ((theColumnInfo.Seperator?.ColSpan ?? int.MaxValue) < 1) { throw new InvalidOperationException("ColSpan must not be lower than 1."); } theColumnIndex++; } var theRows = tableInfoProvider.GetRows(); foreach (TRow theRow in theRows) { int theColumnCount = theResult.Count; theColumnIndex = 0; for (int theIndex = 0; theIndex < theColumnCount; theIndex++) { TextColumn <TColumn> theTextColumn = theResult[theColumnIndex]; var theValue = tableInfoProvider.GetCellValue(theRow, theTextColumn.Column, theIndex); if (theValue.ColSpan < 1) { throw new InvalidOperationException("ColSpan must not be lower than 1."); } else if (theValue.ColSpan > 1) { int theRemainingColumnCount = theColumnCount - theIndex; if (theValue.ColSpan > theRemainingColumnCount) { throw new InvalidOperationException( $"ColSpan must not be greater than than the remaining column " + $"count ({theRemainingColumnCount})." ); } } theTextColumn.Rows.Add(theValue); if (theValue.ColSpan == 1) { theTextColumn.Width = Math.Max(theTextColumn.Width, theValue.CellValue.Length); } else { int theTotalWidth = theTextColumn.Width; for (int theNextIndex = theIndex + 1; theNextIndex < theIndex + theValue.ColSpan; theNextIndex++) { TextColumn <TColumn> theNextTextColumn = theResult[theNextIndex]; theNextTextColumn.Rows.Add((string.Empty, 1)); theTotalWidth += theNextTextColumn.Width; } while (theTotalWidth < theValue.CellValue.Length) { for (int theNextIndex = theIndex; theNextIndex < theIndex + theValue.ColSpan; theNextIndex++) { TextColumn <TColumn> theNextTextColumn = theResult[theNextIndex]; theNextTextColumn.Width++; theTotalWidth++; if (theTotalWidth == theValue.CellValue.Length) { break; } } } } theColumnCount -= theValue.ColSpan - 1; theColumnIndex += theValue.ColSpan; } } return(theResult); }
/// <summary>Returns a pretty-print string representation of the specified /// <paramref name="table"/> object.</summary> /// <param name="table">Table object</param> /// <param name="tableInfoProvider">Table info provider</param> /// <returns>Pretty-print string representation of the table</returns> public static string DumpTableObject <T, TColumn, TRow>( this T table, TableInfoProvider <TColumn, TRow> tableInfoProvider ) where T : class { if (table is null) { throw new ArgumentNullException(nameof(table)); } if (tableInfoProvider is null) { throw new ArgumentNullException(nameof(tableInfoProvider)); } var theResult = new StringBuilder(); List <TextColumn <TColumn> > theColumns = GetTextColumns(tableInfoProvider); string theSpaces = new string(' ', tableInfoProvider.LeadingSpaces); theResult.Append(theSpaces); int theColumnCount = theColumns.Count; if (theColumns.Any(c => c.Seperator != null)) { for (int theIndex = 0; theIndex < theColumnCount; theIndex++) { TextColumn <TColumn> theColumn = theColumns[theIndex]; ColumnSeperator?theSeperator = theColumn.Seperator; if (theSeperator != null) { int theColSpan = theSeperator.ColSpan; int theWidth; if (theColSpan == 1) { theWidth = theColumn.Width; } else { theWidth = theColumns.Skip(theIndex).Take(theColSpan).Sum(c => c.Width) + (theColSpan - 1) * 3; } var theCenteredHeader = new StringBuilder(theSeperator.Header); while (theCenteredHeader.Length < theWidth) { if (theCenteredHeader.Length % 2 == 0) { theCenteredHeader.Insert(0, ' '); } else { theCenteredHeader.Append(' '); } } theResult.Append(theCenteredHeader); theIndex += theColSpan - 1; } if (theIndex < theColumnCount - 1) { theResult.Append(" | "); } } theResult .Append(Lf) .Append(theSpaces); } for (int theIndex = 0; theIndex < theColumnCount; theIndex++) { TextColumn <TColumn> theColumn = theColumns[theIndex]; theResult.Append(string.Format(GetAlignmentString(theColumn), theColumn.Header)); if (theIndex < theColumnCount - 1) { theResult.Append(" | "); } } if (theColumns.Any(c => c.SecondaryHeader != null)) { theResult .Append(Lf) .Append(theSpaces); for (int theIndex = 0; theIndex < theColumnCount; theIndex++) { TextColumn <TColumn> theColumn = theColumns[theIndex]; theResult.Append(string.Format(GetAlignmentString(theColumn), theColumn.SecondaryHeader)); if (theIndex < theColumnCount - 1) { theResult.Append(" | "); } } } if (theColumns.Any(c => c.DataType != null)) { theResult .Append(Lf) .Append(theSpaces); for (int theIndex = 0; theIndex < theColumnCount; theIndex++) { TextColumn <TColumn> theColumn = theColumns[theIndex]; theResult.Append(string.Format(GetAlignmentString(theColumn), theColumn.DataType)); if (theIndex < theColumnCount - 1) { theResult.Append(" | "); } } } theResult.Append(Lf); var theSeperatorLine = new StringBuilder(); for (int theIndex = 0; theIndex < theColumnCount; theIndex++) { theSeperatorLine.Append('-', theColumns[theIndex].Width); if (theIndex < theColumnCount - 1) { theSeperatorLine.Append("-|-"); } } theResult .Append(theSpaces) .Append(theSeperatorLine) .Append(Lf); int theRowCount = theColumns.First().Rows.Count; string?theEmptyTableText = tableInfoProvider.EmptyTableText; if (theEmptyTableText != null && theRowCount == 0) { theResult .Append(theSpaces) .Append(theEmptyTableText) .Append(Lf); } else { for (int theRowIndex = 0; theRowIndex < theRowCount; theRowIndex++) { theResult.Append(theSpaces); if (theRowIndex == theRowCount - 1) { // Letzte Zeile if (tableInfoProvider.HasSumRow) { theResult .Append(theSeperatorLine) .Append(Lf) .Append(theSpaces); } } for (int theIndex = 0; theIndex < theColumnCount; theIndex++) { TextColumn <TColumn> theColumn = theColumns[theIndex]; (string theCellValue, int theColSpan) = theColumn.Rows[theRowIndex]; string theAlignmentString; if (theColSpan == 1) { theAlignmentString = GetAlignmentString(theColumn); } else { int theWidth = theColumns.Skip(theIndex).Take(theColSpan).Sum(c => c.Width) + (theColSpan - 1) * 3; theAlignmentString = $"{{0,-{theWidth}}}"; } theResult.Append(string.Format(theAlignmentString, theCellValue)); theIndex += theColSpan - 1; if (theIndex < theColumnCount - 1) { theResult.Append(" | "); } } theResult.Append(Lf); } } if (tableInfoProvider.HasTrailingSeperatorLine && (theRowCount != 0 || theEmptyTableText != null)) { theResult .Append(theSpaces) .Append(theSeperatorLine) .Append(Lf); } return(theResult.ToString()); }