打印DataTable的内容

46
目前我有一段代码,通过SQL连接查找数据库表,并将前五行插入到一个数据表(Table)中。
using(SqlCommand _cmd = new SqlCommand(queryStatement, _con))
{
    DataTable Table = new DataTable("TestTable");

    SqlDataAdapter _dap = new SqlDataAdapter(_cmd);

    _con.Open();
    _dap.Fill(Table);
    _con.Close();
}

如何将这个表格的内容打印到控制台上供用户查看?
经过一番搜索,我是否应该将内容绑定到列表视图,还是有直接打印它们的方法?在这个阶段,我并不关心设计,只关心数据。

如果你已经将所有内容都包装在 using 语句中,那么 .Open() 和 .Close() 是否还需要呢? - David Mays
10个回答

60

你可以尝试这段代码:

foreach(DataRow dataRow in Table.Rows)
{
    foreach(var item in dataRow.ItemArray)
    {
        Console.WriteLine(item);
    }
}

更新 1

DataTable Table = new DataTable("TestTable");
using(SqlCommand _cmd = new SqlCommand(queryStatement, _con))
{
    SqlDataAdapter _dap = new SqlDataAdapter(_cmd);
    _con.Open();
    _dap.Fill(Table);
    _con.Close();

}
Console.WriteLine(Table.Rows.Count);
foreach(DataRow dataRow in Table.Rows)
{
    foreach(var item in dataRow.ItemArray)
    {
        Console.WriteLine(item);
    }
}

嗨,谢谢你的回答。这个编译没有问题,但是没有显示任何东西,有可能是什么都没有吗? - William
更新后的代码仍然没有显示数据... 代码位于public Form1()内部。它应该放在其他地方吗? - William
这是Windows应用程序还是控制台应用程序? - Arshad
这是一个Windows窗体应用程序。 - William
1
让我们在聊天室继续这个讨论 - Arshad
显示剩余2条评论

11

适当的表格显示

static void print_results(DataTable data)
    {
        Console.WriteLine();
        Dictionary<string, int> colWidths = new Dictionary<string, int>();

        foreach (DataColumn col in data.Columns)
        {
            Console.Write(col.ColumnName);
            var maxLabelSize = data.Rows.OfType<DataRow>()
                    .Select(m => (m.Field<object>(col.ColumnName)?.ToString() ?? "").Length)
                    .OrderByDescending(m => m).FirstOrDefault();

            colWidths.Add(col.ColumnName, maxLabelSize);
            for (int i = 0; i < maxLabelSize - col.ColumnName.Length + 10; i++) Console.Write(" ");
        }

        Console.WriteLine();

        foreach (DataRow dataRow in data.Rows)
        {
            for (int j = 0; j < dataRow.ItemArray.Length; j++)
            {
                Console.Write(dataRow.ItemArray[j]);
                for (int i = 0; i < colWidths[data.Columns[j].ColumnName] - dataRow.ItemArray[j].ToString().Length + 10; i++) Console.Write(" ");
            }
            Console.WriteLine();
        }
    }

对于那些需要类似于pandas数据框打印输出或仅仅是SSMS/VSCode表格输出的人来说,这是首选解决方案。谢谢! - ferreiradev

10

以下是另一种解决方案,它将表格转储为逗号分隔的字符串:

using System.Data;

public static string DumpDataTable(DataTable table)
        {
            string data = string.Empty;
            StringBuilder sb = new StringBuilder();

            if (null != table && null != table.Rows)
            {
                foreach (DataRow dataRow in table.Rows)
                {
                    foreach (var item in dataRow.ItemArray)
                    {
                        sb.Append(item);
                        sb.Append(',');
                    }
                    sb.AppendLine();
                }

                data = sb.ToString();
            }
            return data;
        }

5
foreach (DataRow dr in myDataTable.Rows)
{
    foreach (var item in dr.ItemArray)
    {
        Console.Write(item + " ");
    }
    Console.WriteLine();
}

1之前的答案与此类似,但未清晰地格式化行条目和单元格之间的分隔线。


这应该是对你所提到的答案的评论,而不是一个独立的回答。它没有提供对原帖中的问题的新颖回应或解决方案。 - undefined
Stack Overflow的用户希望得到尽可能简洁的答案。最简洁的答案是我所提到的那个,但它无法展示输出的内容,而这对于了解循环的实际工作方式非常重要 - 这就是促使我,同一个人,寻求简洁答案,并对答案进行改进的原因。无论如何,点赞的人并不同意你的观点。 - undefined
重复大部分答案并不够简洁,与只是说(添加Console.WriteLine来显示输出)的评论相比。此外,不要被分数误导,人们经常点赞糟糕的内容。 - undefined

