Visual Studio 2005を使用しており、コンソールに出力する2つの列といくつかの行を持つDataTableがあります。私は次のようなものになることを願っていました:
DataTable results = MyMethod.GetResults();
Console.WriteLine (results.ToString());
単純なDataTableを文字列に変換する最良の方法(つまり、私からのコーディングの最小量)とは何ですか?
this のようなものを使用できます。
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
string res = string.Join(Environment.NewLine,
results.Rows.OfType<DataRow>().Select(x => string.Join(" ; ", x.ItemArray)));
遅いですが、これは私が使用するものです
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));
}
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にインポートしました。ビルトインのコマンドレットにより、コンソールがとても便利になります。
ループ用に2つ、行用に1つ、列用に1つ、dataRow(i).Valueを出力します。 nullとDbNullに注意してください。
または、アプリをWinFormsに変更し、グリッドを使用してDataTableをグリッドにバインドします。デモ/サンプルアプリの場合。
/// <summary>
/// Dumps the passed DataSet obj for debugging as list of html tables
/// </summary>
/// <param name="msg"> the msg attached </param>
/// <param name="ds"> the DataSet object passed for Dumping </param>
/// <returns> the Nice looking dump of the DataSet obj in html format</returns>
public static string DumpHtmlDs(string msg, ref System.Data.DataSet ds)
{
StringBuilder objStringBuilder = new StringBuilder();
objStringBuilder.AppendLine("<html><body>");
if (ds == null)
{
objStringBuilder.AppendLine("Null dataset passed ");
objStringBuilder.AppendLine("</html></body>");
WriteIf(objStringBuilder.ToString());
return objStringBuilder.ToString();
}
objStringBuilder.AppendLine("<p>" + msg + " START </p>");
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("<table>");
//objStringBuilder.AppendLine("================= My TableName is " +
//dt.TableName + " ========================= START");
int colNumberInRow = 0;
objStringBuilder.Append("<tr><th>row number</th>");
foreach (System.Data.DataColumn dc in dt.Columns)
{
if (dc == null)
{
objStringBuilder.AppendLine("DataColumn is null ");
continue;
}
objStringBuilder.Append(" <th> |" + colNumberInRow.ToString() + " | ");
objStringBuilder.Append( dc.ColumnName.ToString() + " </th> ");
colNumberInRow++;
} //eof foreach (DataColumn dc in dt.Columns)
objStringBuilder.Append("</tr>");
int rowNum = 0;
foreach (System.Data.DataRow dr in dt.Rows)
{
objStringBuilder.Append("<tr><td> row - | " + rowNum.ToString() + " | </td>");
int colNumber = 0;
foreach (System.Data.DataColumn dc in dt.Columns)
{
objStringBuilder.Append(" <td> |" + colNumber + "|" );
objStringBuilder.Append(dr[dc].ToString() + " </td>");
colNumber++;
} //eof foreach (DataColumn dc in dt.Columns)
rowNum++;
objStringBuilder.AppendLine(" </tr>");
} //eof foreach (DataRow dr in dt.Rows)
objStringBuilder.AppendLine("</table>");
objStringBuilder.AppendLine("<p>" + msg + " END </p>");
} //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 ...として簡単に出力できるようにしました。
それに失敗すると、行と列のコレクションを繰り返し処理して出力しませんか?
ニーズに合わせてクラスのバリアントを作成しました。既に提供されている亜種よりも少し設定しやすいと思います。クラスのインスタンスを作成して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<colCount; j++)
{
tableBuilder.Append(cells[i, j].PadRight(colWidth[j]));
if(j<colCount-1)
{
tableBuilder.Append(valueSeparatorWithMargin);
}
}
tableBuilder.AppendLine(rightBorder);
}
if (IsOuterBordersPresent)
{
tableBuilder.AppendLine(horizLine);
}
return tableBuilder.ToString(0, tableBuilder.Length - 1); //Trim last enter char
}
private string ValueToLimitedLengthString(object value)
{
string strValue = value.ToString();
if (strValue.Length > 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;
}
}
}
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! |
==========================================================
Datatableに単一の列がある場合、datatable
をstring
に変更するのは簡単です。
DataTable results = MyMethod.GetResults();
if(results != null && results.Rows.Count > 0) // Check datatable is null or not
{
List<string> lstring = new List<string>();
foreach(DataRow dataRow in dt.Rows)
{
lstring.Add(Convert.ToString(dataRow["ColumnName"]));
}
string mainresult = string.Join(",", lstring.ToArray()); // You can Use comma(,) or anything which you want. who connect the two string. You may leave space also.
}
Console.WriteLine (mainresult);