簡體   English   中英

如何在 C# 中將 DataTable 轉換為字符串?

[英]How to convert a DataTable to a string in C#?

我正在使用 Visual Studio 2005 並有一個包含兩列和一些行的數據表,我想將它們輸出到控制台。 我希望會有類似的東西:

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

將簡單的 DataTable 轉換為字符串的最佳方法是什么(即我的編碼量最少)?

先決條件

using System.Linq;

然后...

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 輸出非常可讀。 但是,如果格式化對您很重要,那么您別無選擇,只能編寫自己的方法來完成。

你可以使用這樣的東西:

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

我知道我遲到了 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 中。 內置的 commandlet 使控制台工作得很好。

兩個 for 循環,一個用於行,另一個用於列,輸出 dataRow(i).Value。 注意空值和 DbNulls。

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! | 
==========================================================
    /// <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....

失敗了為什么不遍歷它的行和列集合並輸出它們呢?

或者,將應用程序更改為 WinForms,使用網格並將 DataTable 綁定到網格。 如果它是演示/示例應用程序。

我根據您的需要創建了我的類變體。 我相信它比已經提供的變體更可配置。 您可以將它與所有默認設置一起使用,只需創建一個類的實例並調用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;
        }
    }
}

如果 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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM