Просмотр исходного кода

导出多张报表到一个excel

TonyKang 7 лет назад
Родитель
Сommit
8c7f8189c4

+ 58 - 14
modules/reports/controllers/rpt_controller.js

@@ -3,6 +3,7 @@
  */
 
 let mongoose = require('mongoose');
+let async = require('async');
 
 let JV = require('../rpt_component/jpc_value_define');
 
@@ -28,7 +29,7 @@ let callback = function(req, res, err, data){
     }
 };
 
-function getAllPagesCommonOrg(req, res, rpt_id, pageSize, cb) {
+function getAllPagesCommonOrg(rpt_id, pageSize, cb) {
     let rptTpl = null;
     rptTplFacade.getRptTemplate(rpt_id).then(function(rst) {
         rptTpl = rst;
@@ -36,10 +37,12 @@ function getAllPagesCommonOrg(req, res, rpt_id, pageSize, cb) {
             if (rptTpl.ID_KEY) {
                 return demoTemplateFacade.getDemoData(rptTpl.ID_KEY);
             } else {
-                callback(req, res, 'No report template data were found!', null);
+                //callback(req, res, 'No report template data were found!', null);
+                cb('No report template data were found!', null);
             }
         } else {
-            callback(req, res, 'No report template was found!', null);
+            //callback(req, res, 'No report template was found!', null);
+            cb('No report template was found!', null);
         }
     }).then(function(tplData){
             if (tplData) {
@@ -51,18 +54,20 @@ function getAllPagesCommonOrg(req, res, rpt_id, pageSize, cb) {
                 let maxPages = printCom.totalPages;
                 let pageRst = printCom.outputAsSimpleJSONPageArray(rptTpl, tplData, 1, maxPages, defProperties);
                 if (pageRst) {
-                    cb(pageRst);
+                    cb(null, pageRst);
                 } else {
-                    callback(req, res, "Have errors while on going...", null);
+                    //callback(req, res, "Have errors while on going...", null);
+                    cb('Have errors while on going...', null);
                 }
             } else {
-                callback(req, res, 'No report data were found!', null);
+                //callback(req, res, 'No report data were found!', null);
+                cb('No report data were found!', null);
             }
         }
     );
 };
 
-function getAllPagesCommon(req, res, rpt_id, pageSize, cb) {
+function getAllPagesCommon(rpt_id, pageSize, cb) {
     let rptTpl = null;
     rptTplFacade.getRptTemplate(rpt_id).then(function(rst) {
         rptTpl = rst;
@@ -96,10 +101,10 @@ function getAllPagesCommon(req, res, rpt_id, pageSize, cb) {
                 //return demoTemplateData.findOne({"Data_Key": rptTpl.ID_KEY}).exec();
 
             } else {
-                callback(req, res, 'No report template data were found!', null);
+                cb('No report template data were found!', null);
             }
         } else {
-            callback(req, res, 'No report template was found!', null);
+            cb('No report template was found!', null);
         }
     })
 };
@@ -108,9 +113,9 @@ module.exports = {
     getReportAllPages: function(req, res){
         let rpt_id = req.body.ID;
         let pageSize = req.body.pageSize;
-        getAllPagesCommonOrg(req, res, rpt_id, pageSize, function(pageRst){
+        getAllPagesCommonOrg(rpt_id, pageSize, function(err, pageRst){
             //fs.writeFileSync('D:/GitHome/ConstructionOperation/tmp/testRpt.js', JSON.stringify(pageRst));
-            callback(req, res, null, pageRst);
+            callback(req, res, err, pageRst);
         })
     },
     getExcel: function(req, res) {
@@ -119,8 +124,8 @@ module.exports = {
             rptName = req.params.rptName,
             isOneSheet = req.params.isOneSheet;
         ;
-        getAllPagesCommonOrg(req, res, rpt_id, pageSize, function(pageRst){
-            rpt_xl_util.exportExcel(pageRst, pageSize, rptName, isOneSheet, function(newName){
+        getAllPagesCommonOrg(rpt_id, pageSize, function(err, pageRst){
+            rpt_xl_util.exportExcel(pageRst, pageSize, rptName, isOneSheet, null, function(newName){
                 res.setHeader('Content-Type', 'application/vnd.openxmlformats');
                 res.setHeader("Content-Disposition", "attachment; filename=" + strUtil.getPinYinCamelChars(rptName) + ".xlsx");
                 let filestream = fs.createReadStream(__dirname.slice(0, __dirname.length - 28) + '/tmp/' + newName + '.xlsx');
@@ -133,12 +138,51 @@ module.exports = {
             });
         })
     },
+    getExcelInOneBook: function(req, res) {
+        let rpt_ids = req.params.ids.split(','),
+            pageSize = req.params.size,
+            rptName = req.params.rptName;
+        ;
+        let parallelFucs = [];
+        for (let id of rpt_ids) {
+            parallelFucs.push((function (rpt_id) {
+                return function (cb) {
+                    getAllPagesCommonOrg(rpt_id, pageSize, function (err, pageRst) {
+                        if(err){
+                            cb(err);
+                        }
+                        else{
+                            cb(null, pageRst);
+                        }
+                    })
+                }
+            })(parseInt(id)));
+        }
+        async.parallel(parallelFucs, function (err, pageRstArray) {
+            if (err) {
+                callback(req, res, '数据有误', null);
+            } else {
+                rpt_xl_util.exportExcelInOneBook(pageRstArray, pageSize, rptName, function(tmpFilePath){
+                    res.setHeader('Content-Type', 'application/vnd.openxmlformats');
+                    res.setHeader("Content-Disposition", "attachment; filename=" + strUtil.getPinYinCamelChars(rptName) + ".xlsx");
+                    let filestream = fs.createReadStream(__dirname.slice(0, __dirname.length - 28) + '/tmp/' + tmpFilePath + '.xlsx');
+                    filestream.on('data', function(chunk) {
+                        res.write(chunk);
+                    });
+                    filestream.on('end', function() {
+                        res.end();
+                    });
+                });
+                //callback(req, res, false, '', {compilation: rst, gljLibs: gljLibsRst});
+            }
+        })
+    },
     getPDF:function (req, res) {
         let rpt_id = req.params.id,
             pageSize = req.params.size,
             rptName = req.params.rptName;
 
-        getAllPagesCommonOrg(req, res, rpt_id, pageSize, function(pageRst){
+        getAllPagesCommonOrg(rpt_id, pageSize, function(err, pageRst){
             rpt_pdf_util.export_pdf_file(pageRst, pageSize, rptName,function (newName) {
                 res.setHeader('Content-Type', 'application/vnd.openxmlformats');
                 res.setHeader("Content-Disposition", "attachment; filename=" + strUtil.getPinYinCamelChars(rptName) + ".pdf");

+ 4 - 1
modules/reports/routes/report_router.js

@@ -18,7 +18,10 @@ module.exports =function (app) {
         }
     });
     rptRouter.post('/getReport', reportController.getReportAllPages);
+
     rptRouter.get('/getExcel/:id/:size/:rptName/:isOneSheet', reportController.getExcel);
-        rptRouter.get('/getPDF/:id/:size/:rptName', reportController.getPDF);//2/A4/07-1表
+    rptRouter.get('/getExcelInOneBook/:ids/:size/:rptName', reportController.getExcelInOneBook);
+
+    rptRouter.get('/getPDF/:id/:size/:rptName', reportController.getPDF);//2/A4/07-1表
     app.use("/report_api", rptRouter);
 }

+ 4 - 1
modules/reports/rpt_component/jpc_ex.js

@@ -169,7 +169,10 @@ JpcExSrv.prototype.createNew = function(){
             rst[JV.NODE_CONTROL_COLLECTION] = private_buildDftControls(rptTpl, (defProperties == null)?null:defProperties.ctrls);
             rst[JV.NODE_STYLE_COLLECTION] = private_buildDftStyles(rptTpl, (defProperties == null)?null:defProperties.styles);
             rst[JV.NODE_FONT_COLLECTION] = private_buildDftFonts(rptTpl, (defProperties == null)?null:defProperties.fonts);
-            rst[JV.NODE_PAGE_INFO] = JpcCommonHelper.getPageSize(rptTpl);
+            rst[JV.NODE_PAGE_INFO] = {};
+            rst[JV.NODE_PAGE_INFO][JV.NODE_MAIN_INFO_RPT_NAME] = rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MAIN_INFO_RPT_NAME];
+            rst[JV.NODE_PAGE_INFO][JV.NODE_PAGE_SIZE] = JpcCommonHelper.getPageSize(rptTpl);
+            rst[JV.NODE_PAGE_INFO][JV.NODE_MARGINS] = rptTpl[JV.NODE_MAIN_INFO][JV.NODE_MARGINS];
             rst.items = [];
             let bands = JpcBand.createNew(rptTpl, defProperties);
             try {

+ 144 - 17
modules/reports/util/rpt_excel_util.js

@@ -7,6 +7,7 @@ let JSZip = require("jszip");
 let strUtil = require('../../../public/stringUtil');
 let jpcCmnHelper = require('../rpt_component/helper/jpc_helper_common');
 let DPI = jpcCmnHelper.getScreenDPI()[0];
+let fsUtil = require('../../../public/fsUtil');
 const dftHeadXml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>';
 
 function writeContentTypes(sheets, isSinglePage) {
@@ -331,6 +332,7 @@ function writeSheets(pageData, paperSize, sharedStrList, stylesObj, isSinglePage
 function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj){
     let rst = [], xPos = [], yPos = [], yMultiPos = [], headerStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
     let cacheBorderCell = {};
+    let currentPageMergePos = null;
     let private_pre_analyze_pos = function(){
         let cell, pos;
         let self_analyze_sheet_pos = function (theShtData, theXPos, theYPos) {
@@ -446,22 +448,22 @@ function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj){
         borderLineWidths.push(border[JV.PROP_TOP][JV.PROP_LINE_WEIGHT]);
         borderLineWidths.push(border[JV.PROP_BOTTOM][JV.PROP_LINE_WEIGHT]);
         if (sheetBorder[JV.PROP_LEFT] && sheetBorder[JV.PROP_LEFT][JV.PROP_LINE_WEIGHT]) {
-            sheetBorderLineWidths.push(private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_LEFT));
+            sheetBorderLineWidths.push(private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_LEFT, true));
         } else {
             sheetBorderLineWidths.push(0);
         }
         if (sheetBorder[JV.PROP_RIGHT] && sheetBorder[JV.PROP_RIGHT][JV.PROP_LINE_WEIGHT]) {
-            sheetBorderLineWidths.push(private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_RIGHT));
+            sheetBorderLineWidths.push(private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_RIGHT, true));
         } else {
             sheetBorderLineWidths.push(0);
         }
         if (sheetBorder[JV.PROP_TOP] && sheetBorder[JV.PROP_TOP][JV.PROP_LINE_WEIGHT]) {
-            sheetBorderLineWidths.push(private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_TOP));
+            sheetBorderLineWidths.push(private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_TOP, false));
         } else {
             sheetBorderLineWidths.push(0);
         }
         if (sheetBorder[JV.PROP_BOTTOM] && sheetBorder[JV.PROP_BOTTOM][JV.PROP_LINE_WEIGHT]) {
-            sheetBorderLineWidths.push(private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_BOTTOM));
+            sheetBorderLineWidths.push(private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_BOTTOM, false));
         } else {
             sheetBorderLineWidths.push(0);
         }
@@ -473,14 +475,45 @@ function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj){
         }
         return rst;
     };
-    let private_chkAndGetMergeLine = function(cell, sheetBorder, borderStr) {
+    let private_chkAndGetMergeLine = function(cell, sheetBorder, borderStr, needFurtherChk) {
         let rst = 0, mergeBorder = pageData[JV.BAND_PROP_MERGE_BAND];
-        if (sheetBorder[borderStr] && sheetBorder[borderStr][JV.PROP_LINE_WEIGHT] != undefined) {
+        if (sheetBorder[borderStr] && sheetBorder[borderStr][JV.PROP_LINE_WEIGHT] !== undefined) {
             rst = sheetBorder[borderStr][JV.PROP_LINE_WEIGHT];
         }
-        if (cell[JV.PROP_AREA][borderStr] == mergeBorder[borderStr]) {
-            let destStyle = pageData[JV.NODE_STYLE_COLLECTION][mergeBorder[JV.PROP_STYLE][JV.PROP_ID]];
-            rst = destStyle[borderStr][JV.PROP_LINE_WEIGHT];
+        if (currentPageMergePos) {
+            let side = currentPageMergePos[borderStr];
+            if (side.indexOf(cell[JV.PROP_AREA][borderStr]) >= 0) {
+                if (needFurtherChk) {
+                    let topSide = currentPageMergePos[JV.PROP_TOP];
+                    let bottomSide = currentPageMergePos[JV.PROP_BOTTOM];
+                    for (let i = 0; i < topSide.length; i++) {
+                        if (cell[JV.PROP_AREA][JV.PROP_TOP] >= topSide[i]) {
+                            if (cell[JV.PROP_AREA][JV.PROP_BOTTOM] <= bottomSide[i]) {
+                                let destStyle = pageData[JV.NODE_STYLE_COLLECTION][mergeBorder[JV.PROP_STYLE][JV.PROP_ID]];
+                                rst = destStyle[borderStr][JV.PROP_LINE_WEIGHT];
+                                break;
+                            }
+                        } else {
+                            break;
+                        }
+                    }
+                } else {
+                    let destStyle = pageData[JV.NODE_STYLE_COLLECTION][mergeBorder[JV.PROP_STYLE][JV.PROP_ID]];
+                    rst = destStyle[borderStr][JV.PROP_LINE_WEIGHT];
+                }
+            }
+        } else {
+            if (cell[JV.PROP_AREA][borderStr] === mergeBorder[borderStr]) {
+                let destStyle = pageData[JV.NODE_STYLE_COLLECTION][mergeBorder[JV.PROP_STYLE][JV.PROP_ID]];
+                if (needFurtherChk) {
+                    if (cell[JV.PROP_AREA][JV.PROP_TOP] >= mergeBorder[JV.PROP_TOP] &&
+                        cell[JV.PROP_AREA][JV.PROP_BOTTOM] <= mergeBorder[JV.PROP_BOTTOM]) {
+                        rst = destStyle[borderStr][JV.PROP_LINE_WEIGHT];
+                    }
+                } else {
+                    rst = destStyle[borderStr][JV.PROP_LINE_WEIGHT];
+                }
+            }
         }
         return parseInt(rst);
     };
@@ -503,10 +536,10 @@ function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj){
         }
         let sheetBorder = pageData[JV.NODE_STYLE_COLLECTION][cell.style];
         let mergedBorder = private_getIniBorder();
-        mergedBorder[JV.PROP_LEFT][JV.PROP_LINE_WEIGHT] = private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_LEFT);
-        mergedBorder[JV.PROP_RIGHT][JV.PROP_LINE_WEIGHT] = private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_RIGHT);
-        mergedBorder[JV.PROP_TOP][JV.PROP_LINE_WEIGHT] = private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_TOP);
-        mergedBorder[JV.PROP_BOTTOM][JV.PROP_LINE_WEIGHT] = private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_BOTTOM);
+        mergedBorder[JV.PROP_LEFT][JV.PROP_LINE_WEIGHT] = private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_LEFT, true);
+        mergedBorder[JV.PROP_RIGHT][JV.PROP_LINE_WEIGHT] = private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_RIGHT, true);
+        mergedBorder[JV.PROP_TOP][JV.PROP_LINE_WEIGHT] = private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_TOP, false);
+        mergedBorder[JV.PROP_BOTTOM][JV.PROP_LINE_WEIGHT] = private_chkAndGetMergeLine(cell, sheetBorder, JV.PROP_BOTTOM, false);
         for (let i = 0; i < stylesObj.borders.length; i++) {
             let border = stylesObj.borders[i];
             if (private_checkBorder(cell, border, mergedBorder)) {
@@ -723,12 +756,14 @@ function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj){
         private_cacheMergeBandBorderIdxs();
         if (sheetData) {
             //current sheet data
+            currentPageMergePos = sheetData[JV.PAGE_SPECIAL_MERGE_POS];
             self_setDataEx(sheetData, yPos, 0);
         } else {
             //total data in one sheet
             let cnt = 0;
             for (let i = 0; i < pageData.items.length; i++) {
                 let shtItemData = pageData.items[i];
+                currentPageMergePos = shtItemData[JV.PAGE_SPECIAL_MERGE_POS];
                 let tmpPos = yMultiPos[i];
                 cellIdx = 0;
                 self_setDataEx(shtItemData, tmpPos, cnt);
@@ -758,15 +793,30 @@ function writeSheet(pageData, sheetData, paperSize, sharedStrList, stylesObj){
     if (paperSizeIdx >= 0) {
         pStr = 'paperSize="' + JV.PAGES_SIZE_IDX[paperSizeIdx] + '"';
     }
-    let orientationStr = (pageData[JV.NODE_PAGE_INFO][0] > pageData[JV.NODE_PAGE_INFO][1])?'landscape':'portrait';
+    let orientationStr = (pageData[JV.NODE_PAGE_INFO][JV.NODE_PAGE_SIZE][0] > pageData[JV.NODE_PAGE_INFO][JV.NODE_PAGE_SIZE][1])?'landscape':'portrait';
     rst.push('<pageSetup ' + pStr + ' fitToWidth="0" fitToHeight="0" orientation="' + orientationStr + '" />');
     rst.push('<headerFooter alignWithMargins="0"/>');
     rst.push('</worksheet>');
     return rst;
 }
 
+function mergeProperties(orgObj, newObj) {
+    let orgPropArr = [], newPropArr = [];
+    for (let p in orgObj) {
+        orgPropArr.push(p);
+    }
+    for (let p in newObj) {
+        newPropArr.push(p);
+    }
+    for (let i = 0; i < newPropArr.length; i++) {
+        if (orgPropArr.indexOf(newPropArr[i]) < 0) {
+            orgObj[newPropArr[i]] = newObj[newPropArr[i]];
+        }
+    }
+}
+
 module.exports = {
-    exportExcel: function (pageData, paperSize, fName, options, callback) {
+    exportExcel: function (pageData, paperSize, fName, options, custSheetNames, callback) {
         let rptOptions = ({singlePage: false, fileName: 'report'});
         if (options === 'true') {
             rptOptions.singlePage = true;
@@ -776,8 +826,14 @@ module.exports = {
         if (isSinglePage) {
             sheets.push({sheetName: '全部页'});
         } else {
-            for (let i = 0; i < pageData.items.length; i++) {
-                sheets.push({sheetName: '第' + (i + 1) + '页'});
+            if (custSheetNames && custSheetNames.length === pageData.items.length) {
+                for (let i = 0; i < pageData.items.length; i++) {
+                    sheets.push({sheetName: custSheetNames[i]});
+                }
+            } else {
+                for (let i = 0; i < pageData.items.length; i++) {
+                    sheets.push({sheetName: '第' + (i + 1) + '页'});
+                }
             }
         }
         //1.
@@ -849,5 +905,76 @@ module.exports = {
             //return zip.generateNodeStream({type:'nodebuffer',streamFiles:true});
             return zip;
         }
+    },
+
+    exportExcelInOneBook: function (pageDataArray, paperSize, fName, callback) {
+        let me = this, newPageData = {};
+        //1. 重新编排一下数据,把一份报表的pageData合并到一起作为一个Sheet输出(需要重新调整数据纵向坐标),多份报表数据就形成多个Sheet
+        //   -- 简单来说,就是重新包装数据
+        try {
+            // 1.1 newPageData外围属性
+            let newContrl = {}, newFont = {}, newStyle = {};
+            for (let i = 0; i < pageDataArray.length; i++) {
+                mergeProperties(newContrl, pageDataArray[i][JV.NODE_CONTROL_COLLECTION]);
+                mergeProperties(newFont, pageDataArray[i][JV.NODE_FONT_COLLECTION]);
+                mergeProperties(newStyle, pageDataArray[i][JV.NODE_STYLE_COLLECTION]);
+            }
+            newPageData[JV.NODE_CONTROL_COLLECTION] = newContrl;
+            newPageData[JV.NODE_FONT_COLLECTION] = newFont;
+            newPageData[JV.NODE_STYLE_COLLECTION] = newStyle;
+            newPageData[JV.NODE_PAGE_INFO] = pageDataArray[0][JV.NODE_PAGE_INFO];
+            newPageData[JV.BAND_PROP_MERGE_BAND] = pageDataArray[0][JV.BAND_PROP_MERGE_BAND];
+
+            // 1.2 重新设置pageDataArray的各个cell的Top/Bottom坐标
+            let sheetNames = [], newPagePos = [];
+            for (let i = 0; i < pageDataArray.length; i++) {
+                let offsetY = 0;
+                let mergeBand = {};
+                mergeBand[JV.PROP_LEFT] = [];
+                mergeBand[JV.PROP_RIGHT] = [];
+                mergeBand[JV.PROP_TOP] = [];
+                mergeBand[JV.PROP_BOTTOM] = [];
+                newPagePos.push(mergeBand);
+                mergeBand[JV.PROP_LEFT].push(pageDataArray[i][JV.BAND_PROP_MERGE_BAND][JV.PROP_LEFT]);
+                mergeBand[JV.PROP_RIGHT].push(pageDataArray[i][JV.BAND_PROP_MERGE_BAND][JV.PROP_RIGHT]);
+                sheetNames.push(pageDataArray[i][JV.NODE_PAGE_INFO][JV.NODE_MAIN_INFO_RPT_NAME]);
+
+                for (let j = 0; j < pageDataArray[i].items.length; j++) {
+                    let maxY = 0, minY = 100000;
+                    mergeBand[JV.PROP_TOP].push(pageDataArray[i][JV.BAND_PROP_MERGE_BAND][JV.PROP_TOP] + offsetY);
+                    mergeBand[JV.PROP_BOTTOM].push(pageDataArray[i][JV.BAND_PROP_MERGE_BAND][JV.PROP_BOTTOM] + offsetY);
+                    for (let k = 0; k < pageDataArray[i].items[j].cells.length; k++) {
+                        if (maxY < pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_BOTTOM]) {
+                            maxY = pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_BOTTOM];
+                        }
+                        if (minY > pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_TOP]) {
+                            minY = pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_TOP];
+                        }
+                        pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_BOTTOM] += offsetY;
+                        pageDataArray[i].items[j].cells[k][JV.PROP_AREA][JV.PROP_TOP] += offsetY;
+                    }
+                    offsetY += (maxY - minY);
+                }
+            }
+            //2. newPageData的items属性
+            newPageData.items = [];
+            for (let i = 0; i < pageDataArray.length; i++) {
+                let pageItem = {};
+                pageItem[JV.PROP_PAGE_SEQ] = i + 1;
+                pageItem[JV.PROP_CELLS] = [];
+                for (let j = 0; j < pageDataArray[i].items.length; j++) {
+                    for (let k = 0; k < pageDataArray[i].items[j].cells.length; k++) {
+                        pageItem[JV.PROP_CELLS].push(pageDataArray[i].items[j].cells[k]);
+                    }
+                }
+                pageItem[JV.PAGE_SPECIAL_MERGE_POS] = newPagePos[i];
+                newPageData.items.push(pageItem);
+            }
+            //3. everything is ok, then call me
+            me.exportExcel(newPageData, paperSize, fName, 'false', sheetNames, callback);
+            fsUtil.wirteObjToFile(newPageData, 'D:/GitHome/ConstructionOperation/tmp/combinedHeader.js');
+        } catch (e) {
+            console.log(e);
+        }
     }
 }

+ 7 - 0
public/fsUtil.js

@@ -24,5 +24,12 @@ module.exports = {
                 console.log('Write file: ' + filePath + ' ok!');
             });
         }
+    },
+    wirteObjToFile: function(obj, filePath) {
+        if (obj) {
+            let arr = [];
+            arr.push(JSON.stringify(obj));
+            this.writeArrayToFile(arr, filePath);
+        }
     }
 }

+ 3 - 0
public/web/rpt_value_define.js

@@ -35,6 +35,7 @@ let JV = {
     NODE_MAIN_INFO: "主信息",
     NODE_MAIN_INFO_RPT_NAME: "报表名称",
     NODE_PAGE_INFO: "打印页面_信息",
+    NODE_PAGE_SIZE: "纸张宽高",
     NODE_MARGINS: "页边距",
 
     NODE_FONT_COLLECTION: "font_collection",
@@ -192,8 +193,10 @@ let JV = {
     OFFSET_IDX_BOTTOM: 3,
 
     PROP_PAGE_SEQ: "page_seq",
+    PROP_CELLS: "cells",
 
     PAGE_SELF_DEFINE: "自定义",
+    PAGE_SPECIAL_MERGE_POS: "page_merge_pos",
 
     PAGES_SIZE_STR: ["A3", "A4", "A5", "B5", "LETTER", "LEGAL", "EXECUTIVE", "16K"],
     PAGES_SIZE_IDX: [8, 9, 11, 13, 1, 5, 7, 93],

+ 19 - 2
test/calculation/testJSCalc.js

@@ -4,8 +4,25 @@
 
 var test = require('tape');
 
-test('计算式测试', function(t){
-    console.log(10 / 96 * 25.4 / 0.3612);
+// test('计算式测试', function(t){
+//     console.log(10 / 96 * 25.4 / 0.3612);
+//     t.pass('just pass for js calculation!');
+//     t.end();
+// })
+
+test('四舍五入测试', function(t){
+    let a1 = Math.round(17.4, 2);
+    let a2 = Math.round(17.5, 2);
+    let a3 = Math.round(17.6, 2);
+    let a4 = Math.round(18.4, 2);
+    let a5 = Math.round(18.5, 2);
+    let a6 = Math.round(18.6, 2);
+    console.log(a1);
+    console.log(a2);
+    console.log(a3);
+    console.log(a4);
+    console.log(a5);
+    console.log(a6);
     t.pass('just pass for js calculation!');
     t.end();
 })

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

@@ -183,7 +183,7 @@ let JpcCanvasOutput = {
     },
     drawPageBorder: function(rptTpl, canvas, resolution) {
         var me = this;
-        var size = rptTpl[JV.NODE_PAGE_INFO].slice(0);
+        var size = rptTpl[JV.NODE_PAGE_INFO][JV.NODE_PAGE_SIZE].slice(0);
         size[0] = Math.round(resolution[0] * size[0]);
         size[1] = Math.round(resolution[0] * size[1]);
 

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

@@ -5,6 +5,7 @@
 let JV = {
     NODE_MAIN_INFO: "主信息",
     NODE_PAGE_INFO: "打印页面_信息",
+    NODE_PAGE_SIZE: "纸张宽高",
     NODE_MARGINS: "页边距",
 
     NODE_FONT_COLLECTION: "font_collection",

+ 10 - 0
web/maintain/report/rpt_test.html

@@ -33,6 +33,7 @@
                 <input type="button" value="后一页 >" onclick="showPage(1)"/>
                 <input type="button" value="打印" onclick="printCurrentPage()"/>
                 <input type="button" value="Excel" onclick="getExcel()"/>
+                <input type="button" value="ExcelInOneBook" onclick="getExcelInOneBook()"/>
                 <input type="button" value="PDF" onclick="getPDF()"/>
                 <label>
                     <input type="checkbox" id="isOneSheetChk" onclick="isOneSheet = this.checked;">
@@ -131,6 +132,14 @@
         window.location = url;//这里不能使用get方法跳转,否则下载不成功
     }
 
+    function getExcelInOneBook() {
+        let rptIds = "2,3";
+        let size = "A4";
+        let rpt_name = 'OneBook';
+        let url =  "/report_api/getExcelInOneBook/" + rptIds + "/" + size + "/" + rpt_name;
+        window.location = url;//这里不能使用get方法跳转,否则下载不成功
+    }
+
     function getPDF() {
         let rpt = document.getElementById("select_k1");
         let size = document.getElementById("select_k2");
@@ -179,6 +188,7 @@
             });
         }
     }
+
 </script>
 
 </html>