Lmm 1 year ago
parent
commit
75361406ba
5 changed files with 574 additions and 516 deletions
  1. 74 43
      src/App.vue
  2. 355 355
      src/components/Excel/Export2Excel.js
  3. 16 1
      src/components/PopMoreTable.vue
  4. 36 24
      src/js/common.js
  5. 93 93
      src/js/scrollbar.js

+ 74 - 43
src/App.vue

@@ -83,9 +83,9 @@
 						<span 
 							v-if="scope.row.host_connect_status != undefined && scope.row.host_connect_status != null" 
 							class="el-table-tag" 
-							:style="{ background: connectStatColor(scope.row.host_connect_status) }"
+							:style="{ background: connectStatColor(scope.row, 'host_connect_status') }"
 						>
-							{{ connectStatText(scope.row.host_connect_status) }}
+							{{ connectStatText(scope.row, 'host_connect_status') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -95,9 +95,9 @@
 						<span 
 							v-if="scope.row.host_fault != undefined && scope.row.host_fault != null" 
 							class="el-table-tag" 
-							:style="{ background: faultColor(scope.row.host_fault) }"
+							:style="{ background: faultColor(scope.row, 'host_fault') }"
 						>
-							{{ faultText(scope.row.host_fault) }}
+							{{ faultText(scope.row, 'host_fault') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -105,7 +105,7 @@
 				<el-table-column prop="host_su_temp" label="供水水温(℃)" align="center" width="120">
 					<template slot-scope="scope">
 						<span v-if="scope.row.host_su_temp" class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.host_su_temp) }}
+							{{ fixedVal(scope.row, 'host_su_temp') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -113,7 +113,7 @@
 				<el-table-column prop="host_re_temp" label="回水水温(℃)" align="center" width="120">
 					<template slot-scope="scope">
 						<span v-if="scope.row.host_re_temp" class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.host_re_temp) }}