5
使用以下扩展方法(C# 9.0):
/// <summary>
/// Provides extension methods for the <see cref="DataTable"/> type.
/// </summary>
public static class DataTableExtensions
{
    /// <summary>
    /// Generates a textual representation of the data of <paramref name="table"/>.
    /// </summary>
    /// <param name="table">The table to print.</param>
    /// <returns>A textual representation of the data of <paramref name="table"/>.</returns>
    public static String Print(this DataTable table)
    {
        String GetCellValueAsString(DataRow row, DataColumn column)
        {
            var cellValue = row[column];
            var cellValueAsString = cellValue is null or DBNull ? "{{null}}" : cellValue.ToString();

            return cellValueAsString;
        }

        var columnWidths = new Dictionary<DataColumn, Int32>();

        foreach (DataColumn column in table.Columns)
        {
            columnWidths.Add(column, column.ColumnName.Length);
        }

        foreach (DataRow row in table.Rows)
        {
            foreach (DataColumn column in table.Columns)
            {
                columnWidths[column] = Math.Max(columnWidths[column], GetCellValueAsString(row, column).Length);
            }
        }

        var resultBuilder = new StringBuilder();

        resultBuilder.Append("| ");

        foreach (DataColumn column in table.Columns)
        {
            resultBuilder.Append(column.ColumnName.PadRight(columnWidths[column]));
            resultBuilder.Append(" | ");
        }

        resultBuilder.AppendLine();

        foreach (DataRow row in table.Rows)
        {
            resultBuilder.Append("| ");

            foreach (DataColumn column in table.Columns)
            {
                resultBuilder.Append(GetCellValueAsString(row, column).PadRight(columnWidths[column]));
                resultBuilder.Append(" | ");
            }

            resultBuilder.AppendLine();
        }

        return resultBuilder.ToString();
    }
}

运行得很好,看起来也很棒! - curious coder
是的,这就是答案。 - moberme

3

这是通过一个包含单个表格的数据表来完成的。

        SqlConnection con = new SqlConnection(constr);
        con.Open();
        SqlCommand cmd = new SqlCommand("select * from info", con);
        SqlDataAdapter ad = new SqlDataAdapter(cmd);

        DataTable dt = new DataTable();
        ad.Fill(dt);
        Console.WriteLine(dt.Columns[0].ColumnName.ToString());
        Console.WriteLine(dt.Rows[1].ItemArray[0].ToString());

这是通过保存一组表格的数据集来完成的。
        SqlConnection con = new SqlConnection(constr);
        con.Open();
        SqlCommand cmd = new SqlCommand("select * from info", con);
        SqlDataAdapter ad = new SqlDataAdapter(cmd);

        DataSet dt = new DataSet();
        ad.Fill(dt);
        Console.WriteLine(dt.Tables[0].Columns[0].ColumnName.ToString());
        Console.WriteLine(dt.Tables[0].Rows[0].ItemArray[0].ToString());

两者将得到相同的结果。只有数据集包含表的索引编号。


1
打印带有列的Datatable内容行
Here is solution 

DataTable datatableinfo= new DataTable();

// Fill data table 

//datatableinfo=fill by function or get data from database

//Print data table with rows and column


for (int j = 0; j < datatableinfo.Rows.Count; j++)
{
    for (int i = 0; i < datatableinfo.Columns.Count; i++)    
        {    
            Console.Write(datatableinfo.Columns[i].ColumnName + " ");    
            Console.WriteLine(datatableinfo.Rows[j].ItemArray[i]); 
        }
}


Ouput :
ColumnName - row Value
ColumnName - row Value
ColumnName - row Value
ColumnName - row Value

0

一个既可以打印 DataTable 也可以打印 DataRow 的函数。

    private void printDataTable(DataTable Table)
    {
        foreach (DataRow dataRow in Table.Rows)
        {
            printDataRow(dataRow);
        }
    }

    private void printDataRow(DataRow drow)
    {

        StringBuilder sb = new StringBuilder();

        sb.AppendLine(string.Join(",", drow.ItemArray));
        Console.WriteLine(sb);

    }

0

在另一个答案的基础上,这里提供一种将DataTable转换为CSV输出并将列名添加为输出中的第一行的方法:

public static string DataTableToCsv(DataTable table)
{
    string result = string.Empty;
    StringBuilder resultBuilder = new StringBuilder();

    if (table != null && table.Rows != null && table.Columns != null && table.Columns.Count > 0)
    {
        int lastItemIndex = table.Columns.Count - 1;
        int index = 0;

        foreach (DataColumn column in table.Columns)
        {
            resultBuilder.Append(column.ColumnName);

            if (index < lastItemIndex)       // if not the last element in the row
                resultBuilder.Append(", ");  // add the separator

            index++;
        }

        resultBuilder.AppendLine();  // add a CRLF after column names row

        foreach (DataRow dataRow in table.Rows)
        {
            lastItemIndex = dataRow.ItemArray.Length - 1;
            index = 0;

            foreach (object item in dataRow.ItemArray)
            {
                resultBuilder.Append(item);

                if (index < lastItemIndex)       // if not the last element in the row
                    resultBuilder.Append(", ");  // add the separator

                index++;
            }

            resultBuilder.AppendLine();  // add a CRLF after each data row
        }

        result = resultBuilder.ToString();
    }

    return result;
}

使用示例:

DataTable table = new DataTable();
....
Console.WriteLine(DataTableToCsv(table));

请注意,此方法无法正确处理(即转义)包含引号或逗号的数据。但是,它应该足以作为快速且简单的方式将数据表转储到控制台或任何其他地方进行查看。

0
使用以下的扩展方法。
public static string ToCSV(this DataTable t, bool header)
{
    StringBuilder sb = new StringBuilder();
    int i = 0;
    int maxColIdx = 0;
    
    if (t?.Columns?.Count > 0)
    {
        maxColIdx = t.Columns.Count - 1;
        if (header)
        {
            foreach (DataColumn c in t.Columns)
            {
                sb.Append(c.ColumnName);
                if (i < maxColIdx) sb.Append(", ");
                i++;
            }
            sb.AppendLine();
        }

        if (t?.Rows?.Count > 0)
        {
            foreach (DataRow r in t.Rows)
            {
                i = 0;
                foreach (var item in r.ItemArray)
                {
                    sb.Append(item);
                    if( i < maxColIdx) sb.Append(',');
                    i++;
                }
                sb.AppendLine();
            }
        }
    }           
    return sb.ToString();
}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接