如何将嵌套JSON文件提取为HTML表格(Firebase数据场景)
问题描述
我正在做一个项目,需要评审从Firebase数据库导出的JSON格式参与者响应数据。已经能用下面的代码读取JSON并输出到控制台,还能展开查看对象:
// Output json file to console.. fetch("dmao.json") .then((response) => response.json()) .then((json) => { console.log(json.drawingLog); }) .catch((error) => { console.error("Error fetching or parsing JSON:", error); });
但编写JavaScript将对象提取为HTML表格时遇到了问题——代码原本预期json.drawingLog.A是数组,可实际这个结构是带唯一ID的对象(它的子对象是键值对格式)。我的目标是生成一个HTML表格,把每个键作为列标题,每条JSON数据作为新行。
附JSON文件中前两个对象的示例:
"drawingLog": { "A": { "1648717382638": { "canvasHeight": 1000, "canvasWidth": 1000, "colour": { "_array": [ 0.27058823529411763, 0.44313725490196076, 0.7215686274509804, 1 ], "levels": [ 69, 113, 184, 255 ], "maxes": { "hsb": [ 360, 100, 100, 1 ], "hsl": [ 360, 100, 100, 1 ], "rgb": [ 255, 255, 255, 255 ] }, "mode": "rgb" }, "drawingVertices": [ [ 1000, 500 ], [ 980, 629 ], [ 646, 593 ], [ 828, 838 ], [ 712, 897 ], [ 583, 917 ], [ 377, 670 ], [ 338, 838 ], [ 245, 745 ], [ 186, 629 ], [ 0, 457 ], [ 186, 371 ], [ 245, 255 ], [ 338, 162 ], [ 454, 103 ], [ 583, 83 ], [ 712, 103 ], [ 828, 162 ], [ 920, 255 ], [ 980, 371 ] ] }, "1648717474706": { "canvasHeight": 1000, "canvasWidth": 1000, "colour": { "_array": [ 0.8352941176470589, 0.3411764705882353, 0.6274509803921569, 1 ], "levels": [ 213, 87, 160, 255 ], "maxes": { "hsb": [ 360, 100, 100, 1 ], "hsl": [ 360, 100, 100, 1 ], "rgb": [ 255, 255, 255, 255 ] }, "mode": "rgb" }, "drawingVertices": [ [ 933, 500 ], [ 67, 1000 ], [ 67, 0 ] ] } } }
以下是我编写的仅针对'A'项生成HTML表格的代码:
// Output json.drawingLog.A to an HTML table fetch("dmao.json") .then((response) => response.json()) .then((json) => { const table = document.getElementById("drawingLogTable"); const headerRow = table.tHead.rows[0]; const tbody = table.tBodies[0]; // Add table headers if (Array.isArray(json.drawingLog.A) && json.drawingLog.A.length > 0) { for (const key in json.drawingLog.A[0]) { const th = document.createElement("th"); th.textContent = key; headerRow.appendChild(th); } // Add table rows json.drawingLog.A.forEach((item) => { const tr = document.createElement("tr"); for (const key in item) { const td = document.createElement("td"); td.textContent = item[key]; tr.appendChild(td); } tbody.appendChild(tr); }); } else { const tr = document.createElement("tr"); const td = document.createElement("td"); td.textContent = "No data available"; tr.appendChild(td); tbody.appendChild(tr); } }) .catch((error) => { console.error("Error fetching or parsing JSON:", error); });
解决办法
因为json.drawingLog.A是带唯一ID的对象而非数组,得先把它的子对象转成数组再处理。另外,像colour这种嵌套对象、drawingVertices这种数组,直接显示会变成[object Object]或者挤在一起的字符串,需要格式化提升可读性。
修改后的代码如下:
fetch("dmao.json") .then((response) => response.json()) .then((json) => { const table = document.getElementById("drawingLogTable"); const headerRow = table.tHead.rows[0]; const tbody = table.tBodies[0]; // 把drawingLog.A里的所有子对象提取成数组 const drawingEntries = Object.values(json.drawingLog.A); if (drawingEntries.length > 0) { // 拿第一个数据的键作为表头 const headers = Object.keys(drawingEntries[0]); headers.forEach(key => { const th = document.createElement("th"); th.textContent = key; headerRow.appendChild(th); }); // 循环生成每一行数据 drawingEntries.forEach(item => { const tr = document.createElement("tr"); headers.forEach(key => { const td = document.createElement("td"); const value = item[key]; // 嵌套对象和数组转成带缩进的JSON字符串,方便阅读 if (typeof value === 'object' && value !== null) { td.textContent = JSON.stringify(value, null, 2); td.style.whiteSpace = 'pre-wrap'; td.style.fontFamily = 'monospace'; } else { td.textContent = value; } tr.appendChild(td); }); tbody.appendChild(tr); }); } else { const tr = document.createElement("tr"); const td = document.createElement("td"); td.colSpan = headerRow.cells.length || 1; td.textContent = "无可用数据"; tr.appendChild(td); tbody.appendChild(tr); } }) .catch((error) => { console.error("获取或解析JSON出错:", error); });
核心改动:
- 用
Object.values(json.drawingLog.A)将对象转换为数组,这样就能用数组遍历方法处理每条数据。 - 对嵌套对象和数组使用
JSON.stringify格式化,添加缩进并设置单元格样式让换行生效,提升内容可读性。 - 无数据时设置
colSpan,避免表格布局错乱。
内容的提问来源于stack exchange,提问作者Bo55Xtreme
相关产品推荐
相关产品推荐

