原生JavaScript,根据后端返回JSON动态【动态列头、动态数据】生成表格数据

前期准备: JQ下载地址: https://jquery.com/

html 复制代码
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>JSON动态生成表格数据,动态列头拼接</title>
		<style>
			table {
				width: 800px;
				text-align: center;
				border-collapse: collapse;
			}
			
			thead tr {
				height: 40px;
				background-color: rgb(161, 143, 143);
			}
			
			td,
			th {
				padding: 5px;
				border: 1px solid rgb(80, 73, 73);
			}
		</style>
	</head>
	<body>
		<div id="tableContainer"></div>
	</body>
	<!-- 下载地址: https://jquery.com/, 引入Jqurey,需要根据自己的JQ文件修改路径并引入 -->
	<script src="./jquery-3.7.1.min.js"></script>
	<script>
		function run() {
			var list = [{
					line: "line1",
					station: "stationA",
					device: "设备1",
					machine: "line1机台数据"
				}, {
					line: "line1",
					station: "stationB",
					device: "设备B",
					machine: "line1机台数据"
				},
				{
					line: "line1",
					station: "stationA",
					device: "设备2",
					machine: "机台数据"
				}, {
					line: "line1",
					station: "stationC",
					device: "设备C",
					machine: "line1机台数据"
				}, {
					line: "line2",
					station: "stationC",
					device: "设备C",
					machine: "line2机台数据"
				},
				{
					line: "line2",
					station: "stationA",
					device: "设备1",
					machine: "line2机台数据"
				},
				{
					line: "line2",
					station: "stationA",
					device: "设备2",
					machine: ""
				}, {
					line: "line3",
					station: "stationC",
					device: "设备C",
					machine: "line3机台数据"
				}
			]
			let column = [{
					label: '',
					key: 'station'
				},
				{
					label: '设备',
					key: 'device'
				}
			]
			let newLine = []
			let newStation = []
			for (var i = 0; i < list.length; i++) {
				let item = list[i]
				// 线别
				let lines = findArrIsNow(newLine, item.line)
				if (!lines) {
					newLine.push(item.line)
				}
				// station
				let stations = findArrIsNow(newStation, item.station)
				if (!stations) {
					newStation.push(item.station)
				}
			}
			// 组装头部
			for (var i = 0; i < newLine.length; i++) {
				let line = newLine[i]
				column.push({
					label: line,
					key: line
				})
			}
			// 组装数据
			let dataList = []
			for (var i = 0; i < newStation.length; i++) {
				let col = newStation[i]
				for (var j = 0; j < list.length; j++) {
					let lsItem = list[j]
					// 匹配对应的站点
					if (col === lsItem['station']) {
						// 查找设备名是否存在
						let deviceFinds = findObjectArrIsNow(dataList, 'device', lsItem['device'])

						// 不存在就添加
						if (!deviceFinds) {
							let obj = {
								station: col
							}
							obj['device'] = lsItem['device']
							obj[lsItem['line']] = lsItem['machine']
							dataList.push(obj)
						} else {
							deviceFinds[lsItem['line']] = lsItem['machine']
						}
					}
				}
			}
			document.getElementById('tableContainer').innerHTML = createTable(dataList, column, newLine);
			setTimeout(() => {
				mergeCell('myTable', [0])
			}, 500)
		}
		// 表格拼接
		function createTable(dataList, columnList, lineList) {
			var table = '<table id="myTable" border="1">';
			// 组装头部
			let headrs = '<tr>'
			for (var i = 0; i < columnList.length; i++) {
				let colTitles = columnList[i]
				headrs += '<th>' + colTitles.label + '</th>'
			}
			headrs += '</tr>';
			// 组装body
			let bodys = ''
			for (var i = 0; i < dataList.length; i++) {
				bodys += '<tr>';
				for (let tl of columnList) {
					// 第一列相同站点需要合并,特殊标记处理
					if (tl.key === 'station') {
						if (!dataList[i][tl.key]) {
							bodys += '<td rowspan=""></td>';
						} else {
							bodys += '<td rowspan="">' + dataList[i][tl.key] + '</td>';
						}
					} else {
						if (!dataList[i][tl.key]) {
							bodys += '<td></td>';
						} else {
							bodys += '<td>' + dataList[i][tl.key] + '</td>';
						}
					}
				}
				bodys += '</tr>';
			}
			table += headrs + bodys
			table += '</table>';
			return table;
		}

		// 查找数组对象是否存在 [{...}]
		function findObjectArrIsNow(list, key, value) {
			return list.find((fid) => {
				return fid[key] === value
			})
		}

		// 查找数组里是否存在 ['']
		function findArrIsNow(list, value) {
			return list.find((fid) => {
				return fid === value
			})
		}

		/**
		 * @param tableId  table的id
		 * @param cols     需要合并的列
		 */
		function mergeCell(tableId, cols) {
			var table = document.getElementById(tableId);
			var table_rows = table.rows;
			cols.forEach(v => { // 需要合并的列的数组
				for (let i = 0; i < table_rows.length - 1; i++) { // 循环table每一行
					// row
					let now_row = table_rows[i];
					let next_row = table_rows[i + 1];
					// col
					let now_col = now_row.cells[v];
					let next_col = next_row.cells[v];
					if (now_col.innerHTML == next_col.innerHTML) { // 判断内容是否相同
						$(next_col).addClass('remove'); // 标记为需要删除的列dom
						setParentSpan(table, i, v);
					}
				}
			})
			$(".remove").remove();
		}

		/**
		 * @param table  table的dom
		 * @param row    内容相同行
		 * @param col    内容相同列
		 */
		function setParentSpan(table, row, col) {
			var col_item = table.rows[row].cells[col];
			if ($(col_item).hasClass('remove')) {
				setParentSpan(table, --row, col)
			} else {
				col_item.rowSpan += 1;
			}
		}

		// 运行
		run()
	</script>
</html>

效果图:

相关推荐
黑客飓风17 分钟前
JavaScript 性能优化实战大纲
前端·javascript·性能优化
啊阿狸不会拉杆35 分钟前
《算法导论》第 32 章 - 字符串匹配
开发语言·c++·算法
emojiwoo2 小时前
【前端基础知识系列六】React 项目基本框架及常见文件夹作用总结(图文版)
前端·react.js·前端框架
武当豆豆2 小时前
C++编程学习(第25天)
开发语言·c++·学习
张人玉2 小时前
XML 序列化与操作详解笔记
xml·前端·笔记
杨荧2 小时前
基于Python的宠物服务管理系统 Python+Django+Vue.js
大数据·前端·vue.js·爬虫·python·信息可视化
YeeWang3 小时前
🎉 Eficy 让你的 Cherry Studio 直接生成可预览的 React 页面
前端·javascript
gnip3 小时前
Jenkins部署前端项目实战方案
前端·javascript·架构
Orange3015113 小时前
《深入源码理解webpack构建流程》
前端·javascript·webpack·typescript·node.js·es6
lovepenny4 小时前
Failed to resolve entry for package "js-demo-tools". The package may have ......
前端·npm