|  | @@ -967,6 +967,7 @@ JpcFlowTabSrv.prototype.createNew = function() {
 | 
	
		
			
				|  |  |                  const actualPage = (page - 1) * me.multiCols + pi + 1;
 | 
	
		
			
				|  |  |                  // 2.1 Content-Tab
 | 
	
		
			
				|  |  |                  tabRstLst.push(me.outputContent(rptTpl, dataObj, actualPage, bands, unitFactor, controls, fonts, pi, $CURRENT_RPT, customizeCfg));
 | 
	
		
			
				|  |  | +                if (me.multiCols === 1) me.prepareBlankCellsForErase(tabRstLst[tabRstLst.length - 1]);
 | 
	
		
			
				|  |  |                  // 2.2 Column tab
 | 
	
		
			
				|  |  |                  tabRstLst.push(me.outputColumn(rptTpl, dataObj, actualPage, segIdx, segPageIdx, bands, unitFactor, pi, $CURRENT_RPT, customizeCfg));
 | 
	
		
			
				|  |  |                  // 2.3 Sum Seg
 | 
	
	
		
			
				|  | @@ -986,6 +987,112 @@ JpcFlowTabSrv.prototype.createNew = function() {
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |          return rst;
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  | +    JpcFlowTabResult.prepareBlankCellsForErase = function(contentCells) {
 | 
	
		
			
				|  |  | +        // 此方法过滤出符合要求的空白行cells,并初始化 pageBlankCellsForErase
 | 
	
		
			
				|  |  | +        const me = this;
 | 
	
		
			
				|  |  | +        const rstCells = [];
 | 
	
		
			
				|  |  | +        const tmpCells = [];
 | 
	
		
			
				|  |  | +        me.pageBlankCellsForErase = [];
 | 
	
		
			
				|  |  | +        // 1. 首先收集所有空cell
 | 
	
		
			
				|  |  | +        contentCells.forEach(cell => {
 | 
	
		
			
				|  |  | +            if (cell.Value === '') {
 | 
	
		
			
				|  |  | +                tmpCells.push(cell);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +        if (tmpCells.length > 0) {
 | 
	
		
			
				|  |  | +            // 2. 以top为基准归类所有同top位置的cells
 | 
	
		
			
				|  |  | +            const cellCache = {};
 | 
	
		
			
				|  |  | +            let maxCnt = 0;
 | 
	
		
			
				|  |  | +            tmpCells.forEach(cell => {
 | 
	
		
			
				|  |  | +                const preTop = cell.area[JV.PROP_TOP];
 | 
	
		
			
				|  |  | +                const cacheKey = `_${preTop}`;
 | 
	
		
			
				|  |  | +                if (!cellCache[cacheKey]) {
 | 
	
		
			
				|  |  | +                    cellCache[cacheKey] = [];
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                cellCache[cacheKey].push(cell);
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +            // 3. 剔除不完整的行(cell高度不一致、左右位置没有衔接、数量不正等)
 | 
	
		
			
				|  |  | +            const propKeys = [];
 | 
	
		
			
				|  |  | +            for (const key in cellCache) {
 | 
	
		
			
				|  |  | +                // 3.1 剔除前再排一次序
 | 
	
		
			
				|  |  | +                cellCache[key].sort(function(c1, c2) {
 | 
	
		
			
				|  |  | +                    return c1.area[JV.PROP_LEFT] - c2.area[JV.PROP_LEFT];
 | 
	
		
			
				|  |  | +                });
 | 
	
		
			
				|  |  | +                // 3.2 先剔除高度不一致、左右位置没衔接
 | 
	
		
			
				|  |  | +                let isAlign = true;
 | 
	
		
			
				|  |  | +                let preCell = cellCache[key][0];
 | 
	
		
			
				|  |  | +                if (maxCnt < cellCache[key].length) maxCnt = cellCache[key].length;
 | 
	
		
			
				|  |  | +                const cHeight = preCell.area[JV.PROP_BOTTOM] - preCell.area[JV.PROP_TOP];
 | 
	
		
			
				|  |  | +                for (let idx = 1; idx < cellCache[key].length; idx++) {
 | 
	
		
			
				|  |  | +                    const cH = cellCache[key][idx].area[JV.PROP_BOTTOM] - cellCache[key][idx].area[JV.PROP_TOP];
 | 
	
		
			
				|  |  | +                    if (preCell.area[JV.PROP_RIGHT] !== cellCache[key][idx].area[JV.PROP_LEFT] || cHeight !== cH) {
 | 
	
		
			
				|  |  | +                        isAlign = false;
 | 
	
		
			
				|  |  | +                        break;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                    preCell = cellCache[key][idx];
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                if (isAlign) propKeys.push(key);
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            // 3.3 再剔除数量不正的(这里的判断是有争议的,可能理论上应该是那种贴着MergeBorder的左右位置的为准,但后又想到一种特殊情况,左右带竖行输出的,这种判断不合适了
 | 
	
		
			
				|  |  | +            //     所以应该这样判断:上下位置要连续的,不能断节!),那么 propKeys 应该再做一次排序
 | 
	
		
			
				|  |  | +            propKeys.sort(function(key1, key2) {
 | 
	
		
			
				|  |  | +                let rst = 0;
 | 
	
		
			
				|  |  | +                const v1 = parseFloat(key1.slice(1, key1.length));
 | 
	
		
			
				|  |  | +                const v2 = parseFloat(key2.slice(1, key2.length));
 | 
	
		
			
				|  |  | +                rst = v1 - v2;
 | 
	
		
			
				|  |  | +                return rst;
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +            propKeys.forEach(propKey => {
 | 
	
		
			
				|  |  | +                if (maxCnt === cellCache[propKey].length) {
 | 
	
		
			
				|  |  | +                    rstCells.push(...cellCache[propKey]);
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        // console.log(rstCells);
 | 
	
		
			
				|  |  | +        me.pageBlankCellsForErase.push(...rstCells);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    JpcFlowTabResult.eraseBlankCells = function(rptTpl, pageItem) {
 | 
	
		
			
				|  |  | +        const me = this;
 | 
	
		
			
				|  |  | +        const liftUpCells = (cells, maxBottom, upHeight) => {
 | 
	
		
			
				|  |  | +            if (cells && cells.length > 0) {
 | 
	
		
			
				|  |  | +                cells.forEach(cell => {
 | 
	
		
			
				|  |  | +                    if (cell.area[JV.PROP_TOP] >= maxBottom) {
 | 
	
		
			
				|  |  | +                        cell.area[JV.PROP_TOP] -= upHeight;
 | 
	
		
			
				|  |  | +                        cell.area[JV.PROP_BOTTOM] -= upHeight;
 | 
	
		
			
				|  |  | +                    } else if (cell.area[JV.PROP_BOTTOM] > maxBottom) {
 | 
	
		
			
				|  |  | +                        // 未来可能会有那种特殊cell(如左右竖行): top在maxBottom之上,bottom在maxBottom之下,那么需要的是align bottom,减upHeight高度
 | 
	
		
			
				|  |  | +                        cell.area[JV.PROP_BOTTOM] -= upHeight;
 | 
	
		
			
				|  |  | +                    }
 | 
	
		
			
				|  |  | +                });
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        if (rptTpl[JV.NODE_FLOW_INFO][JV.PROP_ERASE_BLANK_ROWS] && me.pageBlankCellsForErase && me.pageBlankCellsForErase.length > 0) {
 | 
	
		
			
				|  |  | +            // 1. 确定好位置和高度
 | 
	
		
			
				|  |  | +            const cTop = me.pageBlankCellsForErase[0].area[JV.PROP_TOP];
 | 
	
		
			
				|  |  | +            const cBottom = me.pageBlankCellsForErase[me.pageBlankCellsForErase.length - 1].area[JV.PROP_BOTTOM];
 | 
	
		
			
				|  |  | +            const cHeight = cBottom - cTop;
 | 
	
		
			
				|  |  | +            // 2. 开始重新设置
 | 
	
		
			
				|  |  | +            // 2.1 剔除cells下的空行
 | 
	
		
			
				|  |  | +            me.pageBlankCellsForErase.forEach(eCell => {
 | 
	
		
			
				|  |  | +                const idx = pageItem.cells.indexOf(eCell);
 | 
	
		
			
				|  |  | +                if (idx >= 0) pageItem.cells.splice(idx, 1);
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +            me.pageBlankCellsForErase.splice(0, me.pageBlankCellsForErase.length);
 | 
	
		
			
				|  |  | +            // 2.2 边框位置提上
 | 
	
		
			
				|  |  | +            if (pageItem[JV.PROP_PAGE_MERGE_BORDER]) {
 | 
	
		
			
				|  |  | +                // pageItem[JV.PROP_PAGE_MERGE_BORDER][JV.PROP_TOP] -= cHeight;
 | 
	
		
			
				|  |  | +                pageItem[JV.PROP_PAGE_MERGE_BORDER][JV.PROP_BOTTOM] -= cHeight;
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +            // 2.3 cells其他位置提上
 | 
	
		
			
				|  |  | +            liftUpCells(pageItem[JV.PROP_CELLS], cBottom, cHeight);
 | 
	
		
			
				|  |  | +            // 2.4 签名位置调整(签名、日期、意见等)
 | 
	
		
			
				|  |  | +            liftUpCells(pageItem[JV.PROP_SIGNATURE_CELLS], cBottom, cHeight);
 | 
	
		
			
				|  |  | +            liftUpCells(pageItem[JV.PROP_SIGNATURE_DATE_CELLS], cBottom, cHeight);
 | 
	
		
			
				|  |  | +            liftUpCells(pageItem[JV.PROP_SIGNATURE_AUDIT_CELLS], cBottom, cHeight);
 | 
	
		
			
				|  |  | +            liftUpCells(pageItem[JV.PROP_INTERACT_CELLS], cBottom, cHeight);
 | 
	
		
			
				|  |  | +            liftUpCells(pageItem[JV.PROP_FIGURE_CELLS], cBottom, cHeight); // 这个用途不一样,提法不同
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  |      JpcFlowTabResult.combinePageCells = function(rstPageCells, verticalCombinePos, horizonCombinePos, controls, fonts) {
 | 
	
		
			
				|  |  |          // let me = this;
 | 
	
		
			
				|  |  |          // 备注:纵向合并要考虑以下因素:
 |