C# DataTable 行转列通用方法

废话不多说,直接上代码,别问我代码是谁,为什么要上它?(注意,转发或者引用我的代码的,请标明出处连接,否则菊花难保!)

下面举两个列子的数据,如下代码所示

DataTable CreateDt1()
{
	var dt = new DataTable();
	dt.Columns.Add("id");
	dt.Columns.Add("编号");
	dt.Columns.Add("姓名");
	dt.Columns.Add("类型");
	dt.Columns.Add("值");
	dt.Rows.Add(1,"0001","张三","身高","180");
	dt.Rows.Add(2,"0001","张三","体重","120");
	dt.Rows.Add(3,"0002","李四","身高","170");
	dt.Rows.Add(4,"0002","李四","体重","130");
	dt.Rows.Add(5,"0003","王五","身高","175");
	dt.Rows.Add(6,"0003","王五","体重","135");
	return dt;
}
DataTable CreateDt2(){
var dt= new DataTable();
	dt.Columns.Add("户主编号");
	dt.Columns.Add("户主姓名");
	dt.Columns.Add("年月");
	dt.Columns.Add("费用类型");
	dt.Columns.Add("金额");
	dt.Rows.Add("0001","张三","2019-6","电费",100);
	dt.Rows.Add("0001","张三","2019-6","水费",90);
	dt.Rows.Add("0001","张三","2019-6","燃气费",200);
	dt.Rows.Add("0001","张三","2019-7","电费",110);
	dt.Rows.Add("0001","张三","2019-7","水费",100);
	dt.Rows.Add("0001","张三","2019-7","燃气费",190);
	dt.Rows.Add("0002","李四","2019-6","电费",125);
	dt.Rows.Add("0002","李四","2019-6","水费",100);
	dt.Rows.Add("0002","李四","2019-6","燃气费",110);
	dt.Rows.Add("0002","李四","2019-7","电费",120);
	dt.Rows.Add("0002","李四","2019-7","水费",60);
	dt.Rows.Add("0002","李四","2019-7","燃气费",150);
	return dt;
}

数据1:

Result Set (6 items)4
id编号姓名类型
10001张三身高180
20001张三体重120
30002李四身高170
40002李四体重130
50003王五身高175
60003王五体重135

数据2:

Result Set (12 items)4
户主编号户主姓名年月费用类型金额
0001张三2019-6电费100
0001张三2019-6水费90
0001张三2019-6燃气费200
0001张三2019-7电费110
0001张三2019-7水费100
0001张三2019-7燃气费190
0002李四2019-6电费125
0002李四2019-6水费100
0002李四2019-6燃气费110
0002李四2019-7电费120
0002李四2019-7水费60
0002李四2019-7燃气费150

行专列的通用方法:

/// <summary>
        /// DataTable行转列
        /// </summary>
        /// <param name="source">数据源</param>
        /// <param name="groupColumns">分组的列</param>
        /// <param name="captionColumns">要作为列显示的列</param>
        /// <param name="valueColumn">值列</param>
        /// <returns></returns>
        public static DataTable TableRowTurnToColumn(DataTable source, DataColumn[] groupColumns, DataColumn[] captionColumns, DataColumn valueColumn)
        {
            if (source == null)
                return null;
            DataTable dt = new DataTable();
            if (groupColumns != null)
                foreach (var item in groupColumns)
                {
                    dt.Columns.Add(item.ColumnName, item.DataType);
                }
            foreach (var item in source.AsEnumerable().Select(p => string.Join("_", captionColumns.Select(q => p[q]))).Distinct())
            {
                if (!dt.Columns.Contains(item.ToString()))
                    dt.Columns.Add(item.ToString());
            }
            var groupdata = source.AsEnumerable().GroupBy(p => string.Join("", groupColumns.Select(q => p[q]))).ToList();
            var groupColNames = groupColumns.Select(p => p.ColumnName);
            groupdata.ForEach(x =>
            {
                DataRow newRow = dt.NewRow();
                foreach (DataColumn col in dt.Columns)
                {
                    if (groupColNames.Contains(col.ColumnName))
                    {
                        newRow[col.ColumnName] = x.FirstOrDefault()[col.ColumnName];
                    }
                    else
                    {
                        var data = x.Where(p => string.Join("_", captionColumns.Select(q => p[q])) == col.ColumnName);
                        if (data.Count() > 0)
                        {
                            var numList = data.Where(p => decimal.TryParse(p[valueColumn].ToString(), out decimal v));//取数值类型的数据,若有就加总,若不是数值数据则用逗号拼接
                            if (numList.Count() > 0)
                            {
                                newRow[col.ColumnName] = numList.Sum(p => Convert.ToDecimal(p[valueColumn]));
                            }
                            else
                            {
                                newRow[col.ColumnName] = string.Join(",", data.Select(p => p[valueColumn]));//如果值不是数值类型的处理
                            }
                        }
                    }
                }
                dt.Rows.Add(newRow);
            });
            return dt;
        }

方法调用:

var dt1=CreateDt1();
var dt2=CreateDt2();
var dt11=TableRowTurnToColumn(dt1,new DataColumn[]{dt1.Columns[1],dt1.Columns[2]},new DataColumn[]{dt1.Columns[3]},dt1.Columns[4]);
var dt21=TableRowTurnToColumn(dt2,new DataColumn[]{dt2.Columns[0],dt2.Columns[1]},new DataColumn[]{dt2.Columns[2],dt2.Columns[3]},dt2.Columns[4]);

打印结果:

数据1行转列的结果:

Result Set (3 items)4
编号姓名身高体重
0001张三180120
0002李四170130
0003王五175135

数据2行转列的结果:

Result Set (2 items)4
户主编号户主姓名2019-6_电费2019-6_水费2019-6_燃气费2019-7_电费2019-7_水费2019-7_燃气费
0001张三10090200110100190
0002李四12510011012060150

合在一起的直观结果:

注:若要多个值,如下图的TeamQuantity 和FuelQuantity的两个值的,转成第三个表的结果,可以私聊。

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值