浏览代码

TASK #3998 调整预览、打印、导出时的行间距更紧凑

TonyKang 3 年之前
父节点
当前提交
8311826bbd

+ 17 - 0
modules/reports/rpt_component/helper/jpc_helper_flow_tab.js

@@ -2,6 +2,23 @@ let JV = require('../jpc_value_define');
 let JpcCommonHelper = require('./jpc_helper_common');
 
 let JpcFlowTabHelper = {
+    getRowHeight: function(bands, rptTpl, isEx) {
+        let rst = 0;
+        let FLOW_INFO_STR = (!isEx)?JV.NODE_FLOW_INFO:JV.NODE_FLOW_INFO_EX;
+        let tab = rptTpl[FLOW_INFO_STR][JV.NODE_FLOW_CONTENT];
+        let band = bands[tab[JV.PROP_BAND_NAME]];
+        if (band) {
+            let maxFieldMeasure = 1.0;
+            if (JV.CAL_TYPE_ABSTRACT === JpcCommonHelper.getPosCalculationType(tab[JV.PROP_CALCULATION])) {
+                let unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
+                maxFieldMeasure = 1.0 * rptTpl[FLOW_INFO_STR][JV.NODE_FLOW_CONTENT][JV.PROP_CMN_HEIGHT] * unitFactor;
+            } else {
+                maxFieldMeasure = (band.Bottom - band.Top) * rptTpl[FLOW_INFO_STR][JV.NODE_FLOW_CONTENT][JV.PROP_CMN_HEIGHT] / JV.HUNDRED_PERCENT;
+            }
+            rst = maxFieldMeasure;
+        }
+        return rst;
+    },
     getMaxRowsPerPage: function(bands, rptTpl, isEx) {
         let rst = 1;
         let FLOW_INFO_STR = (!isEx)?JV.NODE_FLOW_INFO:JV.NODE_FLOW_INFO_EX;

+ 55 - 1
modules/reports/rpt_component/jpc_flow_tab.js

@@ -410,7 +410,7 @@ JpcFlowTabSrv.prototype.createNew = function(){
                         let chkFontHeight = 12;
                         if (font) {
                             chkFontName = font[JV.FONT_PROPS[0]];
-                            chkFontHeight = font[JV.FONT_PROPS[JV.FONT_PROP_IDX_HEIGHT]];
+                            chkFontHeight = parseFloat(font[JV.FONT_PROPS[JV.FONT_PROP_IDX_HEIGHT]]);
                         }
                         let hasSplitStr = false, splitStrArr = [];
                         let accAmt = 0;
@@ -425,6 +425,20 @@ JpcFlowTabSrv.prototype.createNew = function(){
                             }
                         }
                         if (accAmt > rst) rst = accAmt;
+                        if (rst > 3) {
+                            // 新优化,计算实际能显示完的真正行数
+                            const rowHeight = JpcFlowTabHelper.getRowHeight(bands, rptTpl, me.isEx);
+                            let tmpFV = ((chkFontHeight + JV.CLOSE_OUTPUT_ROW_BUFFER) * rst) / rowHeight;
+                            let tmpAmt = Math.floor(tmpFV);
+                            // tmpAmt += Math.ceil((tmpFV - tmpAmt) / 0.5);
+                            // if (tmpFV - tmpAmt >= 0.5 && rst > 6) {
+                            //     tmpAmt++;
+                            // }
+                            if (Math.ceil(tmpFV) > tmpAmt) {
+                                tmpAmt++;
+                            }
+                            rst = tmpAmt;
+                        }
                         // if (hasSplitStr && outputType !== JV.OUTPUT_TYPE_EXCEL) {
                         if (hasSplitStr) {
                             let newValArr = [];
@@ -1300,11 +1314,51 @@ JpcFlowTabSrv.prototype.createNew = function(){
             if (showText) {
                 textArr = textArr.concat(showText.split('|'));
             }
+            /*
             if (contentValInfo[3] < textArr.length && contentValInfo[3] >= 0) {
                 showText = textArr[contentValInfo[3]];
             } else {
                 showText = '';
             }
+            /*/
+            // 因新逻辑要优化自动行高,不再是一个折行占用1row,而是: 
+            // a. 根据实际情况,设置了一个实际的行数值(比如共有10行,根据行高情况,可能只设置了6行的高度,在setupAutoHeightData方法里处理)
+            // b. 这里最大的难题在于跨页分配(预估会有来回调整,目前采用按比例分配原则)
+            // c. 还有个问题就是多个自动行高指标的问题
+            const ACT_ROWS = contentValInfo[4]; //经实际计算,能容纳所有数据的实际行数
+            const CURRENT_ROW = contentValInfo[3]; //从0开始
+            const QUOTA_Rate = textArr.length / ACT_ROWS; //每行显示的加权系数(超过2的话,表示给的行高太多了,需要另外一些特殊处理,后期有需要再加)
+            if (textArr.length <= 3 || ACT_ROWS > textArr.length) {
+                //表示这个一定是附属的autoheight指标,或者数据就只有3行(假如数据3行精简成2行,但刚好处于分页状态,那么无论是前一页或后一页,显示上都很纠结(多出来的一行放哪好?),所以新逻辑的起点要3行以上,少了就不折腾了,老老实实地一个萝卜一个坑)
+                if (CURRENT_ROW < textArr.length && CURRENT_ROW >= 0) {
+                    showText = textArr[CURRENT_ROW];
+                } else {
+                    showText = '';
+                }
+            } else {
+                //这里不管是不是附属autoheight指标,有足够的条件单独处理
+                if (QUOTA_Rate >= 2) {
+                    //压缩超过一半空间的话,说明给的行高度太高了,需要另外一些特殊处理,后期有需要再加
+                } else {
+                    //正常的压缩比例
+                    let startIdx = 0, endIdx = 0;
+                    if (CURRENT_ROW > 0) {
+                        endIdx = Math.round((CURRENT_ROW + 1) * QUOTA_Rate) - 1;
+                        let preEndIdx = 0;
+                        if (CURRENT_ROW > 1) {
+                            //重定位 preEndIdx
+                            preEndIdx = Math.round(CURRENT_ROW * QUOTA_Rate) - 1;
+                        }
+                        startIdx = preEndIdx + 1;
+                    }
+                    //按比例分配
+                    showText = textArr[startIdx];
+                    for (let idx = startIdx + 1; idx <= endIdx; idx++) {
+                        showText += `|${textArr[idx]}`;
+                    }
+                }
+            }
+            //*/
             let rst = JpcCommonOutputHelper.createCommonOutput(tab_field, showText, controls);
             rst[JV.PROP_AREA] = JpcAreaHelper.outputArea(tab_field[JV.PROP_AREA], band, unitFactor, rows, rowIdx, cols, colIdx, me.multiCols, multiColIdx, true, false);
             rst[JV.PROP_IS_AUTO_HEIGHT] = true;

+ 1 - 0
public/web/rpt_value_define.js

@@ -224,6 +224,7 @@ const JV = {
     CONTROL_PROP_IDX_VERTICAL_EXCEL: 5,
     CONTROL_PROP_IDX_SHRINK_FIRST: 6,
     CONTROL_PROP_IDX_CLOSE_OUTPUT: 7,
+    CLOSE_OUTPUT_ROW_BUFFER: 4,
     BORDER_STYLE_PROPS: ["LineWeight", "DashStyle", "Color"],
     PROP_LINE_WEIGHT: "LineWeight",
     PROP_DASH_STYLE: "DashStyle",

+ 33 - 15
web/building_saas/report/js/jpc_output.js

@@ -125,6 +125,13 @@ let JpcCanvasOutput = {
             }
             return rst;
         }
+        function _chkIfCloseOutput(control, actLines, area, fontHeight) {
+            let rst = false;
+            if (control.CloseOutput === 'T' && actLines > 1) {
+                rst = true;
+            }
+            return rst;
+        }
         function private_drawText(val, area, font, control) {
             let dftFontHeight = 12;
             let output = [];
@@ -318,27 +325,38 @@ let JpcCanvasOutput = {
                     }
                 }
 
-                if (font) {
-                    let dftFontHeight = parseFloat(font[JV.FONT_PROPS[1]]);
-                    let dftOthers = "";
-                    let dftFontBold = font[JV.FONT_PROPS[3]];
-                    if (dftFontBold && dftFontBold === 'T') {
-                        dftOthers = "bold " + dftOthers ;
-                    }
-                    let dftFontItalic = font[JV.FONT_PROPS[4]];
-                    if (dftFontItalic && dftFontItalic === 'T') {
-                        dftOthers = dftOthers + "italic ";
-                    }
-                    dftFontHeight = me.scaleFactor * dftFontHeight;
-                    ctx.font = dftOthers + dftFontHeight + "px " + font[JV.PROP_NAME];
+                let dftFontHeight = parseFloat(font[JV.FONT_PROPS[1]]);
+                let dftOthers = "";
+                let dftFontBold = font[JV.FONT_PROPS[3]];
+                if (dftFontBold && dftFontBold === 'T') {
+                    dftOthers = "bold " + dftOthers ;
+                }
+                let dftFontItalic = font[JV.FONT_PROPS[4]];
+                if (dftFontItalic && dftFontItalic === 'T') {
+                    dftOthers = dftOthers + "italic ";
                 }
+                dftFontHeight = me.scaleFactor * dftFontHeight;
+                ctx.font = dftOthers + dftFontHeight + "px " + font[JV.PROP_NAME];
+            // if (font) {
+            //     }
                 _splitValues(cell, control, values, ctx);
 
                 let height = cell[JV.PROP_AREA][JV.PROP_BOTTOM] - cell[JV.PROP_AREA][JV.PROP_TOP];
                 let area = [cell[JV.PROP_AREA][JV.PROP_LEFT] + me.offsetX, cell[JV.PROP_AREA][JV.PROP_TOP] + me.offsetY, cell[JV.PROP_AREA][JV.PROP_RIGHT] + me.offsetX, cell[JV.PROP_AREA][JV.PROP_BOTTOM] + me.offsetY];
+                //这里增加 ‘紧密输出’ 处理:在cell的输出空间划分出上下空间,中间行的输出间隔只有4个像素(要考虑与导出excel一致性,不能少了)
+                const isCloseOutput = _chkIfCloseOutput(control, values.length, area, dftFontHeight);
+                let closeTopOffset = 0;
+                if (isCloseOutput) {
+                    closeTopOffset = (height - (dftFontHeight + 4) * values.length) / 2;
+                }
                 for (let i = 0; i < values.length; i++) {
-                    area[JV.IDX_TOP] = cell[JV.PROP_AREA][JV.PROP_TOP] + i * (height / values.length) + me.offsetY;
-                    area[JV.IDX_BOTTOM] = cell[JV.PROP_AREA][JV.PROP_TOP] + (i + 1) * (height / values.length) + me.offsetY;
+                    if (isCloseOutput) {
+                        area[JV.IDX_TOP] = cell[JV.PROP_AREA][JV.PROP_TOP] + closeTopOffset + i *(dftFontHeight + 4) + me.offsetY;
+                        area[JV.IDX_BOTTOM] = cell[JV.PROP_AREA][JV.PROP_TOP] + closeTopOffset + (i + 1) *(dftFontHeight + 4) + me.offsetY;
+                    } else {
+                        area[JV.IDX_TOP] = cell[JV.PROP_AREA][JV.PROP_TOP] + i * (height / values.length) + me.offsetY;
+                        area[JV.IDX_BOTTOM] = cell[JV.PROP_AREA][JV.PROP_TOP] + (i + 1) * (height / values.length) + me.offsetY;
+                    }
                     if (values[i] === null || values[i] === undefined || values[i] === 'null') {
                         values[i] = "";
                     }

+ 32 - 13
web/building_saas/report/js/rpt_jspdf.js

@@ -160,6 +160,14 @@ let JpcJsPDFHelper = {
             }
         }
 
+        function _chkIfCloseOutput(control, actLines, area, fontHeight) {
+            let rst = false;
+            if (control.CloseOutput === 'T' && actLines > 1) {
+                rst = true;
+            }
+            return rst;
+        }
+
         function private_drawCellText(doc, ctx, cell, fonts, controls) {
             if (cell[JV.PROP_VALUE] !== undefined && cell[JV.PROP_VALUE] !== null) {
                 // let values = ("" + cell[JV.PROP_VALUE]).split('|');
@@ -194,22 +202,33 @@ let JpcJsPDFHelper = {
                 let area = [cell[JV.PROP_AREA][JV.PROP_LEFT] + offsetX, cell[JV.PROP_AREA][JV.PROP_TOP] + offsetY, cell[JV.PROP_AREA][JV.PROP_RIGHT] + offsetX, cell[JV.PROP_AREA][JV.PROP_BOTTOM] + offsetY];
                 let ah = height;
                 let restTopH = 0, restBottomH = 0;
-                if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_CLOSE_OUTPUT]] === 'T') {
-                    ah = (parseFloat(font[JV.FONT_PROPS[1]]) + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM]) * values.length;
-                    let restH = height - ah;
-                    if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] === 'center') {
-                        restTopH = restH / 2;
-                        restBottomH = restH / 2;
-                    } else if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] === 'bottom') {
-                        restBottomH = restH;
-                    } else {
-                        restTopH = restH;
-                    }
+                let dftFontHeight = parseFloat(font[JV.FONT_PROPS[1]]);
+                const isCloseOutput = _chkIfCloseOutput(control, values.length, area, dftFontHeight);
+                let closeTopOffset = 0;
+                if (isCloseOutput) {
+                    closeTopOffset = (height - (dftFontHeight + 4) * values.length) / 2;
                 }
+                // if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_CLOSE_OUTPUT]] === 'T') {
+                //     ah = (parseFloat(font[JV.FONT_PROPS[1]]) + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP] + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM]) * values.length;
+                //     let restH = height - ah;
+                //     if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] === 'center') {
+                //         restTopH = restH / 2;
+                //         restBottomH = restH / 2;
+                //     } else if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] === 'bottom') {
+                //         restBottomH = restH;
+                //     } else {
+                //         restTopH = restH;
+                //     }
+                // }
                 let spaceIdxArr = [];
                 for (let i = 0; i < values.length; i++) {
-                    area[JV.IDX_TOP] = cell[JV.PROP_AREA][JV.PROP_TOP] + i * (ah / values.length) + offsetY + restTopH;
-                    area[JV.IDX_BOTTOM] = cell[JV.PROP_AREA][JV.PROP_TOP] + (i + 1) * (ah / values.length) + offsetY + restBottomH;
+                    if (isCloseOutput) {
+                        area[JV.IDX_TOP] = cell[JV.PROP_AREA][JV.PROP_TOP] + closeTopOffset + i * (dftFontHeight + 4) + offsetY;
+                        area[JV.IDX_BOTTOM] = cell[JV.PROP_AREA][JV.PROP_TOP] + closeTopOffset + (i + 1) * (dftFontHeight + 4) + offsetY;
+                    } else {
+                        area[JV.IDX_TOP] = cell[JV.PROP_AREA][JV.PROP_TOP] + i * (ah / values.length) + offsetY + restTopH;
+                        area[JV.IDX_BOTTOM] = cell[JV.PROP_AREA][JV.PROP_TOP] + (i + 1) * (ah / values.length) + offsetY + restBottomH;
+                    }
                     if (values[i] === null || values[i] === undefined || values[i] === 'null') {
                         values[i] = "";
                     }

+ 21 - 2
web/building_saas/report/js/rpt_print.js

@@ -335,13 +335,32 @@ function buildText(destRst, cell, font, control, offsetX, offsetY, adjustY, canv
             }
         }
     };