+							{{ fixedVal(scope.row, 'host_re_temp') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -122,9 +122,13 @@
 					<template slot-scope="scope">
 						<div v-if="scope.row.host_temp_diff">
 							<span class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-								{{ fixedVal(scope.row.host_temp_diff) }}
+								{{ fixedVal(scope.row, 'host_temp_diff') }}
 							</span>
-							<i v-if="scope.row.hpCnt > scope.row.maxCnt" class="el-icon-caret-bottom ml10" @click.stop="handleClickMore(scope.row, 'host')"></i>
+							<i 
+								v-if="scope.row.hpCnt > scope.row.maxCnt && scope.row.runStatus == 1" 
+								class="el-icon-caret-bottom ml10" 
+								@click.stop="handleClickMore(scope.row, 'host')"
+							></i>
 						</div>
 						<span v-else>/</span>
 					</template>
@@ -144,9 +148,9 @@
 						<span 
 							v-if="scope.row.nt_connect_status != undefined && scope.row.nt_connect_status != null" 
 							class="el-table-tag" 
-							:style="{ background: connectStatColor(scope.row.nt_connect_status) }"
+							:style="{ background: connectStatColor(scope.row, 'nt_connect_status') }"
 						>
-							{{ connectStatText(scope.row.nt_connect_status) }}
+							{{ connectStatText(scope.row, 'nt_connect_status') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -156,9 +160,9 @@
 						<span 
 							v-if="scope.row.nt_fault != undefined && scope.row.nt_fault != null" 
 							class="el-table-tag" 
-							:style="{ background: faultColor(scope.row.nt_fault) }"
+							:style="{ background: faultColor(scope.row, 'nt_fault') }"
 						>
-							{{ faultText(scope.row.nt_fault) }}
+							{{ faultText(scope.row, 'nt_fault') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -166,7 +170,7 @@
 				<el-table-column prop="nt_in_temp" label="送风温度(℃)" align="center" width="120">
 					<template slot-scope="scope">
 						<span v-if="scope.row.nt_in_temp" class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.nt_in_temp) }}
+							{{ fixedVal(scope.row, 'nt_in_temp') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -174,7 +178,7 @@
 				<el-table-column prop="nt_in_humidity" label="送风湿度(%)" align="center" width="120">
 					<template slot-scope="scope">
 						<span v-if="scope.row.nt_in_humidity" class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.nt_in_humidity) }}
+							{{ fixedVal(scope.row, 'nt_in_humidity') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -183,9 +187,13 @@
 					<template slot-scope="scope">
 						<div v-if="scope.row.nt_dew_point">
 							<span class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-								{{ fixedVal(scope.row.nt_dew_point) }}
+								{{ fixedVal(scope.row, 'nt_dew_point') }}
 							</span>
-							<i v-if="scope.row.dhCnt > scope.row.maxCnt" class="el-icon-caret-bottom ml10" @click.stop="handleClickMore(scope.row, 'newTrend')"></i>
+							<i
+								v-if="scope.row.dhCnt > scope.row.maxCnt && scope.row.runStatus == 1" 
+								class="el-icon-caret-bottom ml10" 
+								@click.stop="handleClickMore(scope.row, 'newTrend')"
+							></i>
 						</div>
 						<span v-else>/</span>
 					</template>
@@ -205,9 +213,9 @@
 						<span 
 							v-if="scope.row.hex_connect_status != undefined && scope.row.hex_connect_status != null" 
 							class="el-table-tag" 
-							:style="{ background: connectStatColor(scope.row.hex_connect_status) }"
+							:style="{ background: connectStatColor(scope.row, 'hex_connect_status') }"
 						>
-							{{ connectStatText(scope.row.hex_connect_status)}}
+							{{ connectStatText(scope.row, 'hex_connect_status')}}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -217,9 +225,9 @@
 						<span 
 							v-if="scope.row.hex_fault != undefined && scope.row.hex_fault != null" 
 							class="el-table-tag" 
-							:style="{ background: faultColor(scope.row.hex_fault) }"
+							:style="{ background: faultColor(scope.row, 'hex_fault') }"
 						>
-							{{ faultText(scope.row.hex_fault) }}
+							{{ faultText(scope.row, 'hex_fault') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -227,7 +235,7 @@
 				<el-table-column prop="hex_su_temp" label="供水水温(℃)" align="center" width="120">
 					<template slot-scope="scope">
 						<span v-if="scope.row.hex_su_temp" class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.hex_su_temp) }}
+							{{ fixedVal(scope.row, 'hex_su_temp') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -235,7 +243,7 @@
 				<el-table-column prop="hex_re_temp" label="回水水温(℃)" align="center" width="120">
 					<template slot-scope="scope">
 						<span v-if="scope.row.hex_re_temp" class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.hex_re_temp) }}
+							{{ fixedVal(scope.row, 'hex_re_temp') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -247,7 +255,7 @@
 							class="el-table-tag" 
 							:style="{ background: calcArgsColor(scope) }"
 						>
-							{{ fixedVal(scope.row.hex_temp_diff) }}
+							{{ fixedVal(scope.row, 'hex_temp_diff') }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -255,10 +263,14 @@
 				<el-table-column prop="hex_pump_status" label="水泵状态" align="center" width="120">
 					<template slot-scope="scope">
 						<div v-if="scope.row.hex_pump_status != undefined && scope.row.hex_pump_status != null">
-							<span class="el-table-tag" :style="{ background: hexPumpStateColor(scope.row.hex_pump_status) }">
-								{{ hexPumpStateText(scope.row.hex_pump_status) }}
+							<span class="el-table-tag" :style="{ background: hexPumpStateColor(scope.row, 'hex_pump_status') }">
+								{{ hexPumpStateText(scope.row, 'hex_pump_status') }}
 							</span>
-							<i v-if="scope.row.hexCnt > scope.row.maxCnt" class="el-icon-caret-bottom ml10" @click.stop="handleClickMore(scope.row, 'heatExchange')"></i>
+							<i 
+								v-if="scope.row.hexCnt > scope.row.maxCnt && scope.row.runStatus == 1" 
+								class="el-icon-caret-bottom ml10" 
+								@click.stop="handleClickMore(scope.row, 'heatExchange')"
+							></i>
 						</div>
 						<span v-else>/</span>
 					</template>
@@ -272,7 +284,7 @@
 				<el-table-column prop="end_exception_num" label="通讯异常数量" align="center" width="120">
 					<template slot-scope="scope">
 						<span v-if="scope.row.end_exception_num != undefined && scope.row.end_exception_num != null">
-							{{ scope.row.end_exception_num }}
+							{{ scope.row.runStatus == 1 ? scope.row.end_exception_num : '/' }}
 						</span>
 						<span v-else>/</span>
 					</template>
@@ -280,35 +292,35 @@
 				<el-table-column prop="end_min_temp" label="最低室内温度(℃)" align="center" width="140">
 					<template slot-scope="scope">
 						<span class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.end_min_temp) }}
+							{{ fixedVal(scope.row, 'end_min_temp') }}
 						</span>
 					</template>
 				</el-table-column>
 				<el-table-column prop="end_min_humidity" label="最低室内湿度(%)" align="center" width="140">
 					<template slot-scope="scope">
 						<span class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.end_min_humidity) }}
+							{{ fixedVal(scope.row, 'end_min_humidity') }}
 						</span>
 					</template>
 				</el-table-column>
 				<el-table-column prop="end_min_dew_point" label="最低室内露点(℃)" align="center" width="140">
 					<template slot-scope="scope">
 						<span class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.end_min_dew_point) }}
+							{{ fixedVal(scope.row, 'end_min_dew_point') }}
 						</span>
 					</template>
 				</el-table-column>
 				<el-table-column prop="end_max_temp" label="最高室内温度(℃)" align="center" width="140">
 					<template slot-scope="scope">
 						<span class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.end_max_temp) }}
+							{{ fixedVal(scope.row, 'end_max_temp') }}
 						</span>
 					</template>
 				</el-table-column>
 				<el-table-column prop="end_max_humidity" label="最高室内湿度(%)" align="center" width="140">
 					<template slot-scope="scope">
 						<span class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-							{{ fixedVal(scope.row.end_max_humidity) }}
+							{{ fixedVal(scope.row, 'end_max_humidity') }}
 						</span>
 					</template>
 				</el-table-column>
@@ -316,9 +328,13 @@
 					<template slot-scope="scope">
 						<div>
 							<span class="el-table-tag" :style="{ background: calcArgsColor(scope) }">
