Selaa lähdekoodia

指标对比,可导出Excel

MaiXinRong 7 vuotta sitten
vanhempi
commit
853375fcdf

+ 4 - 0
app/controller/compare_controller.js

@@ -34,6 +34,9 @@ module.exports = app => {
             try {
                 const data = JSON.parse(ctx.request.body.data);
                 const tenders = data.tenders;
+                if (!data.keyword || data.keyword === '') {
+                    throw '请输入查询关键字';
+                }
                 for (const tender of tenders) {
                     if (!tender.lib_id) {
                         throw '查询的标段有误或不存在';
@@ -51,6 +54,7 @@ module.exports = app => {
             } catch (err) {
                 responseData.err = 1;
                 responseData.msg = err.toString();
+                console.log(err);
             }
 
             //console.log('end' + new Date());

+ 1 - 1
app/extend/helper.js

@@ -133,7 +133,7 @@ module.exports = {
         return reg1.test(code) && reg2.test(code) && (!reg3.test(code));
     },
     /**
-     * 检查code 是否是 指标节点编号
+     * 检查code 是否是 指标编号
      * @param {String} code
      * @returns {boolean}
      */

+ 29 - 17
app/public/js/compare.js

@@ -51,7 +51,7 @@ $(document).ready(function () {
             cols.code = 0;
             this.sheet.getCell(0, cols.code).text('指标编号').hAlign(hCenter).vAlign(vCenter);
             this.sheet.addSpan(0, cols.code, 2, 1);
-            this.sheet.setColumnWidth(cols.code, 100);
+            this.sheet.setColumnWidth(cols.code, 80);
 
             colsName.push('name');
             cols.name = 1;
@@ -65,8 +65,8 @@ $(document).ready(function () {
             cols.unit2 = 3;
             this.sheet.getCell(0, cols.unit1).text('指标单位').hAlign(hCenter).vAlign(vCenter);
             this.sheet.addSpan(0, cols.unit1, 2, 2);
-            this.sheet.setColumnWidth(cols.unit1, 60);
-            this.sheet.setColumnWidth(cols.unit2, 60);
+            this.sheet.setColumnWidth(cols.unit1, 65);
+            this.sheet.setColumnWidth(cols.unit2, 65);
 
             if (this.tenders.length > 0) {
                 this.sheet.getCell(0, cols.unit2+1).text('经济指标').hAlign(hCenter).vAlign(vCenter);
@@ -102,12 +102,11 @@ $(document).ready(function () {
 
             this.colsName = colsName;
             this.cols = cols;
-            //this.sheet.getRange(-1, -1, this.sheet.getRowCount(), this.sheet.getColumnCount()).setBorder(this.borderLine, {all: true});
+            this.sheet.getRange(0, 0, this.sheet.getRowCount(), this.sheet.getColumnCount()).setBorder(this.borderLine, {all: true});
 
             SpreadJsObj.endMassOperationSheet(this.sheet);
         }
         sortData (data) {
-            console.log(data);
             function findTenderData (data, tenderId) {
                 for (const tender of data) {
                     if (tender.lib_id === tenderId) {
@@ -166,28 +165,29 @@ $(document).ready(function () {
                     }
                 }
             }
-            console.log(result);
             return result;
         }
         loadData (data) {
             const self = this;
+            const colCount = compareObj.tenders.length > 0 ? 6+compareObj.tenders.length+1 : 6;
             this.searchData = data;
             this.showData = this.sortData(this.searchData);
-            console.log(new Date());
             function loadNode (node, row) {
-                self.sheet.getCell(row, self.cols.code).text(node.code);
-                self.sheet.getCell(row, self.cols.name).text(node.name);
-                self.sheet.getRange(row, -1, 1, -1).backColor('#dae5ee');
+                self.sheet.getCell(row, self.cols.code).text(node.code).wordWrap(true);
+                self.sheet.getCell(row, self.cols.name).text(node.name).wordWrap(true);
+                self.sheet.getRange(row, 0, 1, colCount).backColor('#dae5ee');
+                self.sheet.autoFitRow(row);
             }
             function loadIndex(index, row) {
                 for (const colName of self.colsName) {
                     if (colName === 'averageIndex') {
                         const aver = Number((index.sumValue / self.tenders.length).toFixed(2));
-                        self.sheet.getCell(row, self.cols[colName]).value(aver);
+                        self.sheet.getCell(row, self.cols[colName]).value(aver).wordWrap(true);
                     } else if (index[colName]) {
-                        self.sheet.getCell(row, self.cols[colName]).value(index[colName]);
+                        self.sheet.getCell(row, self.cols[colName]).value(index[colName]).wordWrap(true);
                     }
                 }
+                self.sheet.autoFitRow(row);
             }
             let iRow = 2;
             SpreadJsObj.massOperationSheet(this.sheet, function () {
@@ -202,9 +202,8 @@ $(document).ready(function () {
                         iRow += 1;
                     }
                 }
-                //self.sheet.getRange(-1, -1, self.sheet.getRowCount(), self.sheet.getColumnCount()).setBorder(self.borderLine, {all: true});
+                self.sheet.getRange(-1, -1, self.sheet.getRowCount(), self.sheet.getColumnCount()).setBorder(self.borderLine, {all: true});
             });
-            console.log(new Date());
         }
         searchIndex (keyword) {
             const self = this;
@@ -212,9 +211,7 @@ $(document).ready(function () {
                 tenders: this.tenders,
                 keyword: keyword,
             };
-            console.log(new Date());
             postData('/compare/search', data, function (datas) {
-                console.log(new Date());
                 self.loadData(datas);
             });
         }
@@ -237,6 +234,15 @@ $(document).ready(function () {
 
     $('#search').click(function () {
         compareObj.searchIndex($('#keyword').val());
+    });
+
+    $('#export-excel').click(function () {
+        const excelIo = new GC.Spread.Excel.IO();
+        const fileName = '指标对比.xlsx';
+        const sJson = JSON.stringify(compareObj.spread.toJSON());
+        excelIo.save(sJson, function(blob) {
+            saveAs(blob, fileName);
+        });
     })
 
     // $.contextMenu({
@@ -265,12 +271,18 @@ $(document).ready(function () {
     //             name: '导出excel',
     //             callback: function (key, opt) {
     //                 const excelIo = new GC.Spread.Excel.IO();
-    //                 const fileName = 'e:\\1.xlsx';
+    //                 const fileName = '1.xlsx';
     //                 const sJson = JSON.stringify(compareObj.spread.toJSON());
     //                 excelIo.save(sJson, function(blob) {
     //                     saveAs(blob, fileName);
     //                 });
     //             }
+    //         },
+    //         'exportPDF': {
+    //             name: '导出PDF',
+    //             callback: function (key, opt) {
+    //                  compareObj.spread.savePDF();
+    //             }
     //         }
     //     }
     // });

+ 182 - 0
app/public/js/file-saver/FileSaver.js

@@ -0,0 +1,182 @@
+/* FileSaver.js
+ * A saveAs() FileSaver implementation.
+ * 1.3.8
+ * 2018-03-22 14:03:47
+ *
+ * By Eli Grey, https://eligrey.com
+ * License: MIT
+ *   See https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
+ */
+
+/*global self */
+/*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
+
+/*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/src/FileSaver.js */
+
+var saveAs = saveAs || (function(view) {
+	"use strict";
+	// IE <10 is explicitly unsupported
+	if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {
+		return;
+	}
+	var
+		  doc = view.document
+		  // only get URL when necessary in case Blob.js hasn't overridden it yet
+		, get_URL = function() {
+			return view.URL || view.webkitURL || view;
+		}
+		, save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")
+		, can_use_save_link = "download" in save_link
+		, click = function(node) {
+			var event = new MouseEvent("click");
+			node.dispatchEvent(event);
+		}
+		, is_safari = /constructor/i.test(view.HTMLElement) || view.safari
+		, is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)
+		, setImmediate = view.setImmediate || view.setTimeout
+		, throw_outside = function(ex) {
+			setImmediate(function() {
+				throw ex;
+			}, 0);
+		}
+		, force_saveable_type = "application/octet-stream"
+		// the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
+		, arbitrary_revoke_timeout = 1000 * 40 // in ms
+		, revoke = function(file) {
+			var revoker = function() {
+				if (typeof file === "string") { // file is an object URL
+					get_URL().revokeObjectURL(file);
+				} else { // file is a File
+					file.remove();
+				}
+			};
+			setTimeout(revoker, arbitrary_revoke_timeout);
+		}
+		, dispatch = function(filesaver, event_types, event) {
+			event_types = [].concat(event_types);
+			var i = event_types.length;
+			while (i--) {
+				var listener = filesaver["on" + event_types[i]];
+				if (typeof listener === "function") {
+					try {
+						listener.call(filesaver, event || filesaver);
+					} catch (ex) {
+						throw_outside(ex);
+					}
+				}
+			}
+		}
+		, auto_bom = function(blob) {
+			// prepend BOM for UTF-8 XML and text/* types (including HTML)
+			// note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
+			if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
+				return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});
+			}
+			return blob;
+		}
+		, FileSaver = function(blob, name, no_auto_bom) {
+			if (!no_auto_bom) {
+				blob = auto_bom(blob);
+			}
+			// First try a.download, then web filesystem, then object URLs
+			var
+				  filesaver = this
+				, type = blob.type
+				, force = type === force_saveable_type
+				, object_url
+				, dispatch_all = function() {
+					dispatch(filesaver, "writestart progress write writeend".split(" "));
+				}
+				// on any filesys errors revert to saving with object URLs
+				, fs_error = function() {
+					if ((is_chrome_ios || (force && is_safari)) && view.FileReader) {
+						// Safari doesn't allow downloading of blob urls
+						var reader = new FileReader();
+						reader.onloadend = function() {
+							var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');
+							var popup = view.open(url, '_blank');
+							if(!popup) view.location.href = url;
+							url=undefined; // release reference before dispatching
+							filesaver.readyState = filesaver.DONE;
+							dispatch_all();
+						};
+						reader.readAsDataURL(blob);
+						filesaver.readyState = filesaver.INIT;
+						return;
+					}
+					// don't create more object URLs than needed
+					if (!object_url) {
+						object_url = get_URL().createObjectURL(blob);
+					}
+					if (force) {
+						view.location.href = object_url;
+					} else {
+						var opened = view.open(object_url, "_blank");
+						if (!opened) {
+							// Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
+							view.location.href = object_url;
+						}
+					}
+					filesaver.readyState = filesaver.DONE;
+					dispatch_all();
+					revoke(object_url);
+				}
+			;
+			filesaver.readyState = filesaver.INIT;
+
+			if (can_use_save_link) {
+				object_url = get_URL().createObjectURL(blob);
+				setImmediate(function() {
+					save_link.href = object_url;
+					save_link.download = name;
+					click(save_link);
+					dispatch_all();
+					revoke(object_url);
+					filesaver.readyState = filesaver.DONE;
+				}, 0);
+				return;
+			}
+
+			fs_error();
+		}
+		, FS_proto = FileSaver.prototype
+		, saveAs = function(blob, name, no_auto_bom) {
+			return new FileSaver(blob, name || blob.name || "download", no_auto_bom);
+		}
+	;
+
+	// IE 10+ (native saveAs)
+	if (typeof navigator !== "undefined" && navigator.msSaveOrOpenBlob) {
+		return function(blob, name, no_auto_bom) {
+			name = name || blob.name || "download";
+
+			if (!no_auto_bom) {
+				blob = auto_bom(blob);
+			}
+			return navigator.msSaveOrOpenBlob(blob, name);
+		};
+	}
+
+	// todo: detect chrome extensions & packaged apps
+	//save_link.target = "_blank";
+
+	FS_proto.abort = function(){};
+	FS_proto.readyState = FS_proto.INIT = 0;
+	FS_proto.WRITING = 1;
+	FS_proto.DONE = 2;
+
+	FS_proto.error =
+	FS_proto.onwritestart =
+	FS_proto.onprogress =
+	FS_proto.onwrite =
+	FS_proto.onabort =
+	FS_proto.onerror =
+	FS_proto.onwriteend =
+		null;
+
+	return saveAs;
+}(
+	   typeof self !== "undefined" && self
+	|| typeof window !== "undefined" && window
+	|| this
+));

+ 14 - 8
app/view/compare/index.ejs

@@ -1,14 +1,19 @@
 <div class="panel-content">
     <div class="panel-title fluid">
-        <div class="title-main">
-            <div class="btn-group">
-                <a class="btn btn-primary btn-sm" href="#generate-data" data-toggle="modal" data-target="#generate-data">造价文件:0</a>
+        <div class="title-main d-flex justify-content-between">
+            <div>
+                <div class="btn-group">
+                    <a class="btn btn-primary btn-sm" href="#generate-data" data-toggle="modal" data-target="#generate-data">造价文件:0</a>
+                </div>
+                <div class="btn-group pr-0">
+                    <input type="text" class="form-control form-control-sm m-0" placeholder="输入指标节点编号或者名称" id="keyword" style="width:200px">
+                </div>
+                <div class="btn-group">
+                    <button class="btn btn-sm btn-primary " type="button" id="search">搜索</button>
+                </div>
             </div>
-            <div class="btn-group col-2 pr-0">
-                <input type="text" class="form-control form-control-sm m-0" placeholder="输入指标节点编号或者名称" id="keyword">
-            </div>
-            <div class="btn-group">
-                <button class="btn btn-sm btn-primary " type="button" id="search">搜索</button>
+            <div>
+                <a href="javascript: void(0)" class="btn btn-primary btn-sm pull-right" target="_blank" id="export-excel">导出Excel</a>
             </div>
         </div>
     </div>
@@ -21,6 +26,7 @@
         </div>
     </div>
 </div>
+<script src="/public/js/file-saver/FileSaver.js"></script>
 <script src="/public/js/spreadjs/sheets/gc.spread.sheets.all.10.0.1.min.js"></script>
 <script src="/public/js/spreadjs/sheets/pluggable/gc.spread.sheets.print.10.0.1.min.js"></script>
 <script src="/public/js/spreadjs/sheets/interop/gc.spread.excelio.10.0.1.min.js"></script>