Asp.Net中C#实现的DataGrid小计,合计和纵向合并的通用方法

本文主要是介绍Asp.Net中C#实现的DataGrid小计,合计和纵向合并的通用方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 //方法定义 

 /// <summary>
 /// 映射计数器
 /// </summary>
 public class MapCounter
 {
             protected decimal _counter;
             protected int _mapIndex;
             public MapCounter(int mapIndex)
             {
                          this._mapIndex = mapIndex;
                          this._counter = 0;
             }
             public int MapIndex{get{return this._mapIndex;}}
             public void Add(decimal value)
             {
                          this._counter += value;
             }
             public void Reset()
             {
                          this._counter = 0;
             }
             public decimal Value{get{return this._counter;}}
 }
 public class PresentUtil
 {
             public static void PreparePresent(DataGrid target,DataTable dataSource,int keyColumnIndex,string keyColumnDataSourceName,int totalColumnColSpan,int subTotalColumnColSpan,int[] redundancyColumns,int[] totalColumns,int[] subTotalColumns,params int[] mergeColumns)
             {
                          //重构数据源,该数据源已插入小计和合计的空行
                          target.DataSource = PrepareNewDataSource(dataSource,keyColumnDataSourceName,dataSource.Columns.Count);
                          target.CurrentPageIndex = 0;
                          target.DataBind();
                          //填充小计和合计行
                          FillSummationRow(target,keyColumnIndex,totalColumnColSpan,subTotalColumnColSpan,redundancyColumns,totalColumns,subTotalColumns);   

                          //合并列以美化效果
                          MergeTextCellAtColumn(target,mergeColumns);  
  }
             protected static void FillSummationRow(DataGrid curGrid,int keyColumnIndex,int totalColumnColSpan,int subTotalColumnColSpan,int[] redundancyColumns,int[] totalColumns,int[] subTotalColumns)
             {
                          //获取绑定数据源
                          DataTable curTable = (DataTable)curGrid.DataSource;
                          int collectRowIndex = curTable.Rows.Count - 1;
                          MapCounter[] totalCounter = new MapCounter[totalColumns.Length];
                          for(int i = 0; i < totalColumns.Length; i ++)
                          {
                                       totalCounter[i] = new MapCounter(totalColumns[i]);
                          }
                          MapCounter[] subTotalCounter = new MapCounter[subTotalColumns.Length];
                          for(int i = 0; i < subTotalColumns.Length; i ++)
                          {
                                       subTotalCounter[i] = new MapCounter(subTotalColumns[i]);
                          }
                          MapCounter[] redundancyCounter = new MapCounter[redundancyColumns.Length];
                          for(int i = 0; i < redundancyCounter.Length; i ++)
                          {
                                       redundancyCounter[i] = new MapCounter(redundancyColumns[i]);
                          }
                          for( int i = 0; i < curGrid.Items.Count - 1; i ++)
                          {
                                       string keyText = curGrid.Items[i].Cells[keyColumnIndex].Text.Trim();
                                       bool same = false;
                                       //通过判断关键文本是否相同来确定是否需要进行累加
                                       if(i - 1 >= 0)
                                       {
                                                    same = curGrid.Items[i].Cells[keyColumnIndex].Text == curGrid.Items[i - 1].Cells[keyColumnIndex].Text;
                                       }
                                       //关键文本不同的,不包括小计行,对相关数值进行累加
                                       if(!same && !keyText.Trim().Equals("&nbsp;"))
                                       {
                                                    //冗余累加:所谓冗余,指出当前列所在的多行会因为内容相同而被合并,其参与计算的方式是以最终合并的单元值参与计算,如,2个值为40的单元被合并为一个40的rowspan = 2 的单元,那么仅有当前的40参与累计运算
                                                    foreach(MapCounter counter in redundancyCounter)
                                                    {
                                                                 counter.Add(SafeConvertToDecimal(curGrid.Items[i].Cells[counter.MapIndex].Text));
                                                    }     
                                       }
                                       //明细数据始终需要累计,但不包括小计行
                                       if(!keyText.Trim().Equals("&nbsp;"))
                                       {
                                                    //合计累加
                                                    foreach(MapCounter counter in totalCounter)
                                                    {
                                                                 counter.Add(SafeConvertToDecimal(curGrid.Items[i].Cells[counter.MapIndex].Text));
                                                    }
                                                    //小计累加
                                                    foreach(MapCounter counter in subTotalCounter)
                                                    {
                                                                 counter.Add(SafeConvertToDecimal(curGrid.Items[i].Cells[counter.MapIndex].Text));
                                                    }

                                       } 
                                       //构造小计行    
                                       if(keyText.Trim().Equals("&nbsp;"))
                                       {
                                                    curGrid.Items[i].Cells[0].Visible = true;     
                                                    curGrid.Items[i].Cells[0].ColumnSpan = subTotalColumnColSpan;
                                                    curGrid.Items[i].Cells[0].Text = "<b><font color ='#0033FF'>小计:</font></b>"; 
                                                    for(int j = 1; j <= subTotalColumnColSpan; j ++)
                                                    {
                                                                 curGrid.Items[i].Cells[j].Visible = false;
                                                    } 
                                                    foreach(MapCounter counter in subTotalCounter)
                                                    {
                                                                 curGrid.Items[i].Cells[counter.MapIndex].Text = "<b><font color ='#0033FF'>" + counter.Value.ToString() +"</font></b>";
                                                    }
                                                    //清空小计计数器
                                                    foreach(MapCounter counter in subTotalCounter)
                                                    {
                                                                 counter.Reset();
                                                    }
                                       }
    
                          }
   
                          //构造最终合计行   
                          curGrid.Items[collectRowIndex].Cells[0].Visible = true;   
                          curGrid.Items[collectRowIndex].Cells[0].ColumnSpan = totalColumnColSpan;
                          curGrid.Items[collectRowIndex].Cells[0].Text = "<b><font color ='#ff0066'>合计:</font></b>";
                          for(int j = 1; j <= totalColumnColSpan; j ++)
                          {
                                       curGrid.Items[collectRowIndex].Cells[j].Visible = false; 
                          }
                          foreach(MapCounter counter in redundancyCounter)
                          {
                                       curGrid.Items[collectRowIndex].Cells[counter.MapIndex].Text = "<b><font color ='#ff0066'>" + counter.Value.ToString() +"</font></b>";
                          }
                          foreach(MapCounter counter in totalCounter)
                          {
                                       curGrid.Items[collectRowIndex].Cells[counter.MapIndex].Text = "<b><font color ='#ff0066'>" + counter.Value.ToString() +"</font></b>";
                          }
  
             }
             protected static void MergeTextCellAtColumn(DataGrid curGrid,int columnIndex)
             {
                          DataGridItem  curItem = null;
                          DataGridItem  nextItem = null;
                          for (int r = 0; r < curGrid.Items.Count; r++)
                          {
                                       ///当前单元格
                                       curItem = curGrid.Items[r];
                                       ///其下单元格
                                       if(r + 1 < curGrid.Items.Count)
                                                    nextItem = curGrid.Items[r + 1];
                                       else
                                                    nextItem = null;
                                       string curValue = curItem == null ? string.Empty:curItem.Cells[columnIndex].Text;
                                       string nextValue = nextItem == null ? string.Empty:nextItem.Cells[columnIndex].Text;
                                       ///如果单元格内容相同
                                       if( curValue != string.Empty && nextValue != string.Empty && curValue == nextValue)
                                       {
                                                    ///设置其下单元格不可见
                                                    if(nextValue != null)nextItem.Cells[columnIndex].Visible = false;
                                                    ///如果当前单元格可见,则将其RowSpan + 1
                                                    if(curItem.Cells[columnIndex].Visible == true)
                                                    {
                                                                 curItem.Cells[columnIndex].RowSpan += 1;      
                                                    }
                                                    ///如果当前单元格不可见,则直接回溯到其上第一个可见单元格为止
                                                    else if(curItem.Cells[columnIndex].Visible == false)
                                                    {
                                                                 if(curItem.Cells[0].ColumnSpan > 1)
                                                                 {
                                                                              //证明是合计行,则需要跳过
                                                                 }
                                                                 else
                                                                 {
                                                                              int preRowIndex = r;
                                                                              while(preRowIndex >= 0 && curGrid.Items[preRowIndex].Cells[columnIndex].Visible == false)
                                                                              {
                                                                                           preRowIndex -= 1;
                                                                              }
                                                                              string preValue = curGrid.Items[preRowIndex].Cells[columnIndex].Text;
                                                                              if(curValue == preValue)
                                                                              {
                                                                                           ///将其上第一个可见单元格的RowSpan + 1
                                                                                           curGrid.Items[preRowIndex].Cells[columnIndex].RowSpan += 1;
                                                                              }
                                                                 }
                                                    }
                                       } 
                                       ///如果单元格内容不同
                                       else if(curValue != string.Empty && nextValue != string.Empty && curValue != nextValue)
                                       {
                                                    ///判断是否是临界行:上面的一行或多行与下面的一行或多行的对应单元格内容不同
                                                    if(curItem.Cells[columnIndex].Visible == false)
                                                    {
                                                                 if(curItem.Cells[0].ColumnSpan > 1  && curValue.Trim().Equals("&nbsp;"))
                                                                 {
                                                                              //证明是合计行,则需要跳过
                                                                 }
                                                                 else
                                                                 {
                                                                              int preRowIndex = r;
                                                                              while(preRowIndex >= 0 && curGrid.Items[preRowIndex].Cells[columnIndex].Visible == false)
                                                                              {
                                                                                           preRowIndex -= 1;
                                                                              }
                                                                              string preValue = curGrid.Items[preRowIndex].Cells[columnIndex].Text;
                                                                              if(curValue == preValue)
                                                                              {
                                                                                           ///将其上第一个可见单元格的RowSpan + 1
                                                                                           curGrid.Items[preRowIndex].Cells[columnIndex].RowSpan += 1;
                                                                              }
                                                                 }
                                                    }     
                                                    else
                                                    {
                                                                 ///非临界
                                                    }
                                       }
                                       ///数据列表的最后一行
                                       else if(r == curGrid.Items.Count - 1 && curItem.Cells[columnIndex].Visible == false)
                                       {
                                                    int preRowIndex = r;
                                                    while(preRowIndex >= 0 && curGrid.Items[preRowIndex].Cells[columnIndex].Visible == false)
                                                    {
                                                                 preRowIndex -= 1;
                                                    }
                                                    string preValue = curGrid.Items[preRowIndex].Cells[columnIndex].Text;
                                                    if(curValue == preValue)
                                                    {
                                                                 ///将其上第一个可见单元格的RowSpan + 1
                                                                 curGrid.Items[preRowIndex].Cells[columnIndex].RowSpan += 1;
                                                    }
                                       }
                          }
   
             } 
  
             protected static void MergeTextCellAtColumn(DataGrid curGrid,params int[] columns)
             {
                          foreach(int column in columns)
                          {
                                       MergeTextCellAtColumn(curGrid,column);
                          }
             }
             protected static DataTable PrepareNewDataSource(DataTable dataSource,string keyColumnDataSourceName,int columnCount)
             {
                          DataTable copy = dataSource.Copy();
                          for(int i = 0; i < copy.Rows.Count; i ++)
                          {
                                       string curText = copy.Rows[i][keyColumnDataSourceName].ToString();
                                       string preText = i - 1 > 0 ? copy.Rows[i - 1][keyColumnDataSourceName].ToString():string.Empty;
                                       if(curText == preText)
                                       {
                                                    continue;
                                       }
                                       else if(curText != preText && i - 1 > 0)
                                       {
                                                    //小计行
                                                    DataRow subtotal = dataSource.NewRow();
                                                    subtotal.ItemArray = PrepareItemArray(columnCount);
                                                    dataSource.Rows.InsertAt(subtotal,i);
                                       }
                          }
                          //最后小计行
                          DataRow lastSubtotal = dataSource.NewRow();    
                          lastSubtotal.ItemArray = PrepareItemArray(columnCount);
                          dataSource.Rows.Add(lastSubtotal); 
                          //最终合计行
                          DataRow totalRow = dataSource.NewRow();
                          totalRow.ItemArray = PrepareItemArray(columnCount);
                          dataSource.Rows.Add(totalRow); 
                          return dataSource;
             }
             protected static object[] PrepareItemArray(int columnCount)
             {
                          object[] objs = new object[columnCount];
                          for(int i = 0; i < objs.Length; i ++)
                          {
                                       objs[i] = DBNull.Value;
                          }
                          return objs;
             }
             protected static decimal SafeConvertToDecimal(object value)
             {
                          try
                          {
                                       return Convert.ToDecimal(value);
                          }
                          catch
                          {
                                       return 0;
                          }
             }   
  
 }


 //UI调用方式
 //获取数据源
 DataTable curDt = objPlan.QueryByYearDeptidProjcet(currYear,deptID,project);
 //调用实现
 PresentUtil.PreparePresent(DGList,curDt,1,"project",4,9,new int[]{5,6,7,8},new int[]{10,11,12,13,14},new int[]{10,11,12,13,14},new int[]{0,1,3,4,5,6,7,8});

 //数据源结构
 
 //输出效果展示

这篇关于Asp.Net中C#实现的DataGrid小计,合计和纵向合并的通用方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/420311

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

hdu2241(二分+合并数组)

题意:判断是否存在a+b+c = x,a,b,c分别属于集合A,B,C 如果用暴力会超时,所以这里用到了数组合并,将b,c数组合并成d,d数组存的是b,c数组元素的和,然后对d数组进行二分就可以了 代码如下(附注释): #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<que

2. c#从不同cs的文件调用函数

1.文件目录如下: 2. Program.cs文件的主函数如下 using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;namespace datasAnalysis{internal static

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操