Przeglądaj źródła

Merge branch 'master' of http://smartcost.f3322.net:3000/SmartCost/ConstructionCost

chenshilong 7 lat temu
rodzic
commit
0ae19e3ccc

+ 1 - 0
config/gulpConfig.js

@@ -101,6 +101,7 @@ module.exports = {
         'public/web/tree_sheet/tree_sheet_controller.js',
         'public/web/tree_sheet/tree_sheet_helper.js',
         'public/web/sheet/sheet_data_helper.js',
+        'web/building_saas/main/js/views/glj_col.js',
         'web/building_saas/main/js/views/main_tree_col.js',
         'web/building_saas/main/js/views/project_info.js',
         'web/building_saas/main/js/views/project_view.js',

+ 5 - 1
modules/all_models/bills_template.js

@@ -13,6 +13,10 @@ var BillsTemplateSchema = new Schema({
     name: String,
     unit: String,
     deleteInfo: deleteSchema,
-    tempType: Number
+    tempType: Number,
+    //计算基数
+    calcBase: String,
+    //费率ID
+    feeRateID:Number
 });
 //mongoose.model('temp_bills', BillsTemplateSchema);  之后删除

+ 4 - 0
modules/all_models/proj_setting.js

@@ -11,6 +11,10 @@ let projSettingSchema = {
     main_tree_col: {
         type: Schema.Types.Mixed,
         default: {}
+    },
+    //设置人材机显示列
+    glj_col:{
+        showAdjustPrice:Boolean//是否显示调整价列
     }
 };
 mongoose.model(collectionName, new Schema(projSettingSchema, {versionKey: false, collection: collectionName}));

+ 4 - 1
modules/all_models/tem_bills.js

@@ -30,7 +30,10 @@ const BillsTemplateSchema = {
     // 工程专业
     engineering: Number,
     type:Number,
-    calcBase: String
+    //计算基数
+    calcBase: String,
+    //费率ID
+    feeRateID:Number
 };
 
 mongoose.model('temp_bills', BillsTemplateSchema, 'temp_bills');

+ 43 - 42
modules/glj/models/glj_list_model.js

@@ -250,9 +250,19 @@ class GLJListModel extends BaseModel {
             };
             let projectGljData = await this.findDataByCondition(condition);
             let isAddProjectGLJ = false;
+
+            // 获取标段对应的单价文件id
+            let unitPriceFileId = unitFileId?unitFileId:await ProjectModel.getUnitPriceFileId(data.project_id);
+            if (unitPriceFileId <= 0) {
+                throw '没有对应的单价文件';
+            }
+
+            let unitPriceModel = new UnitPriceModel();
+
+            // 新增单条记录 (两个操作本来应该是事务操作,然而mongodb事务支持比较弱,就当作是都可以顺利执行)
+
             // 如果找不到数据则新增
             if (!projectGljData) {
-                // 新增单条记录 (两个操作本来应该是事务操作,然而mongodb事务支持比较弱,就当作是都可以顺利执行)
                 let gljInsertData = await this.add(data);
                 if (!gljInsertData) {
                     throw '新增项目工料机失败!';
@@ -261,14 +271,7 @@ class GLJListModel extends BaseModel {
                 projectGljData = gljInsertData;
             }
 
-            // 获取标段对应的单价文件id
-
-            let unitPriceFileId = unitFileId?unitFileId:await ProjectModel.getUnitPriceFileId(data.project_id);
-            if (unitPriceFileId <= 0) {
-                throw '没有对应的单价文件';
-            }
             let CompositionGLJ=[];
-            let unitPriceModel = new UnitPriceModel();
             // 判断类型,如果是混凝土、砂浆、配合比或者主材则查找对应的组成物(前提是没有对应的项目工料机数据)
             if(this.ownCompositionTypes.indexOf(data.type)!=-1) {
                 //如果是新增
@@ -288,7 +291,6 @@ class GLJListModel extends BaseModel {
                 }
             }
             projectGljData.subList=CompositionGLJ;
-
             // 新增单价文件
             let [unitPriceInsertData, isAdd] = await unitPriceModel.addUnitPrice(data, unitPriceFileId);
 
@@ -573,36 +575,31 @@ class GLJListModel extends BaseModel {
                 throw '组成物插入单价数据失败!';
             }
         }
-        let pglj_length = projectGljList instanceof Array ? projectGljList.length:Object.getOwnPropertyNames(projectGljList).length;
-        // 如果已经存在则后续操作停止
-        if(pglj_length === compositionGljList.length) {
-            return
-        }
+        let unitPriceModel = new UnitPriceModel();
+        let unitPriceList = await unitPriceModel.model.find({unit_price_file_id:unitPriceFileId});//查找按文件id查找单价文件数据,用来判断单价文件信息是否已存在
 
         // 整理插入的数据
         let gljInsertData = [];
         let unitPriceInsertData = [];
         for(let tmp of compositionGljList) {
             let key = this.getIndex(tmp,['code','name','specs','unit','gljType']);
-            if (projectGljList[key] !== undefined) {
-                continue;
+            if (projectGljList[key] === undefined) {
+                // 项目工料机插入的数据
+                let gljData = {
+                    glj_id: tmp.ID,
+                    project_id: projectId,
+                    code: tmp.code,
+                    name: tmp.name,
+                    specs: tmp.specs,
+                    unit: tmp.unit === undefined ? '' : tmp.unit,
+                    type: tmp.gljType,
+                    adjCoe:tmp.adjCoe,
+                    original_code:tmp.code,
+                    materialType: tmp.materialType,   //三材类别
+                    materialCoe: tmp.materialCoe
+                };
+                gljInsertData.push(gljData);
             }
-            // 项目工料机插入的数据
-            let gljData = {
-                glj_id: tmp.ID,
-                project_id: projectId,
-                code: tmp.code,
-                name: tmp.name,
-                specs: tmp.specs,
-                unit: tmp.unit === undefined ? '' : tmp.unit,
-                type: tmp.gljType,
-                adjCoe:tmp.adjCoe,
-                original_code:tmp.code,
-                materialType: tmp.materialType,   //三材类别
-                materialCoe: tmp.materialCoe
-            };
-            gljInsertData.push(gljData);
-
             let basePrice = scMathUtil.roundTo(tmp.basePrice,-6);
             // 单价文件插入的数据
             let unitPriceData = {
@@ -622,19 +619,17 @@ class GLJListModel extends BaseModel {
             if(tmp.from=='cpt'){
                 unitPriceData.is_add = 1;
             }
-            unitPriceInsertData.push(unitPriceData);
+           if(!unitPriceModel.isPropertyInclude(unitPriceList,['code','name','specs','unit','type'],unitPriceData)){
+               unitPriceInsertData.push(unitPriceData);
+           }
         }
         // 整理完后开始插入数据
-        let addResult = await this.add(gljInsertData);
-        if (!addResult) {
-            throw '组成物插入项目工料机失败!';
-        }
+
         // 插入单价数据表
-        let unitPriceModel = new UnitPriceModel();
-        let addUnitPriceResult = await unitPriceModel.add(unitPriceInsertData);
-        if (!addUnitPriceResult) {
-            throw '组成物插入单价数据失败!';
-        }
+        if(unitPriceInsertData.length >0) await unitPriceModel.add(unitPriceInsertData);
+       //插入项目工料机
+        if(gljInsertData.length > 0) await this.add(gljInsertData);
+
 
         return
     }
@@ -719,6 +714,12 @@ class GLJListModel extends BaseModel {
 
     async getCompositionGLJByData(glj,unitPriceFileId){
         let [gljData,mixRatioData,unitPriceData] = await this.getCompositionListByGLJ(glj,unitPriceFileId);
+        let priceNum = unitPriceData?Object.getOwnPropertyNames(unitPriceData).length:0;
+        let mixNum = mixRatioData?Object.getOwnPropertyNames(mixRatioData).length:0;
+        if(priceNum !==mixNum){//检查组成物数据是否一致
+            console.log("组成物数据有误,组成物单价文件个数:"+priceNum+",    组成物个数:"+mixNum);
+            return []
+        }
         gljData = this.combineData(gljData, unitPriceData, [], mixRatioData);
         return gljData;
     }

+ 1 - 1
modules/glj/models/unit_price_model.js

@@ -184,7 +184,7 @@ class UnitPriceModel extends BaseModel {
         }
         if(pops instanceof  Array){
             for(let p of pops){
-                if(obj[p]){
+                if(obj[p]!==undefined && obj[p]!==undefined!=null){
                     condition[p]=obj[p]
                 }
             }

+ 1 - 1
modules/pm/controllers/new_proj_controller.js

@@ -39,7 +39,7 @@ module.exports = {
             async function (cb) {
                 let engineeringModel = new EngineeringLibModel();
                 let engineering = await engineeringModel.getEngineering(property.engineering_id);
-                projSetting.insertData({"projectID": newProjID, main_tree_col: engineering.main_tree_col}, cb);
+                projSetting.insertData({"projectID": newProjID, main_tree_col: engineering.main_tree_col,glj_col:engineering.glj_col}, cb);
             }
         ], (err) => callback(err));
     }

+ 1 - 1
modules/pm/facade/pm_facade.js

@@ -229,7 +229,7 @@ async function copyUnitPriceFile(newProjectID,rootProjectID,userID,originaluUnit
         let rList = [];
         for(let m of mList){
             m._doc.unit_price_file_id = newFID;
-            m._doc.id = await getCounterID('mix_ratio');
+            m._doc.id = await getCounterID(model.modelName);
             rList.push(m._doc);
         }
         await insertMany(rList,model)

+ 1 - 1
modules/pm/models/templates/bills_template_model.js

@@ -40,7 +40,7 @@ class BillsTemplateModel extends BaseModel {
      */
     async getTemplateDataForNewProj (valuationId, engineering) {
         // 筛选字段
-        let field = {_id: 0, ID: 1, ParentID: 1, NextSiblingID: 1, code: 1, name: 1, unit: 1, flags: 1,type:1, calcBase: 1};
+        let field = {_id: 0, ID: 1, ParentID: 1, NextSiblingID: 1, code: 1, name: 1, unit: 1, flags: 1,type:1, calcBase: 1,feeRateID:1};
         let data = await this.findDataByCondition({valuationId: valuationId, engineering: engineering}, field, false);
 
         return data === null ? [] : data;

+ 1 - 1
modules/ration_glj/facade/ration_glj_facade.js

@@ -168,7 +168,7 @@ function createNewRecord(ration_glj) {
     newRecoed.type = ration_glj.type;
     newRecoed.repositoryId = ration_glj.repositoryId;
     newRecoed.projectGLJID = ration_glj.projectGLJID;
-    newRecoed.adjCoe = ration_glj.adjCoe
+    newRecoed.adjCoe = ration_glj.adjCoe;
     return newRecoed
 }
 

modules/reports/util/pdfkit_test.js → test/unit/reports/pdfkit_test.js


+ 9 - 1
web/building_saas/css/custom.css

@@ -46,4 +46,12 @@ legend.legend{
     padding: 8px;
     padding-top: 7px;
     padding-bottom: 7px;
-}
+}
+
+#gljPriceTenderCoe::-webkit-outer-spin-button,
+#gljPriceTenderCoe::-webkit-inner-spin-button {
+         -webkit-appearance: none;
+     }
+#gljPriceTenderCoe {
+    -moz-appearance: textfield;
+}

+ 2 - 1
web/building_saas/main/html/main.html

@@ -44,7 +44,7 @@
         <div class="main-nav">
             <ul class="nav nav-tabs flex-column" role="tablist">
                 <li class="nav-item"><a class="active" data-toggle="tab" href="#zaojiashu" id="tab_zaojiashu" role="tab">造价书</a></li>
-                <li class="nav-item"><a data-toggle="tab" href="#project_glj" id="tab_project_glj" data-name="tab_project_glj" role="tab">人材机</a></li>
+                <li class="nav-item"><a data-toggle="tab" href="#project_glj" id="tab_project_glj" data-name="tab_project_glj" role="tab">人材机汇总</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#fee_rates" id="tab_fee_rate" role="tab" >费率</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#calc_program_manage" id="tab_calc_program_manage" role="tab">计算程序</a></li>
                 <li class="nav-item"><a data-toggle="tab" href="#tender_price" id="tab_tender_price" role="tab">调价</a></li>
@@ -1342,6 +1342,7 @@
         <script type="text/javascript" src="/public/web/sheet/sheet_data_helper.js"></script>
 
         <!-- view -->
+        <script type="text/javascript" src="/web/building_saas/main/js/views/glj_col.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/main_tree_col.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_info.js"></script>
         <script type="text/javascript" src="/web/building_saas/main/js/views/project_view.js"></script>

+ 1 - 9
web/building_saas/main/html/tender_price.html

@@ -1,12 +1,4 @@
-<!--<style>
-    input::-webkit-outer-spin-button,
-    input::-webkit-inner-spin-button {
-        -webkit-appearance: none;
-    }
-    input[type="number"]{
-        -moz-appearance: textfield;
-    }
-</style>-->
+
 <div class="toolsbar px-1">
     <div class="btn-toolbar py-1">
         <div class="input-group input-group-sm mr-2">

+ 1 - 1
web/building_saas/main/js/models/ration.js

@@ -600,8 +600,8 @@ var Ration = {
                     newNode.source = newSource;
                     newNode.sourceType = project.Ration.getSourceType();
                     newNode.data = newSource;
-                    ProjectController.syncDisplayNewNode(sheetController, newNode);
                     project.projectGLJ.loadData(function () {
+                        ProjectController.syncDisplayNewNode(sheetController, newNode);
                         project.ration_glj.addToMainTree(data.ration_gljs);
                         projectObj.mainController.refreshTreeNode([newNode], false);
                         project.calcProgram.calcAndSave(newNode,function () {

+ 36 - 0
web/building_saas/main/js/views/glj_col.js

@@ -0,0 +1,36 @@
+/**
+ * Created by zhang on 2018/7/3.
+ */
+let gljCol = {
+    ration_glj_setting: {
+        header: [
+            {headerName: "编码", headerWidth: 100, dataCode: "code", dataType: "String", formatter: "@"},
+            {headerName: "名称", headerWidth: 160, dataCode: "name", dataType: "String"},
+            {headerName: "规格型号", headerWidth: 90, dataCode: "specs", dataType: "String", hAlign: "left"},
+            {headerName: "单位", headerWidth: 45, dataCode: "unit", dataType: "String", hAlign: "center"},
+            {headerName: "类型", headerWidth: 45, dataCode: "shortName", dataType: "String", hAlign: "center"},
+            {headerName: "定额消耗", headerWidth: 80, dataCode: "rationItemQuantity", dataType: "Number", hAlign: "right", decimalField: "glj.quantity"},    // dataType: "Number", formatter: "0.00"
+            {headerName: "自定消耗", headerWidth: 80, dataCode: "customQuantity", dataType: "Number", hAlign: "right", decimalField: "glj.quantity"},
+            {headerName: "消耗量", headerWidth: 80, dataCode: "quantity", dataType: "Number", hAlign: "right", decimalField: "glj.quantity"},
+            {headerName: "总消耗量", headerWidth: 80, dataCode: "totalQuantity", dataType: "Number", hAlign: "right", decimalField: "glj.quantity"},
+            {headerName: "定额价", headerWidth: 80, dataCode: "basePrice", dataType: "Number", hAlign: "right", decimalField: "glj.unitPrice"},
+            {headerName: "调整价", headerWidth: 80, dataCode: "adjustPrice", dataType: "Number", hAlign: "right", decimalField: "glj.unitPrice"},
+            {headerName: "市场价", headerWidth: 80, dataCode: "marketPrice", dataType: "Number", hAlign: "right", decimalField: "glj.unitPrice"},
+            {headerName: "是否暂估", headerWidth: 65, dataCode: "isEstimate", dataType: "String", hAlign: "center", vAlign: "center", cellType: "checkBox"
+            }
+        ],
+        view: {
+            lockColumns: [0, 4, 5, 7, 8, 10, 12]
+        },
+        // 工料机类型是混凝土、砂浆、配合比、机械台班时,价格不可编辑。
+        editedTyep:[GLJTypeConst.MAIN_MATERIAL,GLJTypeConst.EQUIPMENT]//主材设备
+    },
+    removeCol:function (dataCode,setting) {
+       // let colIndex =
+
+
+
+    }
+
+
+};

+ 0 - 2
web/building_saas/main/js/views/glj_view.js

@@ -88,8 +88,6 @@ var gljOprObj = {
             }
         ],
         view: {
-            comboBox: [{row: -1, col: 12, rowCount: -1, colCount: 1}],
-            lockedCells: [{row: -1, col: 3, rowCount: -1, colCount: 1}],
             lockColumns: [0, 4, 5, 7, 8, 10, 12]
         },
         // 工料机类型是混凝土、砂浆、配合比、机械台班时,价格不可编辑。

+ 7 - 0
web/building_saas/main/js/views/main_tree_col.js

@@ -52,6 +52,13 @@ let MainTreeCol = {
             if((node.sourceType === projectObj.project.Ration.getSourceType()&&node.data.type!=rationType.ration)||node.sourceType==projectObj.project.ration_glj.getSourceType()){
                 return calcTools.uiGLJPrice(node.data.marketUnitFee);
             }
+        },
+        feeRate:function (node) {
+            if(node.data.feeRateID){
+                let rate = projectObj.project.FeeRate.getFeeRateByID(node.data.feeRateID);
+                if (rate) return rate.rate;
+            }
+            return node.data.feeRate;
         }
     },
     readOnly: {

+ 5 - 2
web/building_saas/main/js/views/project_glj_view.js

@@ -529,7 +529,10 @@ projectGljObject={
     },
     refreshDataSheet:function () {
         let me = projectGljObject;
-        let quantityCol = 5;
+        //------------5;
+        let quantityCol = _.findIndex(me.projectGljSetting.header,function (header) {
+            return header.dataCode ==  'quantity'|| header.dataCode == 'techQuantity' || header.dataCode =='subdivisionQuantity';
+        });
         if(me.displayType == filterType.FBFX){//分部分项人材机,将“总消耗量”替换显示为“分部分项总消耗量”。
             me.projectGljSetting.header[quantityCol].dataCode = 'subdivisionQuantity';
             me.projectGljSheet.setValue(0, quantityCol, "分部分项总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
@@ -540,7 +543,6 @@ projectGljObject={
             me.projectGljSetting.header[quantityCol].dataCode = 'quantity';
             me.projectGljSheet.setValue(0, quantityCol, "总消耗量", GC.Spread.Sheets.SheetArea.colHeader);
         }
-
         if(me.displayType == filterType.SCHZ){//三材汇总树节点
             me.showMaterialTreeData();
         }else {
@@ -839,6 +841,7 @@ projectGljObject={
         let prowData = parentSheet.name() == 'projectGljSheet'?me.projectGljSheetData[prow]:me.materialTree.items[prow].data;
         let updateData = {id: deleteRecode.mix_ratio_id, field: 'mix_ratio.consumption' , value: 0, market_price: parentMarketPrice, base_price: parentBasePrice};
         projectObj.project.composition.deleteComposition(updateData,deleteRecode,prowData.id,function () {
+            _.remove(me.mixRatioData,{"mix_ratio_id":deleteRecode.mix_ratio_id});
             me.refreshParentData(prow,prowData.id);
             me.mixRatioSheet.deleteRows(row,1);
             me.onUnitFileChange(deleteRecode);

+ 22 - 41
web/building_saas/report/html/rpt_print.html

@@ -13,15 +13,25 @@
         page-break-before: auto;
         page-break-after: auto;
     }
+    @page {size: A4 portrait;}
+    body {page: page}
+    div {page: page}
 </style>
-<style type="text/css">
-    svg{
-        width: 1122px;
-        height: 1122px;
+<!--
+    .printPage {
+        page: page
     }
-</style>
+    @page {size: A4 landscape;}
+    div { page: page }
+@page {margin: auto;}
+@page horizon {size: A4 landscape;}
+@page vertical1 {size: A4 portrait;}
+    @page horizon1 {size: A4 landscape;}
+    @page vertical1 {size: A4 portrait;}
+-->
 <script type="text/javascript" src="/web/building_saas/report/js/jpc_output_value_define.js"></script>
 <body onload="loading()" onbeforeunload="closing()">
+    <canvas id="chkCanvas" style="display:none"></canvas>
 </body>
 <script src="/lib/jquery/jquery-3.2.1.min.js"></script>
 <script type="text/javascript" src="/web/building_saas/report/js/jpc_output.js"></script>
@@ -53,49 +63,20 @@
                 orgWidth = orgHeight;
                 orgHeight = tmpInt;
             }
-//            for (let i = 0; i < pageData.items.length; i++) {
-//                let div = $('<div class="pageBreak"><canvas width="' + pageWidth + '" height="' + pageHeight + '"></canvas></div>');
-//                $("body").append(div);
-//            }
-//            $(document.body).find("div").each(function(index,element){
-//                $(element).find("canvas").each(function(cIdx,elementCanvas){
-//                    canvasArr.push(elementCanvas);
-//                });
-//            });
-//            JpcCanvasOutput.scaleFactor = scaleFactor;
-//            JpcCanvasOutput.resetFonts(pageData[JV.NODE_FONT_COLLECTION]);
-//            for (let i = 0; i < canvasArr.length; i++) {
-//                JpcCanvasOutput.offsetX = -30;
-//                JpcCanvasOutput.offsetY = -30;
-//                JpcCanvasOutput.drawToCanvas(pageData, canvasArr[i], i+1);
-//            }
-
-//            let imgDataArr = [];
-//            for (let canvas of canvasArr) {
-//                imgDataArr.push(canvas.toDataURL());
-//            }
-//            let imgIdx = 0;
-//            $(document.body).find("div").each(function(index,element){
-//                let img = document.createElement('img');
-//                img.src = imgDataArr[imgIdx];
-//                img.height = orgHeight;
-//                img.width = orgWidth;
-//                imgIdx++;
-//                element.appendChild(img);
-//                $(element).find("canvas").each(function(cIdx,elementCanvas){
-//                    elementCanvas.style.display = "none";
-//                });
-//            });
 
             let svgArr = rptPrintHelper.buildSvgArr(pageData, -30, -30);
             for (let i = 0; i < pageData.items.length; i++) {
                 let div = $('<div class="pageBreak"></div>');
-//                console.log()
-//                div.append(svgArr[i]);
                 div.append($(svgArr[i].join("")));
                 $("body").append(div);
             }
-
+            $(document.body).find("div").each(function(index,element){
+                $(element).find("svg").each(function(cIdx,elementSvg){
+                    elementSvg.setAttribute('height', pageHeight);
+                    elementSvg.setAttribute('width', pageWidth);
+                });
+            });
+//            $("body").css({"page": "page"});
             window.print();
             //document.execCommand("print");
         } else {

+ 86 - 33
web/building_saas/report/js/rpt_print.js

@@ -15,20 +15,21 @@ let rptPrintHelper = {
             sessionStorage.currentPageData = null;
         }
     },
-    print: function () {
-        //
-    },
     buildSvgArr: function (pagesData, offsetX, offsetY) {
+        let me = this;
         let styles = pagesData[JV.NODE_STYLE_COLLECTION],
             fonts = pagesData[JV.NODE_FONT_COLLECTION],
             controls = pagesData[JV.NODE_CONTROL_COLLECTION]
         ;
         let rst = [];
-        for (let page of pagesData.items) {
+        let canvas = document.getElementById("chkCanvas");
+        for (let idx = 0; idx < pagesData.items.length; idx++) {
+            let page = pagesData.items[idx];
             let svgPageArr = [], pixelSize = getPixelSize(pagesData);
             svgPageArr.push("<svg width='" + pixelSize[0] + "' height='" + pixelSize[1] + "'>");
+            let adjustY = 0.5 * ((idx + 1) % 2);
             for (let cell of page.cells) {
-                svgPageArr.push(buildCellSvg(cell, fonts, styles, controls, page[JV.PROP_PAGE_MERGE_BORDER], pagesData[JV.BAND_PROP_MERGE_BAND], offsetX, offsetY));
+                svgPageArr.push(buildCellSvg(cell, fonts, styles, controls, page[JV.PROP_PAGE_MERGE_BORDER], pagesData[JV.BAND_PROP_MERGE_BAND], offsetX, offsetY, adjustY, canvas));
             }
             svgPageArr.push("</svg>");
             rst.push(svgPageArr);
@@ -41,25 +42,37 @@ function getActualBorderStyle(cell, styles, mergeBorderStyle, pageBorderArea, bo
     let rst = styles[cell[JV.PROP_STYLE]][borderStr];
     if (mergeBorderStyle) {
         if (parseFloat(cell[JV.PROP_AREA][borderStr]) === parseFloat(pageBorderArea[borderStr])) {
-            rst = mergeBorderStyle[borderStr];
+            if (borderStr === JV.PROP_LEFT || borderStr === JV.PROP_RIGHT) {
+                if (parseFloat(cell[JV.PROP_AREA][JV.PROP_TOP]) >= parseFloat(pageBorderArea[JV.PROP_TOP]) &&
+                    parseFloat(cell[JV.PROP_AREA][JV.PROP_BOTTOM]) <= parseFloat(pageBorderArea[JV.PROP_BOTTOM])) {
+                    rst = mergeBorderStyle[borderStr];
+                }
+            } else if (borderStr === JV.PROP_TOP || borderStr === JV.PROP_BOTTOM) {
+                if (parseFloat(cell[JV.PROP_AREA][JV.PROP_LEFT]) >= parseFloat(pageBorderArea[JV.PROP_LEFT]) &&
+                    parseFloat(cell[JV.PROP_AREA][JV.PROP_RIGHT]) <= parseFloat(pageBorderArea[JV.PROP_RIGHT])) {
+                    rst = mergeBorderStyle[borderStr];
+                }
+            }
         }
     }
     return rst;
 }
 
-function buildCellSvg(cell, fonts, styles, controls, pageMergeBorder, rptMergeBorder, offsetX, offsetY) {
+function buildCellSvg(cell, fonts, styles, controls, pageMergeBorder, rptMergeBorder, offsetX, offsetY, adjustY, canvas) {
     let rst = [];
     let style = styles[cell[JV.PROP_STYLE]];
     let mergeBandStyle = null;
     if (rptMergeBorder) {
-        mergeBandStyle = styles[rptMergeBorder[JV.PROP_STYLE]];
+        mergeBandStyle = styles[rptMergeBorder[JV.PROP_STYLE][JV.PROP_ID]];
+    }
+    let font = cell[JV.PROP_FONT];
+    if (typeof font === 'string') {
+        font = fonts[cell[JV.PROP_FONT]];
     }
     let left = parseInt(cell[JV.PROP_AREA][JV.PROP_LEFT]) + offsetX + 0.5,
         right = parseInt(cell[JV.PROP_AREA][JV.PROP_RIGHT]) + offsetX + 0.5,
-        top = parseInt(cell[JV.PROP_AREA][JV.PROP_TOP]) + offsetY + 0.5,
-        bottom = parseInt(cell[JV.PROP_AREA][JV.PROP_BOTTOM]) + offsetY + 0.5,
-        x = left, y = top,
-        text_anchor = "start"
+        top = parseInt(cell[JV.PROP_AREA][JV.PROP_TOP]) + offsetY + adjustY,
+        bottom = parseInt(cell[JV.PROP_AREA][JV.PROP_BOTTOM]) + offsetY + adjustY
     ;
     if (style) {
         let leftBS = getActualBorderStyle(cell, styles, mergeBandStyle, (pageMergeBorder)?pageMergeBorder:rptMergeBorder[JV.PROP_AREA], JV.PROP_LEFT);
@@ -67,37 +80,57 @@ function buildCellSvg(cell, fonts, styles, controls, pageMergeBorder, rptMergeBo
         if (leftBS && parseFloat(leftBS[JV.PROP_LINE_WEIGHT]) > 0) {
             rst.push("<line x1='" + left + "' y1='" + top +
                 "' x2='" + left + "' y2='" + bottom +
-                "' style='stroke:rgb(0,0,0);stroke-width:1'/>")
+                "' style='stroke:rgb(0,0,0);stroke-width:" + leftBS[JV.PROP_LINE_WEIGHT] +"'/>")
         }
         let rightBS = getActualBorderStyle(cell, styles, mergeBandStyle, (pageMergeBorder)?pageMergeBorder:rptMergeBorder[JV.PROP_AREA], JV.PROP_RIGHT);
         // if (style[JV.PROP_RIGHT] && parseFloat(style[JV.PROP_RIGHT][JV.PROP_LINE_WEIGHT]) > 0) {
         if (rightBS && parseFloat(rightBS[JV.PROP_LINE_WEIGHT]) > 0) {
             rst.push("<line x1='" + right + "' y1='" + top +
                 "' x2='" + right + "' y2='" + bottom +
-                "' style='stroke:rgb(0,0,0);stroke-width:1'/>")
+                "' style='stroke:rgb(0,0,0);stroke-width:" + rightBS[JV.PROP_LINE_WEIGHT] +"'/>")
         }
         let topBS = getActualBorderStyle(cell, styles, mergeBandStyle, (pageMergeBorder)?pageMergeBorder:rptMergeBorder[JV.PROP_AREA], JV.PROP_TOP);
         // if (style[JV.PROP_TOP] && parseFloat(style[JV.PROP_TOP][JV.PROP_LINE_WEIGHT]) > 0) {
         if (topBS && parseFloat(topBS[JV.PROP_LINE_WEIGHT]) > 0) {
             rst.push("<line x1='" + left + "' y1='" + top +
                 "' x2='" + right + "' y2='" + top +
-                "' style='stroke:rgb(0,0,0);stroke-width:1'/>")
+                "' style='stroke:rgb(0,0,0);stroke-width:" + topBS[JV.PROP_LINE_WEIGHT] +"'/>")
         }
         let bottomBS = getActualBorderStyle(cell, styles, mergeBandStyle, (pageMergeBorder)?pageMergeBorder:rptMergeBorder[JV.PROP_AREA], JV.PROP_BOTTOM);
         // if (style[JV.PROP_BOTTOM] && parseFloat(style[JV.PROP_BOTTOM][JV.PROP_LINE_WEIGHT]) > 0) {
         if (bottomBS && parseFloat(bottomBS[JV.PROP_LINE_WEIGHT]) > 0) {
             rst.push("<line x1='" + left + "' y1='" + bottom +
                 "' x2='" + right + "' y2='" + bottom +
-                "' style='stroke:rgb(0,0,0);stroke-width:1'/>")
+                "' style='stroke:rgb(0,0,0);stroke-width:" + bottomBS[JV.PROP_LINE_WEIGHT] +"'/>")
         }
     }
-    let font = cell[JV.PROP_FONT];
-    if (typeof font === 'string') {
-        font = fonts[cell[JV.PROP_FONT]];
-    }
-    let fontsize = Math.round(parseInt(font[JV.FONT_PROPS[JV.FONT_PROP_IDX_HEIGHT]]) * 3 / 4);
+    buildText(rst, cell, font, controls[cell[JV.PROP_CONTROL]], offsetX, offsetY, adjustY, canvas);
+
+    return rst.join("");
+}
+
+function buildText(destRst, cell, font, control, offsetX, offsetY, adjustY, canvas) {
+    let orgFontHeight = parseInt(font[JV.FONT_PROPS[JV.FONT_PROP_IDX_HEIGHT]]);
     let fontWeight = (font[JV.FONT_PROPS[JV.FONT_PROP_IDX_BOLD]] === 'T')?"bold":"normal";
-    let control = controls[cell[JV.PROP_CONTROL]];
+    let fontStyle = (font[JV.FONT_PROPS[JV.FONT_PROP_IDX_ITALIC]] === 'T')?"italic":"normal";
+    let left = parseInt(cell[JV.PROP_AREA][JV.PROP_LEFT]) + offsetX + 0.5,
+        right = parseInt(cell[JV.PROP_AREA][JV.PROP_RIGHT]) + offsetX + 0.5,
+        top = parseInt(cell[JV.PROP_AREA][JV.PROP_TOP]) + offsetY + adjustY,
+        bottom = parseInt(cell[JV.PROP_AREA][JV.PROP_BOTTOM]) + offsetY + adjustY,
+        x = left, y = top,
+        text_anchor = "start"
+    ;
+    let value = cell[JV.PROP_VALUE];
+    if (!(value)) {
+        value = "";
+    }
+    let values = null;
+    if (typeof value === "string") {
+        values = value.split("|");
+    } else {
+        values = [value];
+    }
+    let stepHeight = (parseInt(cell[JV.PROP_AREA][JV.PROP_BOTTOM]) - parseInt(cell[JV.PROP_AREA][JV.PROP_TOP])) / values.length;
     if (control) {
         if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_HORIZON]] === "left") {
             text_anchor = "start";
@@ -109,19 +142,39 @@ function buildCellSvg(cell, fonts, styles, controls, pageMergeBorder, rptMergeBo
             text_anchor = "middle";
             x = Math.round((left + right) / 2);
         }
-        if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] === "top") {
-            y = top + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP];
-        } else if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] === "bottom") {
-            y = bottom - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM];
-        } else if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] === "center") {
-            y = Math.round((top + bottom + fontsize) / 2 );
+    }
+    for (let vidx = 0; vidx < values.length; vidx++) {
+        //check whether need to adjust the font size
+        let ctx = canvas.getContext("2d");
+        let dftFontHeight = orgFontHeight;
+        ctx.font = ((font[JV.FONT_PROPS[JV.FONT_PROP_IDX_BOLD]] === 'T')?"bold ":"") + ((font[JV.FONT_PROPS[JV.FONT_PROP_IDX_ITALIC]] === 'T')?"italic":"") + dftFontHeight + "px " + font[JV.PROP_NAME];
+        while ((right - left) <= ctx.measureText(values[vidx]).width) {
+            if (dftFontHeight > 6) {
+                dftFontHeight--;
+                ctx.font = ((font[JV.FONT_PROPS[JV.FONT_PROP_IDX_BOLD]] === 'T')?"bold ":"") + ((font[JV.FONT_PROPS[JV.FONT_PROP_IDX_ITALIC]] === 'T')?"italic":"") + dftFontHeight + "px " + font[JV.PROP_NAME];
+            } else {
+                break;
+            }
         }
+        dftFontHeight = (dftFontHeight * 3 / 4); //SVG的字体与canvas的字体大小的切换, 不用考虑取整
+        if (control) {
+            if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] === "top") {
+                y = Math.round((top + vidx * stepHeight) + JV.OUTPUT_OFFSET[JV.OFFSET_IDX_TOP]);
+            } else if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] === "bottom") {
+                y = Math.round((top + (vidx + 1) * stepHeight) - JV.OUTPUT_OFFSET[JV.OFFSET_IDX_BOTTOM]);
+            } else if (control[JV.CONTROL_PROPS[JV.CONTROL_PROP_IDX_VERTICAL]] === "center") {
+                y = Math.round(((top + vidx * stepHeight) + (top + (vidx + 1) * stepHeight) + dftFontHeight) / 2 );
+            }
+        }
+        if (font[JV.PROP_NAME] === "宋体") {
+            y--;
+        }
+        destRst.push("<text style='fill:black;font-family:" + font[JV.PROP_NAME] +
+            ";font-weight:" + fontWeight +
+            ";font-style:" + fontStyle +
+            ";font-size:" + dftFontHeight + "pt' x='" +
+            x +"' y='" + y + "' text-anchor='" + text_anchor + "' xml:space='preserve'>" + values[vidx] + "</text>");
     }
-    rst.push("<text style='fill:black;font-family:" + font[JV.PROP_NAME] +
-        ";font-weight:" + fontWeight +
-        ";font-size:" + fontsize + "pt' x='" +
-        x +"' y='" + y + "' text-anchor='" + text_anchor + "'>" + cell[JV.PROP_VALUE] + "</text>");
-    return rst.join("");
 }
 
 function getPixelSize(pagesData) {