原生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>

效果图:

相关推荐
2601_968900777 分钟前
玻璃深加工的工艺窗口:4 道工序的温度与时间参数边界
android·java·javascript
志尊宝7 分钟前
AI原生前端开发(037):AI辅助的Vue 3开发最佳实践
前端·vue.js·ai-native
中科三方12 分钟前
AI时代新攻击面:悬空DNS记录正在成为黑客的低成本入侵入口
服务器·前端·人工智能
程序员大阳15 分钟前
副队长JavaScript教程(53)-DOM操作元素的属性
javascript·dom·属性·setattribute·getattribuite
超级架构师34 分钟前
让 COBOL 长出 AI 大脑:原生 Agent 核心框架 praxo-core 深度剖析
c语言·开发语言·c++·人工智能·python·架构·ai编程
努力变的更好38 分钟前
H5与小程序之间的回调
前端·小程序·apache
Non-existent98739 分钟前
在 WPS/Excel 里做地理数据处理:功能市场 + 奥维 / Google Earth / QGIS 三种跳转实战
开发语言·javascript·ecmascript
zhougl99644 分钟前
什么是 URL
javascript
汤米粥1 小时前
目前流行的前端 CSS 框架
前端·css·bootstrap·ant design·‌tailwind css·bulma
砚凝霜1 小时前
CTF Misc 签到 GXUST·CTF:查看源码 + HTML 注释 + Base64 解码(附 Base64 原理)
前端·html