-								{{ fixedVal(scope.row.end_max_dew_point) }}
+								{{ fixedVal(scope.row, 'end_max_dew_point') }}
 							</span>
-							<i v-if="scope.row.cbCnt > 1" class="el-icon-caret-bottom ml10" @click.stop="handleClickMore(scope.row, 'end')"></i>
+							<i 
+								v-if="scope.row.cbCnt > 1 && scope.row.runStatus == 1" 
+								class="el-icon-caret-bottom ml10" 
+								@click.stop="handleClickMore(scope.row, 'end')"
+							></i>
 						</div>
 					</template>
 				</el-table-column>
@@ -337,7 +353,7 @@
 			@current-change="handleCurrentChange"
 		></el-pagination>
 		<!-- 更多信息对话框 -->
-		<el-dialog :title="dialog.title" :visible.sync="dialog.show" width="75%">
+		<el-dialog :title="dialog.title" :visible.sync="dialog.show" width="60%">
 			<pop-more-table :visible="dialog.show" :tableData="dialog.tableData" :columns="dialog.tableColumns"></pop-more-table>
 		</el-dialog>
 	</div>
@@ -362,37 +378,50 @@ export default {
 	},
 	computed: {
 		connectStatColor() {
-			return function(state) {
-				return this.connectStatMap[state] ? this.connectStatMap[state].color : 'yellow'
+			return function(row, prop) {
+				if (row.runStatus != 1) return '';
+				let state = row[prop];
+				return this.connectStatMap[state] ? this.connectStatMap[state].color : 'yellow';
 			}
 		},
 		connectStatText() {
-			return function(state) {
+			return function(row, prop) {
+				if (row.runStatus != 1) return '/';
+				let state = row[prop];
 				return this.connectStatMap[state] ? this.connectStatMap[state].label : '异常'
 			}
 		},
 		faultColor() {
-			return function(state) {
+			return function(row, prop) {
+				if (row.runStatus != 1) return '';
+				let state = row[prop];
 				return this.faultMap[state] ? this.faultMap[state].color : ''
 			}
 		},
 		faultText() {
-			return function(state) {
+			return function(row, prop) {
+				if (row.runStatus != 1) return '/';
+				let state = row[prop];
 				return this.faultMap[state] ? this.faultMap[state].label : '/'
 			}
 		},
 		hexPumpStateColor() {
-			return function(state) {
+			return function(row, prop) {
+				if (row.runStatus != 1) return '';
+				let state = row[prop];
 				return this.hexPumpStatMap[state] ? this.hexPumpStatMap[state].color : ''
 			}
 		},
 		hexPumpStateText() {
-			return function(state) {
+			return function(row, prop) {
+				if (row.runStatus != 1) return '/';
+				let state = row[prop];
 				return this.hexPumpStatMap[state] ? this.hexPumpStatMap[state].label : '/'
 			}
 		},
 		calcArgsColor() {
 			return function(scope) {
+				if (scope.row.runStatus != 1) return '';
 				let property = scope.column.property || '';
 				if (property && property.length) {
 					let argsItems = this.argsList.filter(a => a.En === property);
@@ -401,7 +430,9 @@ export default {
 			}
 		},
 		fixedVal() {
-			return function(val) {
+			return function(row, prop) {
+				if (row.runStatus != 1) return '/';
+				let val = row[prop];
 				if (val == 0) return 0;
 				if (!val) return '/';
 				return parseFloat(val).toFixed(1);

+ 355 - 355
src/components/Excel/Export2Excel.js

@@ -1,357 +1,357 @@
-/* eslint-disable */
-require('script-loader!file-saver'); //For saving files
-require('./Blob.js'); //For binary conversion
+/* eslint-disable */
+require('script-loader!file-saver'); //For saving files
+require('./Blob.js'); //For binary conversion
 require('script-loader!xlsx/dist/xlsx.core.min'); //xlsx core
-import XLSXS from 'xlsx-js-style';
-
-function generateArray(table) {
-	var out = [];
-	var rows = table.querySelectorAll('tr');
-	var ranges = [];
-	for (var R = 0; R < rows.length; ++R) {
-		var outRow = [];
-		var row = rows[R];
-		var columns = row.querySelectorAll('td');
-		for (var C = 0; C < columns.length; ++C) {
-			var cell = columns[C];
-			var colspan = cell.getAttribute('colspan');
-			var rowspan = cell.getAttribute('rowspan');
-			var cellValue = cell.innerText;
-			if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
-
-			//Skip ranges
-			ranges.forEach(function(range) {
-				if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e
-					.c) {
-					for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
-				}
-			});
-
-			//Handle Row Span
-			if (rowspan || colspan) {
-				rowspan = rowspan || 1;
-				colspan = colspan || 1;
-				ranges.push({
-					s: {
-						r: R,
-						c: outRow.length
-					},
-					e: {
-						r: R + rowspan - 1,
-						c: outRow.length + colspan - 1
-					}
-				});
-			};
-
-			//Handle Value
-			outRow.push(cellValue !== "" ? cellValue : null);
-
-			//Handle Colspan
-			if (colspan)
-				for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
-		}
-		out.push(outRow);
-	}
-	return [out, ranges];
-};
-
-function datenum(v, date1904) {
-	if (date1904) v += 1462;
-	var epoch = Date.parse(v);
-	return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
-}
-
-function sheet_from_array_of_arrays(data, opts) {
-	var ws = {};
-	var range = {
-		s: {
-			c: 10000000,
-			r: 10000000
-		},
-		e: {
-			c: 0,
-			r: 0
-		}
-	};
-	for (var R = 0; R != data.length; ++R) {
-		for (var C = 0; C != data[R].length; ++C) {
-			if (range.s.r > R) range.s.r = R;
-			if (range.s.c > C) range.s.c = C;
-			if (range.e.r < R) range.e.r = R;
-			if (range.e.c < C) range.e.c = C;
-			var cell = {
-				v: data[R][C]
-			};
-			if (cell.v == null) continue;
-			var cell_ref = XLSX.utils.encode_cell({
-				c: C,
-				r: R
-			});
-
-			if (typeof cell.v === 'number') cell.t = 'n';
-			else if (typeof cell.v === 'boolean') cell.t = 'b';
-			else if (cell.v instanceof Date) {
-				cell.t = 'n';
-				cell.z = XLSX.SSF._table[14];
-				cell.v = datenum(cell.v);
-			} else cell.t = 's';
-
-			ws[cell_ref] = cell;
-		}
-	}
-	if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
-	return ws;
-}
-
-function Workbook() {
-	if (!(this instanceof Workbook)) return new Workbook();
-	this.SheetNames = [];
-	this.Sheets = {};
-}
-
-function s2ab(s) {
-	var buf = new ArrayBuffer(s.length);
-	var view = new Uint8Array(buf);
-	for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
-	return buf;
-}
-
-export function export_table_to_excel(id) {
-	var theTable = document.getElementById(id);
-	var oo = generateArray(theTable);
-	var ranges = oo[1];
-
-	/* original data */
-	var data = oo[0];
-	var ws_name = "SheetJS";
-	// console.log(data);
-
-	var wb = new Workbook(),
-		ws = sheet_from_array_of_arrays(data);
-
-	/* add ranges to worksheet */
-	// ws['!cols'] = ['apple', 'banan'];
-	ws['!merges'] = ranges;
-
-	/* add worksheet to workbook */
-	wb.SheetNames.push(ws_name);
-	wb.Sheets[ws_name] = ws;
-
-	var wbout = XLSX.write(wb, {
-		bookType: 'xlsx',
-		bookSST: false,
-		type: 'binary'
-	});
-
-	saveAs(new Blob([s2ab(wbout)], {
-		type: "application/octet-stream"
-	}), "test.xlsx")
-}
-
-function formatJson(jsonData) {
-	console.log(jsonData)
-}
-
-export function export_json_to_excel(th, jsonData, defaultTitle) {
-
-	var data = jsonData;
-
-	// 添加标题
-	for (var i = 0; i < th.length; i++) {
-		data[i].unshift([th[i]])
-	}
-
-	// 这里是定义sheet的名称 有几个sheet就加几个
-	var ws_name = [];
-	th.forEach(item => {
-		ws_name.push(item);
-	});
-
-	var wb = new Workbook(),
-		ws = [];
-	//数据转换
-	for (var j = 0; j < th.length; j++) {
-		ws.push(sheet_from_array_of_arrays(data[j]))
-	}
-
-	//生成多个sheet
-	for (var k = 0; k < th.length; k++) {
-		wb.SheetNames.push(ws_name[k])
-		wb.Sheets[ws_name[k]] = ws[k]
-	}
-
-	var wbout = XLSX.write(wb, {
-		bookType: 'xlsx',
-		bookSST: false,
-		type: 'binary'
-	});
-
-	var title = defaultTitle || '列表'
-	saveAs(new Blob([s2ab(wbout)], {
-		type: "application/octet-stream"
-	}), title + ".xlsx");
-}
-
-export function export_json_to_excel_merges({
-	multiHeader = [],
-	header,
-	data,
-	filename,
-	merges = [],
-	autoWidth = true,
-	bookType = 'xlsx'
-} = {}) {
-	/* original data */
-	filename = filename || '列表';
-	data = [...data]
-	data.unshift(header);
-	for (let i = multiHeader.length - 1; i > -1; i--) {
-		data.unshift(multiHeader[i])
-	}
-
-	var ws_name = "Sheet1";
-	var wb = new Workbook(),
-		ws = sheet_from_array_of_arrays(data);
-
-	/* add worksheet to workbook */
-	wb.SheetNames.push(ws_name);
-	wb.Sheets[ws_name] = ws;
-
-	// 单元格样式定义
-	/*
-	var dataInfo = wb.Sheets[wb.SheetNames[0]];
-	const tableTitleFont = {
-		font: {
-		  name: "微软雅黑",
-		  sz: 18,
-		},
-		alignment: {
-		  horizontal: "center",
-		  vertical: "center",
-		},
-		bold: true
-	}
-	const tableColumnFont = {
-		font: {
-		  name: "微软雅黑",
-		  sz: 11,
-		},
-		alignment: {
-			horizontal: "center",
-			vertical: "center",
-			wrapText: 1,
-		}
-	}
-	dataInfo["A1"].s = tableTitleFont
-	// dataInfo["A2"].s = tableTitleFont
-	// 从第2行开始
-	let regexColumn = /[A-Z]2$/;
-	for (var b in dataInfo) {
-	  if (regexColumn.test(b)) {
-	    dataInfo[b].s = tableColumnFont;
-	  }
-	}
-	*/
-	//设置单元格格式
-	for (const key in ws) {
-		if (key.indexOf('!') < 0) {
-			if (!ws[key].s) {
-				ws[key].s = {
-					font: {
-						name: '宋体',
-						sz: 10
-					},
-					border: {
-						top: {
-							style: 'thin'
-						},
-						bottom: {
-							style: 'thin'
-						},
-						left: {
-							style: 'thin'
-						},
-						right: {
-							style: 'thin'
-						}
-					},
-					alignment: {
-						horizontal: 'center',
-						vertical: 'center',
-						wrapText: true
-					}
-				}
-			}
-		}
-	}
-
-	// 合并单元格
-	if (merges.length > 0) {
-		if (!ws['!merges']) ws['!merges'] = [];
-		merges.forEach(item => {
-			ws['!merges'].push(XLSX.utils.decode_range(item))
-		})
-	}
-
-	// 自动计算单元格宽度
-	if (autoWidth) {
-		let colWidths = [];
-		// 计算每一列的所有单元格宽度
-		// 先遍历行
-		data.forEach((row) => {
-			// 列序号
-			let index = 0
-			// 遍历列
-			for (const key in row) {
-				if (colWidths[index] == null) colWidths[index] = []
-				switch (typeof row[key]) {
-					case 'string':
-					case 'number':
-					case 'boolean':
-						colWidths[index].push(getCellWidth(row[key]))
-						break
-					case 'object':
-					case 'function':
-						colWidths[index].push(0)
-						break
-				}
-				index++
-			}
-		})
-		ws['!cols'] = [];
-		colWidths.forEach((widths, index) => {
-			// 计算列头的宽度
-			widths.push(getCellWidth(header[index]))
-			// 设置最大值为列宽
-			ws['!cols'].push({
-				wch: Math.max(...widths)
-			})
-		})
-	}
-
-	var wbout = XLSXS.write(wb, {
-		bookType: bookType,
-		bookSST: false,
-		type: 'binary'
-	});
-
-	saveAs(new Blob([s2ab(wbout)], {
-		type: "application/octet-stream"
-	}), `${filename}.${bookType}`);
-}
-
-export function getCellWidth(value) {
-	if (value == null) {
-		return 10
-	} else if (value.toString().charCodeAt(0) > 255) {
-		// 判断是否包含中文
-		let length = value.toString().length * 2
-		if (length > 60) {
-			length = length - 40
-			//这里的宽度可以自己设定,在前面设置wrapText: 1可以在单元格内换行
-		}
-		return length + 2
-	} else {
-		return value.toString().length * 1.2
-	}
+import XLSXS from 'xlsx-js-style';
+
+function generateArray(table) {
+	var out = [];
+	var rows = table.querySelectorAll('tr');
+	var ranges = [];
+	for (var R = 0; R < rows.length; ++R) {
+		var outRow = [];
+		var row = rows[R];
+		var columns = row.querySelectorAll('td');
+		for (var C = 0; C < columns.length; ++C) {
+			var cell = columns[C];
+			var colspan = cell.getAttribute('colspan');
+			var rowspan = cell.getAttribute('rowspan');
+			var cellValue = cell.innerText;
+			if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;
+
+			//Skip ranges
+			ranges.forEach(function(range) {
+				if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e
+					.c) {
+					for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);
+				}
+			});
+
+			//Handle Row Span
+			if (rowspan || colspan) {
+				rowspan = rowspan || 1;
+				colspan = colspan || 1;
+				ranges.push({
+					s: {
+						r: R,
+						c: outRow.length
+					},
+					e: {
+						r: R + rowspan - 1,
+						c: outRow.length + colspan - 1
+					}
+				});
+			};
+
+			//Handle Value
+			outRow.push(cellValue !== "" ? cellValue : null);
+
+			//Handle Colspan
+			if (colspan)
+				for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
+		}
+		out.push(outRow);
+	}
+	return [out, ranges];
+};
+
+function datenum(v, date1904) {
+	if (date1904) v += 1462;
+	var epoch = Date.parse(v);
+	return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
+}
+
+function sheet_from_array_of_arrays(data, opts) {
+	var ws = {};
+	var range = {
+		s: {
+			c: 10000000,
+			r: 10000000
+		},
+		e: {
+			c: 0,
+			r: 0
+		}
+	};
+	for (var R = 0; R != data.length; ++R) {
+		for (var C = 0; C != data[R].length; ++C) {
+			if (range.s.r > R) range.s.r = R;
+			if (range.s.c > C) range.s.c = C;
+			if (range.e.r < R) range.e.r = R;
+			if (range.e.c < C) range.e.c = C;
+			var cell = {
+				v: data[R][C]
+			};
+			if (cell.v == null) continue;
+			var cell_ref = XLSX.utils.encode_cell({
+				c: C,
+				r: R
+			});
+
+			if (typeof cell.v === 'number') cell.t = 'n';
+			else if (typeof cell.v === 'boolean') cell.t = 'b';
+			else if (cell.v instanceof Date) {
+				cell.t = 'n';
+				cell.z = XLSX.SSF._table[14];
+				cell.v = datenum(cell.v);
+			} else cell.t = 's';
+
+			ws[cell_ref] = cell;
+		}
+	}
+	if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
+	return ws;
+}
+
+function Workbook() {
+	if (!(this instanceof Workbook)) return new Workbook();
+	this.SheetNames = [];
+	this.Sheets = {};
+}
+
+function s2ab(s) {
+	var buf = new ArrayBuffer(s.length);
+	var view = new Uint8Array(buf);
+	for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
+	return buf;
+}
+
+export function export_table_to_excel(id) {
+	var theTable = document.getElementById(id);
+	var oo = generateArray(theTable);
+	var ranges = oo[1];
+
+	/* original data */
+	var data = oo[0];
+	var ws_name = "SheetJS";
+	// console.log(data);
+
+	var wb = new Workbook(),
+		ws = sheet_from_array_of_arrays(data);
+
+	/* add ranges to worksheet */
+	// ws['!cols'] = ['apple', 'banan'];
+	ws['!merges'] = ranges;
+
+	/* add worksheet to workbook */
+	wb.SheetNames.push(ws_name);
+	wb.Sheets[ws_name] = ws;
+
+	var wbout = XLSX.write(wb, {
+		bookType: 'xlsx',
+		bookSST: false,
+		type: 'binary'
+	});
+
+	saveAs(new Blob([s2ab(wbout)], {
+		type: "application/octet-stream"
+	}), "test.xlsx")
+}
+
+function formatJson(jsonData) {
+	console.log(jsonData)
+}
+
+export function export_json_to_excel(th, jsonData, defaultTitle) {
+
+	var data = jsonData;
+
+	// 添加标题
+	for (var i = 0; i < th.length; i++) {
+		data[i].unshift([th[i]])
+	}
+
+	// 这里是定义sheet的名称 有几个sheet就加几个
+	var ws_name = [];
+	th.forEach(item => {
+		ws_name.push(item);
+	});
+
+	var wb = new Workbook(),
+		ws = [];
+	//数据转换
+	for (var j = 0; j < th.length; j++) {
+		ws.push(sheet_from_array_of_arrays(data[j]))
+	}
+
+	//生成多个sheet
+	for (var k = 0; k < th.length; k++) {
+		wb.SheetNames.push(ws_name[k])
+		wb.Sheets[ws_name[k]] = ws[k]
+	}
+
+	var wbout = XLSX.write(wb, {
+		bookType: 'xlsx',
+		bookSST: false,
+		type: 'binary'
+	});
+
+	var title = defaultTitle || '列表'
+	saveAs(new Blob([s2ab(wbout)], {
+		type: "application/octet-stream"
+	}), title + ".xlsx");
+}
+
+export function export_json_to_excel_merges({
+	multiHeader = [],
+	header,
+	data,
+	filename,
+	merges = [],
+	autoWidth = true,
+	bookType = 'xlsx'
+} = {}) {
+	/* original data */
+	filename = filename || '列表';
+	data = [...data]
+	data.unshift(header);
+	for (let i = multiHeader.length - 1; i > -1; i--) {
+		data.unshift(multiHeader[i])
+	}
+
+	var ws_name = "Sheet1";
+	var wb = new Workbook(),
+		ws = sheet_from_array_of_arrays(data);
+
+	/* add worksheet to workbook */
+	wb.SheetNames.push(ws_name);
+	wb.Sheets[ws_name] = ws;
+
+	// 单元格样式定义
+	/*
+	var dataInfo = wb.Sheets[wb.SheetNames[0]];
+	const tableTitleFont = {
+		font: {
+		  name: "微软雅黑",
+		  sz: 18,
+		},
+		alignment: {
+		  horizontal: "center",
+		  vertical: "center",
+		},
+		bold: true
+	}
+	const tableColumnFont = {
+		font: {
+		  name: "微软雅黑",
+		  sz: 11,
+		},
+		alignment: {
+			horizontal: "center",
+			vertical: "center",
+			wrapText: 1,
+		}
+	}
+	dataInfo["A1"].s = tableTitleFont
+	// dataInfo["A2"].s = tableTitleFont
+	// 从第2行开始
+	let regexColumn = /[A-Z]2$/;
+	for (var b in dataInfo) {
+	  if (regexColumn.test(b)) {
+	    dataInfo[b].s = tableColumnFont;
+	  }
+	}
+	*/
+	//设置单元格格式
+	for (const key in ws) {
+		if (key.indexOf('!') < 0) {
+			if (!ws[key].s) {
+				ws[key].s = {
+					font: {
+						name: '宋体',
+						sz: 10
+					},
+					border: {
+						top: {
+							style: 'thin'
+						},
+						bottom: {
+							style: 'thin'
+						},
+						left: {
+							style: 'thin'
+						},
+						right: {
+							style: 'thin'
+						}
+					},
+					alignment: {
+						horizontal: 'center',
+						vertical: 'center',
+						wrapText: true
+					}
+				}
+			}
+		}
+	}
+
+	// 合并单元格
+	if (merges.length > 0) {
+		if (!ws['!merges']) ws['!merges'] = [];
+		merges.forEach(item => {
+			ws['!merges'].push(XLSX.utils.decode_range(item))
+		})
+	}
+
+	// 自动计算单元格宽度
+	if (autoWidth) {
+		let colWidths = [];
+		// 计算每一列的所有单元格宽度
+		// 先遍历行
+		data.forEach((row) => {
+			// 列序号
+			let index = 0
+			// 遍历列
+			for (const key in row) {
+				if (colWidths[index] == null) colWidths[index] = []
+				switch (typeof row[key]) {
+					case 'string':
+					case 'number':
+					case 'boolean':
+						colWidths[index].push(getCellWidth(row[key]))
+						break
+					case 'object':
+					case 'function':
+						colWidths[index].push(0)
+						break
+				}
+				index++
+			}
+		})
+		ws['!cols'] = [];
+		colWidths.forEach((widths, index) => {
+			// 计算列头的宽度
+			widths.push(getCellWidth(header[index]))
+			// 设置最大值为列宽
+			ws['!cols'].push({
+				wch: Math.max(...widths)
+			})
+		})
+	}
+
+	var wbout = XLSXS.write(wb, {
+		bookType: bookType,
+		bookSST: false,
+		type: 'binary'
+	});
+
+	saveAs(new Blob([s2ab(wbout)], {
+		type: "application/octet-stream"
+	}), `${filename}.${bookType}`);
+}
+
+export function getCellWidth(value) {
+	if (value == null) {
+		return 10
+	} else if (value.toString().charCodeAt(0) > 255) {
+		// 判断是否包含中文
+		let length = value.toString().length * 2
+		if (length > 60) {
+			length = length - 40
+			//这里的宽度可以自己设定,在前面设置wrapText: 1可以在单元格内换行
+		}
+		return length + 2
+	} else {
+		return value.toString().length * 1.2
+	}
 }

+ 16 - 1
src/components/PopMoreTable.vue

@@ -8,7 +8,12 @@
 				:label="col.label" 
 				:width="col.width ? col.width : ''" 
 				align="center"
-			></el-table-column>
+			>
+				<template slot-scope="scope">
+					<span v-if="col.prop.indexOf('_order') < 0">{{ fixedVal(scope.row, col.prop) }}</span>
+					<span v-else>{{ scope.row[col.prop] }}</span>
+				</template>
+			</el-table-column>
 		</el-table>
 	</div>
 </template>
@@ -29,6 +34,16 @@ export default {
 			type: Array,
 			default: () => []
 		}
+	},
+	computed: {
+		fixedVal() {
+			return function(row, prop) {
+				let val = row[prop];
+				if (val == 0) return 0;
+				if (!val) return '/';
+				return parseFloat(val).toFixed(1);
+			};
+		}
 	}
 };
 </script>

+ 36 - 24
src/js/common.js

@@ -205,31 +205,43 @@ export const endCols = [{
 	{
 		prop: 'end_exception_num',
 		label: '通讯异常数量'
-	},
-	{
-		prop: 'end_min_temp',
-		label: '最低室内温度(℃)'
-	},
-	{
-		prop: 'end_min_humidity',
-		label: '最低室内湿度(%)'
-	},
-	{
-		prop: 'end_min_dew_point',
-		label: '最低室内露点(℃)'
-	},
-	{
-		prop: 'end_max_temp',
-		label: '最高室内温度(℃)'
-	},
-	{
-		prop: 'end_max_humidity',
-		label: '最高室内湿度(%)'
-	},
-	{
-		prop: 'end_max_dew_point',
-		label: '最高室内露点(℃)'
+	},
+	{
+		prop: 'end_min_temp',
+		label: '室内温度(℃)'
+	},
+	{
+		prop: 'end_min_humidity',
+		label: '室内湿度(%)'
+	},
+	{
+		prop: 'end_min_dew_point',
+		label: '室内露点(℃)'
 	}
+	// {
+	// 	prop: 'end_min_temp',
+	// 	label: '最低室内温度(℃)'
+	// },
+	// {
+	// 	prop: 'end_min_humidity',
+	// 	label: '最低室内湿度(%)'
+	// },
+	// {
+	// 	prop: 'end_min_dew_point',
+	// 	label: '最低室内露点(℃)'
+	// },
+	// {
+	// 	prop: 'end_max_temp',
+	// 	label: '最高室内温度(℃)'
+	// },
+	// {
+	// 	prop: 'end_max_humidity',
+	// 	label: '最高室内湿度(%)'
+	// },
+	// {
+	// 	prop: 'end_max_dew_point',
+	// 	label: '最高室内露点(℃)'
+	// }
 ]
 
 /**

+ 93 - 93
src/js/scrollbar.js

@@ -1,94 +1,94 @@
-//自定义滚动条
-import PerfectScrollbar from 'perfect-scrollbar';
-//对应的css
-import "perfect-scrollbar/css/perfect-scrollbar.css";
-
-const updateScrollBar = (el) => {
-	const railX = el.querySelector(".ps__rail-x");
-	const _tbody = el;
-	// 如果table内部还有滚动条的话需要加上_tbody.scrollTop
-	const _top = window.innerHeight - _tbody.getBoundingClientRect().top - railX.clientHeight;
-	railX.style.top = `${_top}px`;
-	railX.style.opacity = "1";
-	railX.style.display = "block";
-}
-
-const el_scrollBar = (el) => {
-	if (el._ps_ instanceof PerfectScrollbar) {
-		el._ps_.update();
-	} else {
-		el._ps_ = new PerfectScrollbar(el, {
-			suppressScrollX: false,
-			suppressScrollY: true //y方向禁止
-		});
-	}
-};
-
-let isScrolling = false;
-let _scrollHander = null;
-let _resizeHander = null;
-
-const directive = {
-	inserted(el) {
-		el = el.querySelector(".el-table__body-wrapper");
-		if (!el) {
-			return console.warn("未发现className为el-table__body-wrapper的dom");
-		}
-		const rules = ["fixed", "absolute", "relative"];
-		if (!rules.includes(window.getComputedStyle(el, null).position)) {
-			console.error(`perfect-scrollbar所在的容器的position属性必须是以下之一:${rules.join("、")}`)
-		}
-		el_scrollBar(el);
-		updateScrollBar(el);
-
-		//注册scroll和resize事件
-		_scrollHander = () => {
-			if (!isScrolling) {
-				window.requestAnimationFrame(() => {
-					updateScrollBar(el);
-					isScrolling = false;
-				});
-			}
-			isScrolling = true;
-		};
-
-		_resizeHander = () => {
-			updateScrollBar(el)
-		}
-
-		document.addEventListener("scroll", _scrollHander)
-		window.addEventListener("resize", _resizeHander)
-	},
-	componentUpdated(el, binding, vnode) {
-		const {
-			expression
-		} = binding;
-
-		el = el.querySelector(".el-table__body-wrapper");
-		if (!el) {
-			return console.warn("未发现className为el-table__body-wrapper的dom");
-		}
-
-		const handler = () => vnode.context[expression].apply();
-
-		vnode.context.$nextTick(
-			() => {
-				try {
-					el_scrollBar(el);
-					updateScrollBar(el);
-					if (expression) {
-						handler()
-					}
-				} catch (error) {
-					console.error(error);
-				}
-			}
-		)
-	},
-	unbind() {
-		document.removeEventListener("scroll", _scrollHander)
-		window.removeEventListener("resize", _resizeHander)
-	}
-}
-
+//自定义滚动条
+import PerfectScrollbar from 'perfect-scrollbar';
+//对应的css
+import "perfect-scrollbar/css/perfect-scrollbar.css";
+
+const updateScrollBar = (el) => {
+	const railX = el.querySelector(".ps__rail-x");
+	const _tbody = el;
+	// 如果table内部还有滚动条的话需要加上_tbody.scrollTop
+	const _top = window.innerHeight - _tbody.getBoundingClientRect().top - railX.clientHeight;
+	railX.style.top = `${_top}px`;
+	railX.style.opacity = "1";
+	railX.style.display = "block";
+}
+
+const el_scrollBar = (el) => {
+	if (el._ps_ instanceof PerfectScrollbar) {
+		el._ps_.update();
+	} else {
+		el._ps_ = new PerfectScrollbar(el, {
+			suppressScrollX: false,
+			suppressScrollY: true //y方向禁止
+		});
+	}
+};
+
+let isScrolling = false;
+let _scrollHander = null;
+let _resizeHander = null;
+
+const directive = {
+	inserted(el) {
+		el = el.querySelector(".el-table__body-wrapper");
+		if (!el) {
+			return console.warn("未发现className为el-table__body-wrapper的dom");
+		}
+		const rules = ["fixed", "absolute", "relative"];
+		if (!rules.includes(window.getComputedStyle(el, null).position)) {
+			console.error(`perfect-scrollbar所在的容器的position属性必须是以下之一:${rules.join("、")}`)
+		}
+		el_scrollBar(el);
+		updateScrollBar(el);
+
+		//注册scroll和resize事件
+		_scrollHander = () => {
+			if (!isScrolling) {
+				window.requestAnimationFrame(() => {
+					updateScrollBar(el);
+					isScrolling = false;
+				});
+			}
+			isScrolling = true;
+		};
+
+		_resizeHander = () => {
+			updateScrollBar(el)
+		}
+
+		document.addEventListener("scroll", _scrollHander)
+		window.addEventListener("resize", _resizeHander)
+	},
+	componentUpdated(el, binding, vnode) {
+		const {
+			expression
+		} = binding;
+
+		el = el.querySelector(".el-table__body-wrapper");
+		if (!el) {
+			return console.warn("未发现className为el-table__body-wrapper的dom");
+		}
+
+		const handler = () => vnode.context[expression].apply();
+
+		vnode.context.$nextTick(
+			() => {
+				try {
+					el_scrollBar(el);
+					updateScrollBar(el);
+					if (expression) {
+						handler()
+					}
+				} catch (error) {
+					console.error(error);
+				}
+			}
+		)
+	},
+	unbind() {
+		document.removeEventListener("scroll", _scrollHander)
+		window.removeEventListener("resize", _resizeHander)
+	}
+}
+
 export default directive;