C# 在控制台整齐的输出 DataTable

效果:

一、前言

在 Winform 平台,可以用 DataGridView 这样的控件来显示数据库的表单数据,但在 C# 控制台项目中,如果有用到数据库查询,我们想看看查询语句的效果,就比较困难了,比如,我随意写了一个控制台输出,代码如下:

using System.Data;

namespace CSharpConnectMySQL
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string sql = "SELECT * FROM goods_type";
            DataSet dataSet = MySqlHelper.GetDataSet(sql);
            DataTable dt = dataSet.Tables[0];
            if(dt.Rows.Count > 0)
            {
                //打印所有列名
                string columnName = string.Empty;
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    columnName += dt.Columns[i].ColumnName + " | ";
                }
                Console.WriteLine(columnName);
                Console.WriteLine("-------------------------");

                //打印每一行的数据
                foreach (DataRow row in dt.Rows)
                {
                    string columnStr = string.Empty;
                    foreach (DataColumn column in dt.Columns)
                    {
                        columnStr += row[column] + " | ";
                    }
                    Console.WriteLine(columnStr);
                }
            }

            Console.ReadKey();
        }
    }
}

效果:

在 Navicat 16 for MySQL 软件中的查询结果

由于没有自动对齐的功能,打印出来的特别难看,于是我就想,能否自己写一个控制台打印数据库的方法出来,并且能自动对齐,虽然作用不大,起码看的舒服,那么接下来就来实现这个功能吧。

二、实现效果

由于后面的效果有用到数据库,所以没安装的 mysql 的,可以安装一下,并加入一些数据,或者手动写一个 DataTable 实体,并加入一些数据,都是可以的。

新建一个 C# 控制台项目,按我之前的帖子来加入一些连接数据库需要的类,和必要的插件

C# 连接 MySQL 数据库_c# mysql_熊思宇的博客-CSDN博客

添加一个类  ConsoleTool

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;

public class ConsoleTool
{
    /// <summary>
    /// 在控制台打印 DataTable
    /// </summary>
    /// <param name="dt"></param>
    public static void PrintDataTabele(DataTable dt)
    {
        if (dt == null)
        {
            Console.WriteLine("DataTable 不能为空");
            return;
        }

        //获取每一列的最大长度
        float[] lenList = GetColumnsMaxFontLength(dt);
        if (IsExceedMaxValue(lenList))
        {
            Console.WriteLine("DataTable列的总长度太长,控制台无法完整显示");
            return;
        }

        //字符串末尾添加多少个空格
        int endAddEmptyCount = 2;
        //打印标题
        string columnName = string.Empty;

        for (int i = 0; i < dt.Columns.Count; i++)
        {
            string value = dt.Columns[i].ColumnName;
            float emptyCount = lenList[i] - GetFontLenght(value);
            value = AppendEmpty(value, emptyCount + endAddEmptyCount);
            columnName += value;
        }
        string hengang = GetPrintBar(GetFontLenght(columnName));
        Console.WriteLine(hengang);
        Console.WriteLine(columnName);
        Console.WriteLine(hengang);

        //打印内容
        for (int i = 0; i < dt.Rows.Count; i++)
        {
            string columnStr = string.Empty;
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                string? value = dt.Rows[i][j].ToString();
                if (string.IsNullOrEmpty(value)) value = "null";
                float emptyCount = lenList[j] - GetFontLenght(value);
                value = AppendEmpty(value, emptyCount + endAddEmptyCount);
                columnStr += value;
            }
            Console.WriteLine(columnStr);
        }

