C# DataTable 行轉列 列轉行 同時轉換


需求:數據庫數據都是縱向的,呈現的時候要求是橫向(列轉行)同時看到行頭(行轉列)。

分析:很多報表呈現都要求要這樣顯示,用類是可以實現,但是代碼多,又需要建很多dto。發下Excel有轉置功能,但又不想牽扯Excel這一套組件。就使用DataTable來實現,代碼也不多。

先看看示例數據3列10行:

 

我們要把它轉成3行10列,列轉行,行轉列同時完成:

 

 

百度上有不少轉換方案,都不盡如意。基本都是一個方向的轉換。要么是行轉列,要么是列轉行。干脆就自己寫了一個。

因為行轉列,列轉行要同時進行,我們需要仔細觀察數據,打個下標來觀察。

先把數據歸類為二維數組,從轉換后的表倒推回去,發現:

結果表的是【1,1】是原始表的【1,1】.

結果表的【1,2】是原始表的【2,1】,類推結果表【1,3】是原始表【3,1】

規律:下標對調就可以得到轉換表

 

 

 

代碼實現:

1、把源數據(包含列頭)轉換成二維數組,然后下標對調。這種方法使用最方便。就是要仔細算下標位置,應為列頭加進去了

 private DataTable PivotDatatable(DataTable dtSource, string columnFilter)
        {
            var columns = columnFilter.Split(',');
            DataTable dtFilter = dtSource.DefaultView.ToTable(false, columns);
            DataTable dtResult = new DataTable();

            var rowCount = dtFilter.Rows.Count;
            var columnCount = columns.Length;

            // 源數組的行數比DataTable的行數+1,, 加一行表頭
            object[,] arrSource = new object[rowCount + 1, columnCount];

            // 目標數組的行數等於選擇的列數,列數等於 源數據的行數+1, 加一列 屬性名
            object[,] arrResult = new object[columnCount, rowCount + 1];

            // 原數組第一行寫表頭
            for (int i = 0; i < columnCount; i++)
            {
                arrSource[0, i] = dtFilter.Columns[i].ColumnName;
            }

            // 源數據 每一行寫 數據
            for (int i = 0; i < rowCount; i++)
            {
                for (int j = 0; j < columnCount; j++)
                {
                    arrSource[i + 1, j] = dtFilter.Rows[i][j];
                }
            }

            // 原數 轉置到 目標數組
            for (int i = 0; i < rowCount + 1; i++)
            {
                for (int j = 0; j < columnCount; j++)
                {
                    arrResult[j, i] = arrSource[i, j];
                }
            }

            // 創建 Datatable 的結構
            for (int i = 0; i < rowCount + 1; i++)
            {
                dtResult.Columns.Add(arrResult[0, i].ToString());
            }

            List<string> valueList = new List<string>();
            for (int i = 1; i < columnCount; i++)
            {
                for (int j = 0; j < rowCount + 1; j++)
                {
                    valueList.Add(arrResult[i, j].ToString());
                }

                dtResult.Rows.Add(valueList.ToArray());
                valueList.Clear();
            }
            return dtResult;
        }

 2、思路是數據轉換成二維碼(不含列頭),轉換完成后,再把列頭加入到新的table里面,不需要過多算下標

private DataTable SwapTable(DataTable tableData)
        {
            int intRows = tableData.Rows.Count;
            int intColumns = tableData.Columns.Count;

            //轉二維數組
            string[,] arrayData = new string[intRows, intColumns];
            for (int i = 0; i < intRows; i++)
            {
                for (int j = 0; j < intColumns; j++)
                {
                    arrayData[i, j] = tableData.Rows[i][j].ToString();
                }
            }
            //下標對換
            string[,] arrSwap = new string[intColumns, intRows];
            for (int m = 0; m < intColumns; m++)
            {
                for (int n = 0; n < intRows; n++)
                {
                    arrSwap[m, n] = arrayData[n, m];
                }
            }
            DataTable dt = new DataTable();
            //添加列
            for (int k = 0; k < intRows; k++)
            {
                dt.Columns.Add(
                        new DataColumn(arrSwap[0, k])
                    );
            }
            //添加行
            for (int r = 1; r < intColumns; r++)
            {
                DataRow dr = dt.NewRow();
                for (int c = 0; c < intRows; c++)
                {
                    dr[c] = arrSwap[r, c].ToString();
                }
                dt.Rows.Add(dr);
            }
            //添加行頭
            DataColumn ColRowHead = new DataColumn(tableData.Columns[0].ColumnName);
            dt.Columns.Add(ColRowHead);
            dt.Columns[ColRowHead.ColumnName].SetOrdinal(0);
            for (int i = 0; i < intColumns - 1; i++)
            {
                dt.Rows[i][ColRowHead.ColumnName] = tableData.Columns[i + 1].ColumnName;
            }
            return dt;
        }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM