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

相关文章

判断PyTorch是GPU版还是CPU版的方法小结

《判断PyTorch是GPU版还是CPU版的方法小结》PyTorch作为当前最流行的深度学习框架之一,支持在CPU和GPU(NVIDIACUDA)上运行,所以对于深度学习开发者来说,正确识别PyTor... 目录前言为什么需要区分GPU和CPU版本?性能差异硬件要求如何检查PyTorch版本?方法1:使用命

Python位移操作和位运算的实现示例

《Python位移操作和位运算的实现示例》本文主要介绍了Python位移操作和位运算的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 位移操作1.1 左移操作 (<<)1.2 右移操作 (>>)注意事项:2. 位运算2.1

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

Qt实现网络数据解析的方法总结

《Qt实现网络数据解析的方法总结》在Qt中解析网络数据通常涉及接收原始字节流,并将其转换为有意义的应用层数据,这篇文章为大家介绍了详细步骤和示例,感兴趣的小伙伴可以了解下... 目录1. 网络数据接收2. 缓冲区管理(处理粘包/拆包)3. 常见数据格式解析3.1 jsON解析3.2 XML解析3.3 自定义

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll

Java中的工具类命名方法

《Java中的工具类命名方法》:本文主要介绍Java中的工具类究竟如何命名,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java中的工具类究竟如何命名?先来几个例子几种命名方式的比较到底如何命名 ?总结Java中的工具类究竟如何命名?先来几个例子JD

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

利用python实现对excel文件进行加密

《利用python实现对excel文件进行加密》由于文件内容的私密性,需要对Excel文件进行加密,保护文件以免给第三方看到,本文将以Python语言为例,和大家讲讲如何对Excel文件进行加密,感兴... 目录前言方法一:使用pywin32库(仅限Windows)方法二:使用msoffcrypto-too

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删