如何使用 Javascript 从带有嵌套列表的 JSON 动态创建表?

How to dynamically create a table from a JSON with nested lists using Javascript?

提问人:Joss 提问时间:4/12/2021 最后编辑:ℛɑƒæĿᴿᴹᴿJoss 更新时间:7/9/2022 访问量:1315

问:

我正在尝试从 JSON 文件创建一个 HTML 表,该表的值可以包含嵌套列表。

例:

{
     "entry 1":[
         ["text1", "text2", "text3"],
         ["text4", "text5", "text6"],
         ["text7", "text8", "text9"]
    ],
    "entry 2": "N/A",
    "entry 3": [
         ["text1", "text2", "text3"],
         ["text4", "text5", "text6"]
    ],
    "entry 4": [
         ["text1", "text2"],
         ["text3", "text4"]
    ]
}

我的目标是为两列创建一个具有预定义标题的 HTML 表:

  • header_title_1
  • header_title_2

这永远不会改变,表格应该如下所示:

table_example

感谢您的帮助!

JavaScript HTML JSON html-table 嵌套列表

评论

1赞 4/12/2021
Stack overflow 不是免费的代码编写服务;到目前为止,你尝试过什么吗?
0赞 Wazeed 4/12/2021
Object.keys(obj)给出了可以迭代以获取所需表格 HTML 的键

答:

2赞 a.mola 4/12/2021 #1

在对象上使用迭代器来获取 .我为每个属性创建了一行,然后为键和值创建了一个单元格。然后,如果值不是数组,就像键一样,我们将其设置为数组以遍历元素。for...inkeyentry2

为数组中的每个元素创建一个新行,并为数组中的项目创建一个新单元格。如果它是一个数组,则该值将转换为以逗号“”分隔的字符串,或者按原样设置。

然后,我们将元素附加到表的正文中。

const tbody = document.getElementById('table').tBodies[0];
const obj = {"entry 1":[["text1","text2","text3"],["text4","text5","text6"],["text7","text8","text9"]],"entry 2":"N/A","entry 3":[["text1","text2","text3"],["text4","text5","text6"]],"entry 4":[["text1","text2"],["text3","text4"]]};

function createTable(obj) {
  tbody.innerHTML = ''; // To reset the table
  
  for (const key in obj) {
    if (!obj.hasOwnProperty(key)) continue;
    const value = Array.isArray(obj[key]) ? obj[key] : [obj[key]];
    const row = document.createElement('tr');
    const key_cell = Object.assign(document.createElement('td'), {
      innerText: key
    });
    const value_column = Object.assign(document.createElement('td'), {
      innerText: value.splice(0, 1)[0]
    });

    row.append(...[key_cell, value_column]);
    tbody.append(row);

    value.forEach(val => {
      const inner_row = document.createElement('tr');
      const empty_key_cell = document.createElement('td');
      const value_cell = Object.assign(document.createElement('td'), {
        innerText: val
      });
      inner_row.append(...[empty_key_cell, value_cell]);
      tbody.append(inner_row);
    });
  }
}

createTable(obj);
<table id="table" border="1" width="100%">
  <thead>
    <td>header_title_1</td>
    <td>header_title_2</td>
  </thead>
  <tbody></tbody>
</table>

评论

0赞 Joss 4/12/2021
非常感谢,它工作得很好!如果我想在每行之间添加一条水平线,这应该添加到JS脚本还是html中?
0赞 a.mola 4/12/2021
如果你的意思是它在你链接的图片中的样子,我已经为此编辑了我的代码......
0赞 a.mola 4/12/2021
你是这个意思吗?
0赞 Joss 4/12/2021
最后一个问题,我的页面以过滤器按钮开头,用于在创建表之前选择要加载的 JSON 文件,您的脚本是否应该在某处包含“id = 表”以使其动态?
0赞 Joss 4/12/2021
第一个表加载得很好,但是当我尝试按 btton 加载另一个 JSON 时,我在控制台中收到以下错误消息:“由于目标被视为被动,无法在被动事件侦听器中阻止默认”
1赞 Carsten Massmann 4/12/2021 #2

或者,在很短的时间内,您可以执行以下操作:

const obj=
{"entry 1":[["text1","text2","text3"],["text4","text5","text6"],["text7","text8","text9"]],
 "entry 2":"N/A",
 "entry 3":[["text1","text2","text3"],["text4","text5","text6"]],
 "entry 4":[["text1","text2"],["text3","text4"]]};
 
document.querySelector("#table tbody").innerHTML=
Object.entries(obj).map(([k,v])=>
   "<tr><td>"+k+"</td><td>"
  +(Array.isArray(v)?v:[[v]]).join("<hr>")
  +"</td></tr>").join("\n")
td>hr {margin:0px}
td {vertical-align:top}
<table id="table" border="1" width="100%">
  <thead>
    <th>header_title_1</th>
    <th>header_title_2</th>
  </thead>
  <tbody></tbody>
</table>