Browse Source

report template preview

TonyKang 8 years ago
parent
commit
4e97a4682c

+ 1 - 1
modules/reports/models/rpt_tpl_data_demo.js

@@ -12,7 +12,7 @@ let RptTemplateDataSchema = new Schema({
     "detail_data": Array
 });
 
-let TemplateData = smartcostdb.model("temp_tpl_data", RptTemplateDataSchema, "temp_tpl_data");
+let TemplateData = smartcostdb.model("temp_tpl_data", RptTemplateDataSchema, "rpt_temp_tpl_data");
 
 class RplTplDataDAO{
     //根据id获取临时数据

+ 1 - 1
public/web/rpt_value_define.js

@@ -1,7 +1,7 @@
 /**
  * Created by Tony on 2017/6/7.
  */
-var JV = {
+let JV = {
     NODE_CROSS_INFO: "交叉表_信息",
     NODE_CROSS_ROW: "交叉行",
     NODE_CROSS_COL: "交叉列",

+ 1 - 1
web/maintain/report/js/jpc_output.js

@@ -1,5 +1,5 @@
 /** Created by Tony on 2016/12/2. */
-JpcCanvasOutput = {
+let JpcCanvasOutput = {
     offsetX: 10,
     offsetY: 10,
     cleanCanvas: function (canvas) {

+ 1 - 1
web/maintain/report/js/jpc_output_value_define.js

@@ -2,7 +2,7 @@
  * Created by Tony on 2017/1/4.
  */
 
-var JV = {
+let JV = {
     NODE_MAIN_INFO: "主信息",
     NODE_PAGE_INFO: "打印页面_信息",
     NODE_MARGINS: "页边距",

+ 10 - 2
web/maintain/report/js/rpt_tpl_main.js

@@ -4,6 +4,7 @@ let rptTplObj = {
     iniPage: function() {
         let me = this
         zTreeOprObj.getReportTemplateTree(RT.GrpType.CONSTRUCT);
+        preview_util.drawBorder($("#tplCanvas")[0]);
     }
 }
 
@@ -284,7 +285,7 @@ let zTreeOprObj = {
                 $('#rptTypeSelectionModal').modal('show');
             } else {
                 //显示报表模板
-                me.getRefTpl();
+                me.chkAndRreshRefTpl();
             }
         }
     },
@@ -302,7 +303,7 @@ let zTreeOprObj = {
             );
         }
     },
-    getRefTpl: function() {
+    chkAndRreshRefTpl: function() {
         let me = zTreeOprObj, params = {};
         if (me.currentNode && me.currentNode.nodeType == RT.NodeType.TEMPLATE && me.currentNode.refId > 0) {
             if (!(me.currentNode.rptTpl)) {
@@ -317,6 +318,13 @@ let zTreeOprObj = {
             }
         }
     },
+    getRefTpl: function() {
+        let me = zTreeOprObj, rst = null;
+        if (me.currentNode && me.currentNode.nodeType == RT.NodeType.TEMPLATE && me.currentNode.refId > 0) {
+            rst = me.currentNode.rptTpl
+        }
+        return rst;
+    },
     refreshTplView: function (rptTpl) {
         let me = zTreeOprObj;
         if (rptTpl) {

+ 148 - 0
web/maintain/report/js/rpt_tpl_preview_util.js

@@ -0,0 +1,148 @@
+/**
+ * Created by Tony on 2017/7/3.
+ * 报表模板预览工具类
+ */
+
+let preview_util = {
+    offsetX: 0,
+    offsetY: 0,
+    drawBorder: function (canvas) {
+        let me = this;
+        if (canvas) {
+            let size = [];
+            size[0] = canvas.width - 1;
+            size[1] = canvas.height - 1;
+            let ctx = canvas.getContext("2d");
+            ctx.save();
+            ctx.beginPath();
+            ctx.translate(0.5,0.5);
+            ctx.lineWidth = 1;
+            ctx.moveTo(me.offsetX, me.offsetY);
+            ctx.lineTo(size[0] + me.offsetX, me.offsetY);
+            ctx.lineTo(size[0] + me.offsetX, size[1] + me.offsetY);
+            ctx.lineTo(me.offsetX, size[1] + me.offsetY);
+            ctx.lineTo(me.offsetX, me.offsetY);
+            ctx.stroke();
+            ctx.restore();
+            ctx.fillStyle="black";
+            ctx.fillRect(size[0] + me.offsetX,10 + me.offsetY,10,size[1]);
+            ctx.fillRect(10 + me.offsetX,size[1] + me.offsetY,size[0],10);
+        }
+    },
+    preview: function(canvas, rptTpl) {
+        let me = this, resolution= [96,96], size = null, shrinkFactor = 1;
+
+        if (!(rptTpl)) return;
+
+        let ctx = canvas.getContext("2d");
+        let pageSize = rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_PAGE_SIZE];
+        let sizeIdx = JV.PAGES_SIZE_STR.indexOf(pageSize);
+        if (sizeIdx >= 0) {
+            size = JV.PAGES_SIZE[sizeIdx];
+        } else {
+            size = JV.PAGES_SIZE[0];
+        }
+        if (rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE || rptTpl[JV.NODE_MAIN_INFO][JV.NODE_PAGE_INFO][JV.PROP_ORIENTATION] === JV.ORIENTATION_LANDSCAPE_CHN) {
+            let ts = size[0];
+            size[0] = size[1];
+            size[1] = ts;
+        }
+        if (size[0] > size[1]) {
+            shrinkFactor = 1.0 * canvas.width / (size[0] * resolution[0]);
+        } else {
+            shrinkFactor = 1.0 * canvas.height / (size[1] * resolution[1]);
+        }
+
+        let private_translateUnit = function(unitStr) {
+            let me = this, rst = 1.0;
+            if (unitStr) {
+                if (JV.MEASUREMENT.PIXEL.indexOf(unitStr) >= 0) {
+                    rst = 1.0;
+                } else if (JV.MEASUREMENT.CM.indexOf(unitStr) >= 0) {
+                    rst = 1.0 * resolution[0] / 2.54;
+                } else if (JV.MEASUREMENT.INCH.indexOf(unitStr) >= 0) {
+                    rst = 1.0 * resolution[0];
+                }
+            }
+            return rst;
+        };
+
+        let private_getReportArea = function(rptTpl, unitFactor) {
+            let rst = [];
+            rst.push(unitFactor * rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_LEFT]);
+            rst.push(unitFactor * rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_TOP]);
+            rst.push(size[0] * resolution[0] - unitFactor * rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_RIGHT]);
+            rst.push(size[1] * resolution[0] - unitFactor * rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS][JV.PROP_BOTTOM]);
+            return rst;
+        };
+
+        let private_setupBandArea = function(band, parentArea) {
+            let rstArea = [].concat(parentArea);
+            switch (JV.LAYOUT.indexOf(band[JV.BAND_PROP_ALIGNMENT])) {
+                case JV.LAYOUT_TOP:
+                    if (band[JV.PROP_CALCULATION] == JV.CAL_TYPE_ABSTRACT) {
+                        rstArea[JV.IDX_BOTTOM] = rstArea[JV.IDX_TOP] + unitFactor * parseFloat(band[JV.BAND_PROP_HEIGHT]);
+                    } else {
+                        rstArea[JV.IDX_BOTTOM] = rstArea[JV.IDX_TOP] + (rstArea[JV.IDX_BOTTOM] - rstArea[JV.IDX_TOP]) * parseFloat(band[JV.BAND_PROP_HEIGHT]) / 100;
+                    }
+                    parentArea[JV.IDX_TOP] = rstArea[JV.IDX_BOTTOM];
+                    break;
+                case JV.LAYOUT_BOTTOM:
+                    if (band[JV.PROP_CALCULATION] == JV.CAL_TYPE_ABSTRACT) {
+                        rstArea[JV.IDX_TOP] = rstArea[JV.IDX_BOTTOM] - unitFactor * parseFloat(band[JV.BAND_PROP_HEIGHT]);
+                    } else {
+                        rstArea[JV.IDX_TOP] = rstArea[JV.IDX_BOTTOM] - (rstArea[JV.IDX_BOTTOM] - rstArea[JV.IDX_TOP]) * parseFloat(band[JV.BAND_PROP_HEIGHT]) / 100;
+                    }
+                    parentArea[JV.IDX_BOTTOM] = rstArea[JV.IDX_TOP];
+                    break;
+                case JV.LAYOUT_LEFT:
+                    if (band[JV.PROP_CALCULATION] == JV.CAL_TYPE_ABSTRACT) {
+                        rstArea[JV.IDX_RIGHT] = rstArea[JV.IDX_LEFT] + unitFactor * parseFloat(band[JV.BAND_PROP_WIDTH]);
+                    } else {
+                        rstArea[JV.IDX_RIGHT] = rstArea[JV.IDX_LEFT] + (rstArea[JV.IDX_RIGHT] - rstArea[JV.IDX_LEFT]) * parseFloat(band[JV.BAND_PROP_WIDTH]) / 100;
+                    }
+                    parentArea[JV.IDX_LEFT] = rstArea[JV.IDX_RIGHT];
+                    break;
+                case JV.LAYOUT_RIGHT:
+                    if (band[JV.PROP_CALCULATION] == JV.CAL_TYPE_ABSTRACT) {
+                        rstArea[JV.IDX_LEFT] = rstArea[JV.IDX_RIGHT] - unitFactor * parseFloat(band[JV.BAND_PROP_WIDTH]);
+                    } else {
+                        rstArea[JV.IDX_LEFT] = rstArea[JV.IDX_RIGHT] - (rstArea[JV.IDX_RIGHT] - rstArea[JV.IDX_LEFT]) * parseFloat(band[JV.BAND_PROP_WIDTH]) / 100;
+                    }
+                    parentArea[JV.IDX_RIGHT] = rstArea[JV.IDX_LEFT];
+                    break;
+            }
+            return rstArea;
+        };
+        let private_showBand = function (band, myArea) {
+            //1. draw band border
+            ctx.save();
+            ctx.beginPath();
+            ctx.translate(0.5,0.5);
+            ctx.lineWidth = 1;
+            ctx.setLineDash([3, 6]);
+            ctx.moveTo((me.offsetX + myArea[JV.IDX_LEFT]) * shrinkFactor, (me.offsetY + myArea[JV.IDX_TOP]) * shrinkFactor );
+            ctx.lineTo((me.offsetX + myArea[JV.IDX_RIGHT]) * shrinkFactor, (me.offsetY + myArea[JV.IDX_TOP]) * shrinkFactor);
+            ctx.lineTo((me.offsetX + myArea[JV.IDX_RIGHT]) * shrinkFactor, (me.offsetY + myArea[JV.IDX_BOTTOM]) * shrinkFactor);
+            ctx.lineTo((me.offsetX + myArea[JV.IDX_LEFT]) * shrinkFactor, (me.offsetY + myArea[JV.IDX_BOTTOM]) * shrinkFactor);
+            ctx.lineTo((me.offsetX + myArea[JV.IDX_LEFT]) * shrinkFactor, (me.offsetY + myArea[JV.IDX_TOP]) * shrinkFactor);
+            ctx.stroke();
+            ctx.restore();
+            //2. then draw sub bands border if have.
+            if (band[JV.BAND_PROP_SUB_BANDS]) {
+                for (let subBand of band[JV.BAND_PROP_SUB_BANDS]) {
+                    if (!(subBand[JV.PROP_CALCULATION])) subBand[JV.PROP_CALCULATION] = JV.CAL_TYPE_ABSTRACT;
+                    let area = private_setupBandArea(band, myArea);
+                    private_showBand(subBand, area);
+                }
+            }
+        };
+        let unitFactor = private_translateUnit(rptTpl[JV.NODE_MAIN_INFO][JV.PROP_UNITS]),
+            orgArea = private_getReportArea(rptTpl, unitFactor);
+        for (let band of rptTpl[JV.NODE_BAND_COLLECTION]) {
+            if (!(band[JV.PROP_CALCULATION])) band[JV.PROP_CALCULATION] = JV.CAL_TYPE_ABSTRACT;
+            let area = private_setupBandArea(band, orgArea);
+            private_showBand(band, area);
+        }
+    }
+}

+ 23 - 18
web/maintain/report/rpt_tpl_main.html

@@ -288,10 +288,14 @@
                                 <div class="form-view col-lg-8 p-0">
                                     <div class="main-data-h" style="position:relative">
                                         <div class="sub-button p-2">
+                                            <button class="btn btn-primary" onclick="preview_util.preview($('#tplCanvas')[0], zTreeOprObj.getRefTpl()) ">预览</button>
                                             <button class="btn btn-primary">保存</button>
                                             <button class="btn btn-secondary">保存并发布</button>
                                             <button class="btn btn-danger">删除模板</button>
                                         </div>
+                                        <div class="main-data">
+                                            <canvas id="tplCanvas" height="820" width="920"></canvas>
+                                        </div>
                                     </div>
                                 </div>
                             </div>
@@ -340,24 +344,25 @@
     </div>
 
     <!-- JS. -->
-<script src="/lib/jquery/jquery.min.js"></script>
-<script src="/lib/tether/tether.min.js"></script>
-<script src="/lib/bootstrap/bootstrap.min.js"></script>
-<script src="/web/maintain/report/js/global.js"></script>
-<script src="/web/maintain/report/js/rpt_tpl_main.js"></script>
-<script src="/web/maintain/report/js/rpt_tpl_helper.js"></script>
-<script src="/web/maintain/report/js/cfg_const.js"></script>
-<!-- zTree -->
-<script type="text/javascript" src="/public/web/date_util.js"></script>
-<script type="text/javascript" src="/lib/ztree/jquery.ztree.core.js"></script>
-<script type="text/javascript" src="/lib/ztree/jquery.ztree.excheck.js"></script>
-<script type="text/javascript" src="/lib/ztree/jquery.ztree.exedit.js"></script>
-<script type="text/javascript" src="/public/web/storageUtil.js"></script>
-<script type="text/javascript" src="/public/web/rpt_tpl_def.js"></script>
-<script type="text/javascript" src="/public/web/common_ajax.js"></script>
-<script type="text/javascript" src="/public/web/treeDataHelper.js"></script>
-<script type="text/javascript" src="/public/web/ztree_common.js"></script>
-<script type="text/javascript" src="/public/web/rpt_value_define.js"></script>
+    <script src="/lib/jquery/jquery.min.js"></script>
+    <script src="/lib/tether/tether.min.js"></script>
+    <script src="/lib/bootstrap/bootstrap.min.js"></script>
+    <script src="/web/maintain/report/js/global.js"></script>
+    <script src="/web/maintain/report/js/rpt_tpl_main.js"></script>
+    <script src="/web/maintain/report/js/rpt_tpl_helper.js"></script>
+    <script src="/web/maintain/report/js/cfg_const.js"></script>
+    <script src="/web/maintain/report/js/rpt_tpl_preview_util.js"></script>
+    <!-- zTree -->
+    <script type="text/javascript" src="/public/web/date_util.js"></script>
+    <script type="text/javascript" src="/lib/ztree/jquery.ztree.core.js"></script>
+    <script type="text/javascript" src="/lib/ztree/jquery.ztree.excheck.js"></script>
+    <script type="text/javascript" src="/lib/ztree/jquery.ztree.exedit.js"></script>
+    <script type="text/javascript" src="/public/web/storageUtil.js"></script>
+    <script type="text/javascript" src="/public/web/rpt_tpl_def.js"></script>
+    <script type="text/javascript" src="/public/web/common_ajax.js"></script>
+    <script type="text/javascript" src="/public/web/treeDataHelper.js"></script>
+    <script type="text/javascript" src="/public/web/ztree_common.js"></script>
+    <script type="text/javascript" src="/public/web/rpt_value_define.js"></script>
 </body>
 <script type="text/javascript">
     autoFlashHeight();