Jelajahi Sumber

excel export unit test

TonyKang 8 tahun lalu
induk
melakukan
21ceba0eab

+ 72 - 23
modules/reports/util/rpt_excel_util.js

@@ -46,7 +46,7 @@ function writeApp(sheets) {
     rst.push('<ScaleCrop>false</ScaleCrop>');
     rst.push('<HeadingPairs>');
     rst.push('<vt:vector size="2" baseType="variant">');
-    rst.push('<vt:variant><vt:lpstr>¹¤×÷±í</vt:lpstr></vt:variant>');
+    rst.push('<vt:variant><vt:lpstr>工作表</vt:lpstr></vt:variant>');
     rst.push('<vt:variant><vt:i4>' + sheets.length + '</vt:i4></vt:variant>');
     rst.push('</vt:vector>');
     rst.push('</HeadingPairs>');
@@ -129,16 +129,28 @@ function writeStyles(styleList){
     //
 }
 function writeSharedString(sharedStrList){
-    //
+    var rst = [];
+    if (sharedStrList && sharedStrList.length > 0) {
+        rst.push(dftHeadXml + '\r\n');
+        rst.push('<sst xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" count="' + sharedStrList.length + '" uniqueCount="' + sharedStrList.length + '">');
+        for (var i = 0; i < sharedStrList.length; i++) {
+            rst.push('<si><t>' + sharedStrList[i] + '</t></si>');
+        }
+        rst.push('</sst>');
+    }
+    return rst;
 }
-function writeSheets(pageData){
-    var rst = [], sharedStrList = [], styleList= [];
+function writeSheets(pageData, sharedStrList, styleList){
+    var rst = [];
     for (var i = 0; i < pageData.items.length; i++) {
-        rst.push(writeSheet(sheetData, sharedStrList, styleList));
+        rst.push(writeSheet(pageData.items[i], sharedStrList, styleList));
     }
+    return rst;
 }
 function writeSheet(sheetData, sharedStrList, styleList){
-    var rst = [], xPos = [0], yPos = [0], headerStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+    var rst = [], xPos = [], yPos = [], headerStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+    xPos.push(0);
+    yPos.push(0);
     private_pre_analyze_pos = function(){
         var cell, pos;
         sheetData.cells.sort(function(cell1, cell2) {
@@ -154,6 +166,7 @@ function writeSheet(sheetData, sharedStrList, styleList){
                     rst = -1;
                 }
             }
+            return rst;
         });
         for (var i = 0; i < sheetData.cells.length; i++) {
             cell = sheetData.cells[i];
@@ -166,8 +179,14 @@ function writeSheet(sheetData, sharedStrList, styleList){
             pos = cell[JV.PROP_AREA][JV.PROP_BOTTOM];
             if (yPos.indexOf(pos) < 0) yPos.push(pos);
         }
-        xPos.sort();
-        yPos.sort();
+        xPos.sort(private_array_sort);
+        yPos.sort(private_array_sort);
+    };
+    private_array_sort = function(i1, i2){
+        var rst = 0;
+        if (i1 > i2) {rst = 1} else
+        if (i1 < i2) rst = -1;
+        return rst;
     };
     private_getCellIdxStr = function(idx){
         var rst = 'A';
@@ -196,12 +215,13 @@ function writeSheet(sheetData, sharedStrList, styleList){
         return rst;
     };
     private_setCols = function(){
+        //remark: 1 excel width = 2.117 mm
         rst.push('<cols>');
         var w = 0;
         for (var i = 1; i < xPos.length; i++) {
-            w = 1.0 * (xPos[i] - xPos[i - 1]) / DPI;
+            w = 1.0 * (xPos[i] - xPos[i - 1]) / DPI * 25.4 / 2.117;
             w = Math.round(w * 1000) / 1000;
-            rst.push('<col min="1" max="1" width="' + w + '" customWidth="1"/>');
+            rst.push('<col min="' + i +'" max="' + i +'" width="' + w + '" customWidth="1"/>');
         }
         rst.push('</cols>');
     };
@@ -224,18 +244,19 @@ function writeSheet(sheetData, sharedStrList, styleList){
         rst.push('</mergeCells>');
     };
     private_setSheetData = function(){
+        //remark: 1 excel height = 0.3612 mm
         rst.push('<sheetData>');
         var spanX = xPos.length - 1, cellIdx = 0, h = 0,
             hasMoreCols = true, nextColIdx = -1,
             nextRowIdx = yPos.indexOf(sheetData.cells[cellIdx][JV.PROP_AREA][JV.PROP_TOP]);
-        for (var i = 0; i < yPos.length - 1; i++) {
+        for (var i = 1; i < yPos.length - 1; i++) {
             if (i === 0) {
-                h = 1.0 * (yPos[i]) / DPI;
+                h = 1.0 * (yPos[i]) / DPI * 25.4 / 0.3612;
             } else {
-                h = 1.0 * (yPos[i] - yPos[i - 1]) / DPI;
+                h = 1.0 * (yPos[i] - yPos[i - 1]) / DPI * 25.4 / 0.3612;
             }
             h = Math.round(h * 1000) / 1000;
-            rst.push('<row r="' + (i+1) + '" spans="1:' + spanX + '" ht="' + h + '" customHeight="1">');
+            rst.push('<row r="' + i + '" spans="1:' + spanX + '" ht="' + h + '" customHeight="1">');
             //then put the cells of this row
             var colIdxStr = '';
             hasMoreCols = true;
@@ -257,33 +278,37 @@ function writeSheet(sheetData, sharedStrList, styleList){
                     if (nextColIdx == j) {
                         var styleIdx = private_getStyleIdx(sheetData.cells[cellIdx]);
                         if (strUtil.isEmptyString(sheetData.cells[cellIdx][JV.PROP_VALUE])) {
-                            rst.push('<c r="' + colIdxStr + (i+1) + '" s="' + styleIdx + '"/>');
+                            rst.push('<c r="' + colIdxStr + i + '" s="' + styleIdx + '"/>');
                             //should setup the right style instead!
                         } else {
                             var valIdx = private_getSharedStrIdx(sheetData.cells[cellIdx][JV.PROP_VALUE]);
-                            rst.push('<c r="' + colIdxStr + (i+1) + '" s="' + styleIdx + '">');
+                            rst.push('<c r="' + colIdxStr + i + '" s="' + styleIdx + '">');
                             rst.push('<v>' + valIdx + '</v>');
                             rst.push('</c>');
                         }
                         cellIdx++;
-                        nextRowIdx = yPos.indexOf(sheetData.cells[cellIdx][JV.PROP_AREA][JV.PROP_TOP]);
-                        if (nextRowIdx > i) {
-                            hasMoreCols = false;
+                        if (cellIdx < sheetData.cells.length) {
+                            nextRowIdx = yPos.indexOf(sheetData.cells[cellIdx][JV.PROP_AREA][JV.PROP_TOP]);
+                            if (nextRowIdx > i) {
+                                hasMoreCols = false;
+                            } else {
+                                nextColIdx = xPos.indexOf(sheetData.cells[cellIdx][JV.PROP_AREA][JV.PROP_LEFT]);
+                            }
                         } else {
-                            nextColIdx = xPos.indexOf(sheetData.cells[cellIdx][JV.PROP_AREA][JV.PROP_LEFT]);
+                            hasMoreCols = false;
                         }
                     } else if (nextColIdx < 0) {
                         //impossible!
                         console.log('has abnormal case!');
                         hasMoreCols = false;
                     } else {
-                        rst.push('<c r="' + colIdxStr + (i+1) + '" s="1"/>');
+                        rst.push('<c r="' + colIdxStr + i + '" s="1"/>');
                     }
                 } else {
-                    rst.push('<c r="' + colIdxStr + (i+1) + '" s="1"/>');
+                    rst.push('<c r="' + colIdxStr + i + '" s="1"/>');
                 }
             }
-            rst.push('</row');
+            rst.push('</row>');
         }
         //sheetData.cells.length
         rst.push('</sheetData>');
@@ -313,4 +338,28 @@ module.exports = {
     exportExcel: function (pageData, options) {
         var rptOptions = (options || {singlePage: false, fileName: 'report'});
     }
+    ,testWriteContentTypes: function(sheets) {
+        return writeContentTypes(sheets);
+    }
+    ,testWriteRootRels: function() {
+        return writeRootRels();
+    }
+    ,testWriteApp: function(sheets) {
+        return writeApp(sheets);
+    }
+    ,testWriteCore: function() {
+        return writeCore();
+    }
+    ,testWriteXlWorkBook: function(sheets) {
+        return writeXlWorkBook(sheets);
+    }
+    ,testWriteXlRels: function(sheets) {
+        return writeXlRels(sheets);
+    }
+    ,testWriteSheets: function(pageData, sharedStrList, styleList){
+        return writeSheets(pageData, sharedStrList, styleList);
+    }
+    ,testWriteSharedString: function(sharedStrList){
+        return writeSharedString(sharedStrList);
+    }
 }

+ 28 - 0
public/fsUtil.js

@@ -0,0 +1,28 @@
+/**
+ * Created by Tony on 2017/4/10.
+ */
+
+var fs = require('fs');
+
+module.exports = {
+    writeArrayToFile: function(arr, filePath) {
+        if (arr && filePath && Array.isArray(arr)) {
+            var chunks = [], len = 0;
+            for (var i = 0; i < arr.length; i++) {
+                var buffer = new Buffer(arr[i]);
+                chunks.push(buffer);
+                len += buffer.length;
+                //
+            }
+            var resultBuffer = new Buffer(len);
+            for(var i=0,size=chunks.length,pos=0;i<size;i++){
+                chunks[i].copy(resultBuffer,pos);
+                pos += chunks[i].length;
+            }
+            fs.writeFile(filePath, resultBuffer, function(err){
+                if(err) throw err;
+                console.log('Write file: ' + filePath + ' ok!');
+            });
+        }
+    }
+}

+ 31 - 0
public/stringUtil.js

@@ -8,5 +8,36 @@ module.exports = {
             rst = reg.test(str);
         }
         return rst;
+    },
+    convertNumToChinese : function(num, isCurrency) {
+        if (!/^\d*(\.\d*)?$/.test(num)) { return "Number is wrong!"; }
+        var AA, BB;
+        if (isCurrency) {
+            AA = new Array("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖");
+            BB = new Array("", "拾", "佰", "仟", "萬", "億", "点", "");
+        } else {
+            AA = ['零','一','二','三','四','五','六','七','八','九'];
+            BB = new Array("", "十", "百", "千", "万", "亿", "点", "");
+        }
+        //var AA = new Array("零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖");
+        //var BB = new Array("", "拾", "佰", "仟", "萬", "億", "点", "");
+        var a = ("" + num).replace(/(^0*)/g, "").split("."), k = 0, re = "";
+        for (var i = a[0].length - 1; i >= 0; i--) {
+            switch (k) {
+                case 0: re = BB[7] + re; break;
+                case 4: if (!new RegExp("0{4}\\d{" + (a[0].length - i - 1) + "}$").test(a[0]))
+                    re = BB[4] + re; break;
+                case 8: re = BB[5] + re; BB[7] = BB[5]; k = 0; break;
+            }
+            if (k % 4 == 2 && a[0].charAt(i + 2) != 0 && a[0].charAt(i + 1) == 0) re = AA[0] + re;
+            if (a[0].charAt(i) != 0) re = AA[a[0].charAt(i)] + BB[k % 4] + re; k++;
+        }
+
+        if (a.length > 1) //加上小数部分(如果有小数部分)
+        {
+            re += BB[6];
+            for (var i = 0; i < a[1].length; i++) re += AA[a[1].charAt(i)];
+        }
+        return re;
     }
 }

+ 7 - 2
test/demo/demo.js

@@ -29,8 +29,13 @@ test('', function(t){
 })
 
 test('default sorting...', function(t){
-    var arrSimple=new Array(1,8,7,6);
-    arrSimple.sort();
+    var arrSimple=new Array(1,8,7,6,10,11);
+    arrSimple.sort(function(i1, i2){
+        rst = 0;
+        if (i1 > i2) {rst = 1} else
+        if (i1 < i2) rst = -1;
+        return rst;
+    });
     console.log(arrSimple);
     t.pass('just pass');
     t.end();

+ 41 - 29
test/demo/stringTest.js

@@ -3,36 +3,48 @@
  */
 
 var test = require('tape');
+var strUtil = require('../../public/stringUtil');
 
-test('some string test cases', function (t) {
-    var reg = /^\s*$/;
-    var foo = "   ";
-    t.equal(reg.test(foo), true);
-    foo = null;
-    t.equal(reg.test(foo), true);
-    foo = undefined;
-    t.equal(reg.test(foo), true);
-    foo = "";
-    t.equal(reg.test(foo), true);
-    foo = 0;
-    t.equal(reg.test(foo), true);
-    t.end();
-});
+//test('some string test cases', function (t) {
+//    var reg = /^\s*$/;
+//    var foo = "   ";
+//    t.equal(reg.test(foo), true);
+//    foo = null;
+//    t.equal(reg.test(foo), true);
+//    foo = undefined;
+//    t.equal(reg.test(foo), true);
+//    foo = "";
+//    t.equal(reg.test(foo), true);
+//    foo = 0;
+//    t.equal(reg.test(foo), true);
+//    t.end();
+//});
+//
+//test('check if string type', function(t){
+//    var foo = "";
+//    t.equal(typeof foo, 'string');
+//    foo = " ";
+//    t.equal(typeof foo, 'string');
+//    foo = 0;
+//    t.equal(typeof foo, 'number');
+//    foo = true;
+//    t.equal(typeof foo, 'boolean');
+//    foo = {};
+//    t.equal(typeof foo, 'object');
+//    foo = function(){};
+//    t.equal(typeof foo, 'function');
+//    foo = [];
+//    t.equal(Array.isArray(foo), true);
+//    t.end();
+//})
 
-test('check if string type', function(t){
-    var foo = "";
-    t.equal(typeof foo, 'string');
-    foo = " ";
-    t.equal(typeof foo, 'string');
-    foo = 0;
-    t.equal(typeof foo, 'number');
-    foo = true;
-    t.equal(typeof foo, 'boolean');
-    foo = {};
-    t.equal(typeof foo, 'object');
-    foo = function(){};
-    t.equal(typeof foo, 'function');
-    foo = [];
-    t.equal(Array.isArray(foo), true);
+test('test number to Chinese', function(t){
+    //t.equal(strUtil.convertNumToChinese(1, true), '壹');
+    //t.equal(strUtil.convertNumToChinese(1, false), '一');
+    t.equal(strUtil.convertNumToChinese(11, false), '一十一');
+    t.equal(strUtil.convertNumToChinese(12, false), '一十二');
+    t.equal(strUtil.convertNumToChinese(21, false), '二十一');
+    //console.log(strUtil.convertNumToChinese(102, false));
+    t.equal(strUtil.convertNumToChinese(102, false), '一百零二');
     t.end();
 })

+ 1 - 1
test/unit/excel_export/fileReadWrite.js

@@ -29,7 +29,7 @@ fs.readFile('../../tmp_data/test_bills_data2.js',function(err,data){
         pos += chunks[i].length;
     }
 
-    fs.writeFile('../../../tmp/resut.text',resultBuffer,function(err){
+    fs.writeFile('../../../tmp/结果.text',resultBuffer,function(err){
         if(err) throw err;
         console.log('has finished');
     });

+ 1 - 0
test/unit/excel_export/privateFunctionTest.js

@@ -35,6 +35,7 @@ test('test private 1', function(t){
         return rst;
     };
     t.equal(private_getCellIdxStr2(0, ''), 'A');
+    t.equal(private_getCellIdxStr2(20, ''), 'U');
     t.equal(private_getCellIdxStr2(25, ''), 'Z');
     t.equal(private_getCellIdxStr2(26, ''), 'AA');
     t.equal(private_getCellIdxStr2(27, ''), 'AB');

+ 46 - 0
test/unit/excel_export/rpt_excel_export_test.js

@@ -0,0 +1,46 @@
+/**
+ * Created by Tony on 2017/4/10.
+ */
+var test = require('tape');
+var fs = require('fs');
+var fsUtil = require('../../../public/fsUtil');
+var rpt_xl_util = require('../../../modules/reports/util/rpt_excel_util');
+
+test('check excel output', function(t){
+    var data = fs.readFileSync('../../../tmp/07_1.page.js', 'utf8', 'r');
+    eval(data);
+    //console.log(testReport07_1);
+    var sheets = [];
+    for (var i = 0; i < testReport07_1.items.length; i++) {
+        sheets.push({sheetName: '第' + (i + 1) + '页'});
+    }
+    var ct = rpt_xl_util.testWriteContentTypes(sheets);
+    fsUtil.writeArrayToFile(ct, '../../../tmp/[Content_Types].xml');
+    t.pass('pass content types');
+    var rootRels = rpt_xl_util.testWriteRootRels();
+    fsUtil.writeArrayToFile(rootRels, '../../../tmp/.rels');
+    t.pass('pass root rels');
+    var app = rpt_xl_util.testWriteApp(sheets);
+    fsUtil.writeArrayToFile(app, '../../../tmp/app.xml');
+    t.pass('pass app');
+    var core = rpt_xl_util.testWriteCore(sheets);
+    fsUtil.writeArrayToFile(core, '../../../tmp/core.xml');
+    t.pass('pass core');
+    var xlWBs = rpt_xl_util.testWriteXlWorkBook(sheets);
+    fsUtil.writeArrayToFile(xlWBs, '../../../tmp/workbook.xml');
+    t.pass('pass workbook');
+    //workbook.xml.rels
+    var xlRels = rpt_xl_util.testWriteXlRels(sheets);
+    fsUtil.writeArrayToFile(xlRels, '../../../tmp/workbook.xml.rels');
+    t.pass('pass xl sheet rels');
+    var sharedStrList = [], styleList= [];
+    var sheetsArr = rpt_xl_util.testWriteSheets(testReport07_1, sharedStrList, styleList);
+    for (var i = 0; i < sheetsArr.length; i++) {
+        fsUtil.writeArrayToFile(sheetsArr[i], '../../../tmp/sheet' + (i + 1) + '.xml');
+        t.pass('pass sheet' + (i + 1));
+    }
+    var sharedStr = rpt_xl_util.testWriteSharedString(sharedStrList);
+    fsUtil.writeArrayToFile(sharedStr, '../../../tmp/sharedStrings.xml');
+    t.pass('pass shared string');
+    t.end();
+});

+ 1 - 1
tmp/07_1.page.js

@@ -1,4 +1,4 @@
-{
+var testReport07_1 = {
 	"control_collection": {
 		"Default": {
 			"Shrink": "T",