如何将DataTable转换为C#中的字符串?

我正在使用Visual Studio 2005并且有一个DataTable,其中包含两列和一些我要输出到控制台的行。 我希望有类似的东西:

DataTable results = MyMethod.GetResults(); Console.WriteLine (results.ToString()); 

将简单的DataTable转换为字符串的最佳方法(即从我这里编写的最少量)是什么?

你可以使用这样的东西:

 Private Sub PrintTableOrView(ByVal table As DataTable, ByVal label As String) Dim sw As System.IO.StringWriter Dim output As String Console.WriteLine(label) ' Loop through each row in the table. ' For Each row As DataRow In table.Rows sw = New System.IO.StringWriter ' Loop through each column. ' For Each col As DataColumn In table.Columns ' Output the value of each column's data. sw.Write(row(col).ToString() & ", ") Next output = sw.ToString ' Trim off the trailing ", ", so the output looks correct. ' If output.Length > 2 Then output = output.Substring(0, output.Length - 2) End If ' Display the row in the console window. ' Console.WriteLine(output) Next Console.WriteLine() End Sub 

迟到但这是我用的

  public static string ConvertDataTableToString(DataTable dataTable) { var output = new StringBuilder(); var columnsWidths = new int[dataTable.Columns.Count]; // Get column widths foreach (DataRow row in dataTable.Rows) { for(int i = 0; i < dataTable.Columns.Count; i++) { var length = row[i].ToString().Length; if (columnsWidths[i] < length) columnsWidths[i] = length; } } // Get Column Titles for (int i = 0; i < dataTable.Columns.Count; i++) { var length = dataTable.Columns[i].ColumnName.Length; if (columnsWidths[i] < length) columnsWidths[i] = length; } // Write Column titles for (int i = 0; i < dataTable.Columns.Count; i++) { var text = dataTable.Columns[i].ColumnName; output.Append("|" + PadCenter(text, columnsWidths[i] + 2)); } output.Append("|\n" + new string('=', output.Length) + "\n"); // Write Rows foreach (DataRow row in dataTable.Rows) { for (int i = 0; i < dataTable.Columns.Count; i++) { var text = row[i].ToString(); output.Append("|" + PadCenter(text,columnsWidths[i] + 2)); } output.Append("|\n"); } return output.ToString(); } private static string PadCenter(string text, int maxLength) { int diff = maxLength - text.Length; return new string(' ', diff/2) + text + new string(' ', (int) (diff / 2.0 + 0.5)); } 
 string res = string.Join(Environment.NewLine, results.Rows.OfType().Select(x => string.Join(" ; ", x.ItemArray))); 
 using(var writer = new StringWriter()) { results.WriteXml(writer); Console.WriteLine(writer.ToString()); } 

当然,这的有用性取决于格式化的重要性。 如果它只是一个调试转储,我发现这样的XML输出非常易读。 但是,如果格式对您很重要,那么您别无选择,只能编写自己的方法来执行此操作。

我知道我已经很晚了xD但是这就是我做到的

  public static string convertDataTableToString(DataTable dataTable) { string data = string.Empty; for (int i = 0; i < dataTable.Rows.Count; i++) { DataRow row = dataTable.Rows[i]; for (int j = 0; j < dataTable.Columns.Count; j++) { data += dataTable.Columns[j].ColumnName + "~" + row[j]; if (j == dataTable.Columns.Count - 1) { if (i != (dataTable.Rows.Count - 1)) data += "$"; } else data += "|"; } } return data; } 

如果有人对此进行了优化,请告诉我

我试过这个:

  public static string convertDataTableToString(DataTable dataTable) { string data = string.Empty; int rowsCount = dataTable.Rows.Count; for (int i = 0; i < rowsCount; i++) { DataRow row = dataTable.Rows[i]; int columnsCount = dataTable.Columns.Count; for (int j = 0; j < columnsCount; j++) { data += dataTable.Columns[j].ColumnName + "~" + row[j]; if (j == columnsCount - 1) { if (i != (rowsCount - 1)) data += "$"; } else data += "|"; } } return data; } 

但这个答案说它更糟糕

我会安装PowerShell 。 它理解.NET对象,并且具有Format-Table和Export-Csv,它们可以完全满足您的需求。 如果你做任何类型的控制台工作,它是C#控制台应用程序的一个很好的补充/替代。

当我开始使用它时,我将控制台应用程序重写为库并将库导入Powershell。 内置的命令行开关使控制台工作得非常好。

两个for循环,一个用于行,另一个用于列,输出dataRow(i).Value。 注意空值和DbNulls。

或者,将应用程序更改为WinForms,使用网格并将DataTable绑定到网格。 如果它是一个演示/示例应用程序。

  ///  /// Dumps the passed DataSet obj for debugging as list of html tables ///  ///  the msg attached  ///  the DataSet object passed for Dumping  ///  the nice looking dump of the DataSet obj in html format public static string DumpHtmlDs(string msg, ref System.Data.DataSet ds) { StringBuilder objStringBuilder = new StringBuilder(); objStringBuilder.AppendLine(""); if (ds == null) { objStringBuilder.AppendLine("Null dataset passed "); objStringBuilder.AppendLine(""); WriteIf(objStringBuilder.ToString()); return objStringBuilder.ToString(); } objStringBuilder.AppendLine("

" + msg + " START

"); if (ds != null) { if (ds.Tables == null) { objStringBuilder.AppendLine("ds.Tables == null "); return objStringBuilder.ToString(); } foreach (System.Data.DataTable dt in ds.Tables) { if (dt == null) { objStringBuilder.AppendLine("ds.Tables == null "); continue; } objStringBuilder.AppendLine(""); //objStringBuilder.AppendLine("================= My TableName is " + //dt.TableName + " ========================= START"); int colNumberInRow = 0; objStringBuilder.Append(""); foreach (System.Data.DataColumn dc in dt.Columns) { if (dc == null) { objStringBuilder.AppendLine("DataColumn is null "); continue; } objStringBuilder.Append(" "); colNumberInRow++; } //eof foreach (DataColumn dc in dt.Columns) objStringBuilder.Append(""); int rowNum = 0; foreach (System.Data.DataRow dr in dt.Rows) { objStringBuilder.Append(""); int colNumber = 0; foreach (System.Data.DataColumn dc in dt.Columns) { objStringBuilder.Append(" "); colNumber++; } //eof foreach (DataColumn dc in dt.Columns) rowNum++; objStringBuilder.AppendLine(" "); } //eof foreach (DataRow dr in dt.Rows) objStringBuilder.AppendLine("
row number |" + colNumberInRow.ToString() + " | "); objStringBuilder.Append( dc.ColumnName.ToString() + "
row - | " + rowNum.ToString() + " | |" + colNumber + "|" ); objStringBuilder.Append(dr[dc].ToString() + "
"); objStringBuilder.AppendLine("

" + msg + " END

"); } //eof foreach (DataTable dt in ds.Tables) } //eof if ds !=null else { objStringBuilder.AppendLine("NULL DataSet object passed for debugging !!!"); } return objStringBuilder.ToString(); }

非常含糊……

id将它简单地插入到数据集中,以便我可以轻松地将其输出为xml ….

失败的原因是为什么不迭代它的行和列集合并输出它们?

 public static string DataTable2String(DataTable dataTable) { StringBuilder sb = new StringBuilder(); if (dataTable != null) { string seperator = " | "; #region get min length for columns Hashtable hash = new Hashtable(); foreach (DataColumn col in dataTable.Columns) hash[col.ColumnName] = col.ColumnName.Length; foreach (DataRow row in dataTable.Rows) for (int i = 0; i < row.ItemArray.Length; i++) if (row[i] != null) if (((string)row[i]).Length > (int)hash[dataTable.Columns[i].ColumnName]) hash[dataTable.Columns[i].ColumnName] = ((string)row[i]).Length; int rowLength = (hash.Values.Count + 1) * seperator.Length; foreach (object o in hash.Values) rowLength += (int)o; #endregion get min length for columns sb.Append(new string('=', (rowLength - " DataTable ".Length) / 2)); sb.Append(" DataTable "); sb.AppendLine(new string('=', (rowLength - " DataTable ".Length) / 2)); if (!string.IsNullOrEmpty(dataTable.TableName)) sb.AppendLine(String.Format("{0,-" + rowLength + "}", String.Format("{0," + ((rowLength + dataTable.TableName.Length) / 2).ToString() + "}", dataTable.TableName))); #region write values foreach (DataColumn col in dataTable.Columns) sb.Append(seperator + String.Format("{0,-" + hash[col.ColumnName] + "}", col.ColumnName)); sb.AppendLine(seperator); sb.AppendLine(new string('-', rowLength)); foreach (DataRow row in dataTable.Rows) { for (int i = 0; i < row.ItemArray.Length; i++) { sb.Append(seperator + String.Format("{0," + hash[dataTable.Columns[i].ColumnName] + "}", row[i])); if (i == row.ItemArray.Length - 1) sb.AppendLine(seperator); } } #endregion write values sb.AppendLine(new string('=', rowLength)); } else sb.AppendLine("================ DataTable is NULL ================"); return sb.ToString(); } 

输出:

 ======================= DataTable ======================= MyTable | COL1 | COL2 | COL3 1000000ng name | ---------------------------------------------------------- | 1 | 2 | 3 | | abc | Dienstag, 12. März 2013 | xyz | | Have | a nice | day! | ========================================================== 

我根据您的需要创建了我的课程变体。 我相信它比已经提供的变体更具可配置性。 您可以将它与所有默认设置一起使用,只需创建一个类的实例并调用StringifyDataTable方法,或者您可以根据需要设置其他选项。

 public class DataTableStringifier { public bool IsOuterBordersPresent { get; set; } //Whether outer borders of table needed public bool IsHeaderHorizontalSeparatorPresent { get; set; } // Whether horizontal line separator between table title and data is needed. Useful to set 'false' if you expect only 1 or 2 rows of data - no need for additional lines then public char ValueSeparator { get; set; } //Vertical line character public char HorizontalLinePadChar { get; set; } // Horizontal line character public char HorizontalLineSeparator { get; set; } // Horizontal border (between header and data) column separator (crossing of horizontal and vertical borders) public int ValueMargin { get; set; } // Horizontal margin from table borders (inner and outer) to cell values public int MaxColumnWidth { get; set; } // To avoid too wide columns with thousands of characters. Longer values will be cropped in the center public string LongValuesEllipses { get; set; } // Cropped values wil be inserted this string in the middle to mark the point of cropping public DataTableStringifier() { MaxColumnWidth = int.MaxValue; IsHeaderHorizontalSeparatorPresent = true; ValueSeparator = '|'; ValueMargin = 1; HorizontalLinePadChar = '-'; HorizontalLineSeparator = '+'; LongValuesEllipses = "..."; IsOuterBordersPresent = false; } public string StringifyDataTable(DataTable table) { int colCount = table.Columns.Count; int rowCount = table.Rows.Count; string[] colHeaders = new string[colCount]; string[,] cells = new string[rowCount, colCount]; int[] colWidth = new int[colCount]; for (int i = 0; i < colCount; i++) { var column = table.Columns[i]; var colName = ValueToLimitedLengthString(column.ColumnName); colHeaders[i] = colName; if (colWidth[i] < colName.Length) { colWidth[i] = colName.Length; } } for (int i = 0; i < rowCount; i++) { DataRow row = table.Rows[i]; for (int j = 0; j < colCount; j++) { var valStr = ValueToLimitedLengthString(row[j]); cells[i, j] = valStr; if (colWidth[j] < valStr.Length) { colWidth[j] = valStr.Length; } } } string valueSeparatorWithMargin = string.Concat(new string(' ', ValueMargin), ValueSeparator, new string(' ', ValueMargin)); string leftBorder = IsOuterBordersPresent ? string.Concat(ValueSeparator, new string(' ', ValueMargin)) : ""; string rightBorder = IsOuterBordersPresent ? string.Concat(new string(' ', ValueMargin), ValueSeparator) : ""; string horizLine = new string(HorizontalLinePadChar, colWidth.Sum() + (colCount - 1)*(ValueMargin*2 + 1) + (IsOuterBordersPresent ? (ValueMargin + 1)*2 : 0)); StringBuilder tableBuilder = new StringBuilder(); if (IsOuterBordersPresent) { tableBuilder.AppendLine(horizLine); } tableBuilder.Append(leftBorder); for (int i = 0; i < colCount; i++) { tableBuilder.Append(colHeaders[i].PadRight(colWidth[i])); if (i < colCount - 1) { tableBuilder.Append(valueSeparatorWithMargin); } } tableBuilder.AppendLine(rightBorder); if (IsHeaderHorizontalSeparatorPresent) { if (IsOuterBordersPresent) { tableBuilder.Append(ValueSeparator); tableBuilder.Append(HorizontalLinePadChar, ValueMargin); } for (int i = 0; i < colCount; i++) { tableBuilder.Append(new string(HorizontalLinePadChar, colWidth[i])); if (i < colCount - 1) { tableBuilder.Append(HorizontalLinePadChar, ValueMargin); tableBuilder.Append(HorizontalLineSeparator); tableBuilder.Append(HorizontalLinePadChar, ValueMargin); } } if (IsOuterBordersPresent) { tableBuilder.Append(HorizontalLinePadChar, ValueMargin); tableBuilder.Append(ValueSeparator); } tableBuilder.AppendLine(); } for (int i = 0; i < rowCount; i++) { tableBuilder.Append(leftBorder); for(int j=0; j MaxColumnWidth) { int beginningLength = (MaxColumnWidth) / 2; int endingLength = (MaxColumnWidth + 1) / 2 - LongValuesEllipses.Length; return string.Concat(strValue.Substring(0, beginningLength), LongValuesEllipses, strValue.Substring(strValue.Length - endingLength, endingLength)); } else { return strValue; } } }