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

相关文章

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

Python脚本实现自动删除C盘临时文件夹

《Python脚本实现自动删除C盘临时文件夹》在日常使用电脑的过程中,临时文件夹往往会积累大量的无用数据,占用宝贵的磁盘空间,下面我们就来看看Python如何通过脚本实现自动删除C盘临时文件夹吧... 目录一、准备工作二、python脚本编写三、脚本解析四、运行脚本五、案例演示六、注意事项七、总结在日常使用

Java实现Excel与HTML互转

《Java实现Excel与HTML互转》Excel是一种电子表格格式,而HTM则是一种用于创建网页的标记语言,虽然两者在用途上存在差异,但有时我们需要将数据从一种格式转换为另一种格式,下面我们就来看看... Excel是一种电子表格格式,广泛用于数据处理和分析,而HTM则是一种用于创建网页的标记语言。虽然两

Git中恢复已删除分支的几种方法

《Git中恢复已删除分支的几种方法》:本文主要介绍在Git中恢复已删除分支的几种方法,包括查找提交记录、恢复分支、推送恢复的分支等步骤,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录1. 恢复本地删除的分支场景方法2. 恢复远程删除的分支场景方法3. 恢复未推送的本地删除分支场景方法4. 恢复

Java中Springboot集成Kafka实现消息发送和接收功能

《Java中Springboot集成Kafka实现消息发送和接收功能》Kafka是一个高吞吐量的分布式发布-订阅消息系统,主要用于处理大规模数据流,它由生产者、消费者、主题、分区和代理等组件构成,Ka... 目录一、Kafka 简介二、Kafka 功能三、POM依赖四、配置文件五、生产者六、消费者一、Kaf

Python将大量遥感数据的值缩放指定倍数的方法(推荐)

《Python将大量遥感数据的值缩放指定倍数的方法(推荐)》本文介绍基于Python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处理,并将所得处理后数据保存为新的遥感影像... 本文介绍基于python中的gdal模块,批量读取大量多波段遥感影像文件,分别对各波段数据加以数值处

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

使用Python实现在Word中添加或删除超链接

《使用Python实现在Word中添加或删除超链接》在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能,本文将为大家介绍一下Python如何实现在Word中添加或... 在Word文档中,超链接是一种将文本或图像连接到其他文档、网页或同一文档中不同部分的功能。通过添加超

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Window Server2016加入AD域的方法步骤

《WindowServer2016加入AD域的方法步骤》:本文主要介绍WindowServer2016加入AD域的方法步骤,包括配置DNS、检测ping通、更改计算机域、输入账号密码、重启服务... 目录一、 准备条件二、配置ServerB加入ServerA的AD域(test.ly)三、查看加入AD域后的变