找回密码
 立即注册

QQ登录

只需一步,快速开始

Clark.Pan 讲师达人认证 悬赏达人认证 SpreadJS 开发认证

超级版主

200

主题

9899

帖子

1万

积分

超级版主

Rank: 8Rank: 8

积分
15535

讲师达人悬赏达人微信认证勋章SpreadJS 认证SpreadJS 高级认证元老葡萄

Clark.Pan 讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2020-3-26 11:47  /   查看:4010  /  回复:7
上回介绍了byRow,byColumn的算法实现,这期我们介绍剩下的byRowColumn,byColumnRow的实现逻辑
首先byRowColumn,byColumnRow的实现需要基于byRow,byColumn的算法实现,具体操作可以参考上一期的内容:如何在导出Excel时带有自动合并(AutoMerge)效果(一)
byRowColumn:
byRowColumn的原理就是在基于按行去合并的基础上,在按列合并所有可合并的单元格,也就是行优先的行列合并。
所以首先需要做的的byRow的操作,在byRow的基础上再循环判断进行byColumn的操作。
  1.   function spanbyrowcolumn(range){
  2.       var spans = spanbyrow(range);
  3.       for(var i=0;i<spans.length;i++){
  4.           var row = spans[i].row;
  5.           var col = spans[i].col;
  6.           var rowCount = spans[i].rowCount;
  7.           var colCount = spans[i].colCount;
  8.           var sourceValue = sheet.getValue(spans[i].row,spans[i].col);
  9.           var spanRowCount = rowCount;
  10.           for(var j=spans[i].row+spans[i].rowCount;j<range.row+range.rowCount;j++){
  11.               var spanFlag = true;
  12.               for(var k=spans[i].col;k<spans[i].col+spans[i].colCount;k++){
  13.                   var tempSpan = findSpan(j,k);
  14.                   if(tempSpan && tempSpan.colCount != colCount){
  15.                       spanFlag = false;
  16.                       break;
  17.                   }
  18.                   if(sourceValue!=sheet.getValue(j,k)){
  19.                       spanFlag = false;
  20.                       break;
  21.                   }
  22.               }
  23.               if(spanFlag){
  24.                   spanRowCount++
  25.                   sheet.removeSpan(j,col);
  26.               }else{
  27.                   break;
  28.               }
  29.           }
  30.           if(spanRowCount>1){
  31.               var compareSpan = findSpan(row,col);
  32.               var currentSpan = new GC.Spread.Sheets.Range(row,col,spanRowCount,colCount);
  33.               if(compareSpan !=null){
  34.                   if(!containSpan(currentSpan,compareSpan)){
  35.                       sheet.removeSpan(row,col);
  36.                       sheet.addSpan(row,col,spanRowCount,colCount);
  37.                   }
  38.               }else{
  39.                   sheet.removeSpan(row,col);
  40.                   sheet.addSpan(row,col,spanRowCount,colCount);
  41.               }
  42.           }
  43.       }
  44.                 }
复制代码

这里还需要一些对特殊情况的判断,例如在做列合并的时候上下两列如果都是合并单元格的处理方式,边界的判断等。
合并的结果如下:
image.png319254149.png
之后导出Excel,结果如下:
image.png265929259.png
byColumnRow:
原理与byRowColumn刚好相反,先做列合并再做行合并,核心代码如下:
  1. function spanbycolumnrow(range){
  2.     var spans = spanbycolumn(range);
  3.     for(var i=0;i<spans.length;i++){
  4.         var row = spans[i].row;
  5.         var col = spans[i].col;
  6.         var rowCount = spans[i].rowCount;
  7.         var colCount = spans[i].colCount;
  8.         var sourceValue = sheet.getValue(spans[i].row,spans[i].col);
  9.         var spanColCount = colCount;
  10.         for(var j=spans[i].col+spans[i].colCount;j<range.col+range.colCount;j++){
  11.             var spanFlag = true;
  12.             for(var k=spans[i].row;k<spans[i].row+spans[i].rowCount;k++){
  13.                 var currentValue = sheet.getValue(k,j);
  14.                 if(sourceValue!=sheet.getValue(k,j)){
  15.                     spanFlag = false;
  16.                     break;
  17.                 }
  18.             }
  19.             if(spanFlag){
  20.                 spanColCount++
  21.                 sheet.removeSpan(row,j);
  22.             }else{
  23.                 break;
  24.             }
  25.         }
复制代码
合并的结果如下:
image.png203631285.png
导出后结果如下图所示:
image.png745611572.png

以上就是4种合并方式的讲解,具体可以参考附件的demo(需要替换引用的相关js为本地的资源)。
上述的算法仅供参考,只是基于思路的基本实现,没有经过过多的优化,具体应用可以在此基础上再进行一些优化来提升程序的健壮性和性能。

image.png785159606.png

automerge导出.html

11.15 KB, 下载次数: 92

7 个回复

倒序浏览
it_idgcapital
注册会员   /  发表于:2020-3-26 13:15:29
沙发
6666,谢谢分享
回复 使用道具 举报
favori讲师达人认证
金牌服务用户   /  发表于:2020-6-16 17:52:47
板凳
回复 使用道具 举报
果果xxxxk
初级会员   /  发表于:2021-5-14 14:30:15
地板
楼主可以提供下findSpan的实现方法吗?
回复 使用道具 举报
Clark.Pan讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2021-5-14 15:34:26
5#
在帖子1楼的最下面,附件demo里面有,您可以下下来仔细详看

回复 使用道具 举报
果果xxxxk
初级会员   /  发表于:2021-5-15 13:20:13
6#
Clark.Pan 发表于 2021-5-14 15:34
在帖子1楼的最下面,附件demo里面有,您可以下下来仔细详看

看到了,感谢
回复 使用道具 举报
Derrick.Jiao讲师达人认证 悬赏达人认证 SpreadJS 开发认证
论坛元老   /  发表于:2021-5-17 08:54:32
7#
回复 使用道具 举报
Ellia.DuanSpreadJS 开发认证
超级版主   /  发表于:2023-11-3 16:49:15
8#
我们在新版本中已经有public 接口实现了这部分内容,欢迎大家点击下面这个链接查看测试:
https://gcdn.grapecity.com.cn/showtopic-198053-1-1.html
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部