+
+    const isCloseOutput = _chkIfCloseOutput(control, values.length, area, orgFontHeight);
+    let closeTopOffset = 0;
+    if (isCloseOutput) {
+        closeTopOffset = (height - (orgFontHeight + 4) * values.length) / 2;
+    }
     for (let vidx = 0; vidx < values.length; vidx++) {
-        area[JV.IDX_TOP] = top + vidx * (height / values.length);
-        area[JV.IDX_BOTTOM] = top + (vidx + 1) * (height / values.length);
+        if (isCloseOutput) {
+            area[JV.IDX_TOP] = top + closeTopOffset + vidx *(orgFontHeight + 4);
+            area[JV.IDX_BOTTOM] = top + closeTopOffset + (vidx + 1) *(orgFontHeight + 4);
+        } else {
+            area[JV.IDX_TOP] = top + vidx * (height / values.length);
+            area[JV.IDX_BOTTOM] = top + (vidx + 1) * (height / values.length);
+        }
         inner_draw_text(values[vidx]);
     }
 }
 
+function _chkIfCloseOutput(control, actLines, area, fontHeight) {
+    let rst = false;
+    if (control.CloseOutput === 'T' && actLines > 1) {
+        rst = true;
+    }
+    return rst;
+}
+
 function private_splitString(strVal, areaWidth, ctx) {
     let rst = [];
     if (strVal) {