        Console.WriteLine(hengang);
    }

    /// <summary>
    /// 是否超过了规定的最大值
    /// </summary>
    /// <param name="lenList"></param>
    /// <returns></returns>
    private static bool IsExceedMaxValue(float[] lenList)
    {
        int singleMax = 100;
        int totalLength = 90;
        float value = 0;
        for (int i = 0; i < lenList.Length; i++)
        {
            value += lenList[i];
        }
        if (value > totalLength)
        {
            return true;
        }
        for (int i = 0; i < lenList.Length; i++)
        {
            if (lenList[i] > singleMax)
            {
                return true;
            }
        }
        return false;
    }

    /// <summary>
    /// 获取列中字符串最大的长度
    /// </summary>
    /// <param name="dataTable"></param>
    /// <returns></returns>
    private static float[] GetColumnsMaxFontLength(DataTable dataTable)
    {
        if (dataTable.Columns.Count == 0) return new float[0];
        if (dataTable.Rows.Count == 0) return new float[0];

        float[] columnLength = new float[dataTable.Columns.Count];

        //先加标题
        for (int i = 0; i < dataTable.Columns.Count; i++)
        {
            columnLength[i] = GetFontLenght(dataTable.Columns[i].ColumnName);
        }

        //再加具体列
        for (int i = 0; i < dataTable.Rows.Count; i++)
        {
            for (int j = 0; j < dataTable.Columns.Count; j++)
            {
                string? columnsCon = dataTable.Rows[i][j].ToString();
                if (string.IsNullOrEmpty(columnsCon)) columnsCon = "null";
                float columnsConLen = GetFontLenght(columnsCon);
                if (columnsConLen > columnLength[j])
                {
                    columnLength[j] = columnsConLen;
                }
            }
        }

        return columnLength;
    }

    /// <summary>
    /// 获取字体的长度
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    private static float GetFontLenght(string? value)
    {
        float nCount = 0;
        for (int i = 0; i < value?.Length; i++)
        {
            char val = value[i];
            //if (val >= 0x4e00 && val <= 0x9fbb)//汉字
            //    nCount += 1;
            if (IsChinese(val))
                nCount += 1;
            else
                nCount += 0.5f;
        }

        return nCount;
    }

    /// <summary>
    /// 给字符串添加空格
    /// </summary>
    /// <param name="value"></param>
    /// <param name="count"></param>
    /// <returns></returns>
    private static string AppendEmpty(string? value, float count)
    {
        if (string.IsNullOrEmpty(value))
            return string.Empty;
        if (count == 0)
            return value + " ";

        string[] arr = count.ToString().Split('.');
        int integer = 0;
        int decimals = 0;
        if (arr.Length == 1)
        {
            if (!int.TryParse(arr[0], out integer))
                return string.Empty;
        }
        if (arr.Length == 2)
        {
            if (!int.TryParse(arr[0], out integer))
                return string.Empty;
            if (!int.TryParse(arr[1], out decimals))
                return string.Empty;
        }
        for (int i = 0; i < integer; i++)
        {
            value += "  ";
        }
        if (decimals == 5)
        {
            value += " ";
        }
        return value;
    }

    /// <summary>
    /// 获取横杆
    /// </summary>
    /// <param name="count"></param>
    /// <returns></returns>
    private static string GetPrintBar(float count)
    {
        string bar = string.Empty;
        string[] arr = count.ToString().Split('.');
        int integer = 0;
        int decimals = 0;
        if (arr.Length == 1)
        {
            if (!int.TryParse(arr[0], out integer))
                return string.Empty;
        }
        if (arr.Length == 2)
        {
            if (!int.TryParse(arr[0], out integer))
                return string.Empty;
            if (!int.TryParse(arr[1], out decimals))
                return string.Empty;
        }
        for (int i = 0; i < integer; i++)
        {
            bar += "--";
        }
        if (decimals == 5)
        {
            bar += "-";
        }

        return bar;
    }

    /// <summary>
    /// 是否是中文
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    private static bool IsChinese(char value)
    {
        UnicodeEncoding unicodeencoding = new UnicodeEncoding();
        byte[] unicodebytearray = unicodeencoding.GetBytes(value.ToString());
        bool isChina = false;
        for (int i = 0; i < unicodebytearray.Length; i++)
        {
            i++;
            //如果是中文字符那么高位不为0  
            if (unicodebytearray[i] != 0)
            {
                isChina = true;
                break;
            }
        }
        return isChina;
    }
}

调用:

using System.Data;

namespace CSharpConnectMySQL
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string sql = "SELECT * FROM goods_type";
            DataSet dataSet = MySqlHelper.GetDataSet(sql);
            if (dataSet.Tables.Count == 0) return;
            DataTable dt = dataSet.Tables[0];
            if(dt.Rows.Count > 0)
            {
                ConsoleTool.PrintDataTabele(dt);
            }

            Console.ReadKey();
        }
    }
}

运行:

由于数据比较少,看着效果不明显,数据多了效果就更好了

end

猜你喜欢

转载自blog.csdn.net/qq_38693757/article/details/131533357