【问题标题】:Generate HTML table from 2D JavaScript array从二维 JavaScript 数组生成 HTML 表格
【发布时间】:2013-02-16 08:42:28
【问题描述】:

在 JavaScript 中,是否可以从 2D 数组生成 HTML 表格?编写 HTML 表格的语法往往非常冗长,所以我想从 2D JavaScript 数组生成 HTML 表格,如图所示:

[
  ["row 1, cell 1", "row 1, cell 2"], 
  ["row 2, cell 1", "row 2, cell 2"]
]

会变成:

<table border="1">
  <tr>
    <td>row 1, cell 1</td>
    <td>row 1, cell 2</td>
  </tr>
  <tr>
    <td>row 2, cell 1</td>
    <td>row 2, cell 2</td>
  </tr>
</table>

所以我正在尝试编写一个 JavaScript 函数,该函数将从 2D JavaScript 数组中返回一个表,如下所示:

function getTable(array){
  // take a 2D JavaScript string array as input, and return an HTML table.
}

【问题讨论】:

  • 我很惊讶以前没有人问过这个问题。我认为这将是大多数 Web 开发人员需要的东西。
  • @VoronoiPotato 我发布了我自己问题的答案,以便该答案对其他 Web 开发人员有用 - 这就是 Stack Overflow 的用途。在 Stack Exchange Network 上发布问题时,甚至会显示“回答您自己的问题”按钮。
  • @VoronoiPotato,这里欢迎自我回答问题 - 您可能对问题本身有疑问,但即时回答问题的能力不应该是其中之一。 blog.stackoverflow.com/2012/05/encyclopedia-stack-exchange

标签: javascript html-table


【解决方案1】:

这是一个使用 dom 代替字符串连接的函数。

function createTable(tableData) {
  var table = document.createElement('table');
  var tableBody = document.createElement('tbody');

  tableData.forEach(function(rowData) {
    var row = document.createElement('tr');

    rowData.forEach(function(cellData) {
      var cell = document.createElement('td');
      cell.appendChild(document.createTextNode(cellData));
      row.appendChild(cell);
    });

    tableBody.appendChild(row);
  });

  table.appendChild(tableBody);
  document.body.appendChild(table);
}

createTable([["row 1, cell 1", "row 1, cell 2"], ["row 2, cell 1", "row 2, cell 2"]]);

【讨论】:

  • 这行得通,但它比我找到的其他答案更冗长。
  • dom 比较冗长,但比 innerHTML 更安全。
  • 您的解决方案似乎生成了一段文本而不是生成表格:jsfiddle.net/jCVmZ
  • 安德森你的答案是一个字符串生成器,请放过我们。他的回答是完全正确的,不会产生段落。它完全按照描述制作了一张表格。 (如果您不相信,请右键单击并检查元素)。这比您的答案或丹尼尔的答案要正确得多。您应该使用 DOM,而不是一些 html 字符串注入。
  • 为什么这个函数直接注入document.body,而不是按照OP的要求返回DOM对象?在哪里注入表不应该是createTable 的责任,除非您还提供一个入口点作为参数。
【解决方案2】:

使用双 for 循环很容易做到这一点。

function makeTableHTML(myArray) {
    var result = "<table border=1>";
    for(var i=0; i<myArray.length; i++) {
        result += "<tr>";
        for(var j=0; j<myArray[i].length; j++){
            result += "<td>"+myArray[i][j]+"</td>";
        }
        result += "</tr>";
    }
    result += "</table>";

    return result;
}

【讨论】:

  • 这是最好的答案。
  • 这不能很好地处理包含&lt;&amp; 的字符串。
  • 使用 DOM,卢克!
【解决方案3】:

另一个innerHTML-less 版本。

function makeTable(array) {
    var table = document.createElement('table');
    for (var i = 0; i < array.length; i++) {
        var row = document.createElement('tr');
        for (var j = 0; j < array[i].length; j++) {
            var cell = document.createElement('td');
            cell.textContent = array[i][j];
            row.appendChild(cell);
        }
        table.appendChild(row);
    }
    return table;
}

【讨论】:

  • 有没有比嵌套循环更好的方法?
【解决方案4】:

丹尼尔威廉姆斯答案的 es6 版本:

  function get_table(data) {
    let result = ['<table border=1>'];
    for(let row of data) {
        result.push('<tr>');
        for(let cell of row){
            result.push(`<td>${cell}</td>`);
        }
        result.push('</tr>');
    }
    result.push('</table>');
    return result.join('\n');
  }

【讨论】:

    【解决方案5】:

    这是使用template literals 的版本。它maps 在数据上创建从模板文字构建的新字符串数组,然后使用insertAdjacentHTML 将它们添加到文档中:

    let data = [
      ['Title', 'Artist', 'Duration', 'Created'],
      ['hello', 'me', '2', '2019'],
      ['ola', 'me', '3', '2018'],
      ['Bob', 'them', '4.3', '2006']
    ];
    
    function getCells(data, type) {
      return data.map(cell => `<${type}>${cell}</${type}>`).join('');
    }
    
    function createBody(data) {
      return data.map(row => `<tr>${getCells(row, 'td')}</tr>`).join('');
    }
    
    function createTable(data) {
    
      // Destructure the headings (first row) from
      // all the rows
      const [headings, ...rows] = data;
    
      // Return some HTML that uses `getCells` to create
      // some headings, but also to create the rows
      // in the tbody.
      return `
        <table>
          <thead>${getCells(headings, 'th')}</thead>
          <tbody>${createBody(rows)}</tbody>
        </table>
      `;
    }
    
    // Bang it altogether
    document.body.insertAdjacentHTML('beforeend', createTable(data));
    table { border-collapse: collapse; }
    tr { border: 1px solid #dfdfdf; }
    th, td { padding: 2px 5px 2px 5px;}

    【讨论】:

    • 我喜欢这里的模板方法,因为它适用于许多其他场景。钻研你的答案有点像剥洋葱。 :)
    • 谢谢。我认为很多问题都来自试图同时做很多事情的代码。分离关注点意味着您实际上一次只需要考虑一件事,并且意味着您可以更好地测试它。
    【解决方案6】:

    the fiddle demo to create a table from an array

    function createTable(tableData) {
      var table = document.createElement('table');
      var row = {};
      var cell = {};
    
      tableData.forEach(function(rowData) {
        row = table.insertRow(-1); // [-1] for last position in Safari
        rowData.forEach(function(cellData) {
          cell = row.insertCell();
          cell.textContent = cellData;
        });
      });
      document.body.appendChild(table);
    }
    

    你可以这样使用它

    var tableData = [["r1c1", "r1c2"], ["r2c1", "r2c2"], ["r3c1", "r3c2"]];
    createTable(tableData);
    

    【讨论】:

      【解决方案7】:

      基于公认的解决方案:

      function createTable (tableData) {
        const table = document.createElement('table').appendChild(
          tableData.reduce((tbody, rowData) => {
            tbody.appendChild(
              rowData.reduce((tr, cellData) => {
                tr.appendChild(
                  document
                    .createElement('td')
                    .appendChild(document.createTextNode(cellData))
                )
                return tr
              }, document.createElement('tr'))
            )
            return tbody
          }, document.createElement('tbody'))
        )
      
        document.body.appendChild(table)
      }
      
      createTable([
        ['row 1, cell 1', 'row 1, cell 2'],
        ['row 2, cell 1', 'row 2, cell 2']
      ])
      

      通过简单的更改,可以将表格作为 HTML 元素返回。

      【讨论】:

        【解决方案8】:

        使用 es6 reduce 的单行代码

        function makeTableHTML(ar) {
          return `<table>${ar.reduce((c, o) => c += `<tr>${o.reduce((c, d) => (c += `<td>${d}</td>`), '')}</tr>`, '')}</table>`
        }
        

        【讨论】:

        • 完美工作,但是如果我想在某些条件下在 ${d} 中添加一个类..我的意思是我如何使用 if 条件TD
        【解决方案9】:

        生成表格并支持 HTML 作为输入。

        灵感来自@spiny-norman https://stackoverflow.com/a/15164796/2326672

        还有@bornd https://stackoverflow.com/a/6234804/2326672

        function escapeHtml(unsafe) {
            return String(unsafe)
                 .replace(/&/g, "&amp;")
                 .replace(/</g, "&lt;")
                 .replace(/>/g, "&gt;")
                 .replace(/"/g, "&quot;")
                 .replace(/'/g, "&#039;");
         }
        
        function makeTableHTML(myArray) {
            var result = "<table border=1>";
            for(var i=0; i<myArray.length; i++) {
                result += "<tr>";
                for(var j=0; j<myArray[i].length; j++){
                    k = escapeHtml((myArray[i][j]));
                    result += "<td>"+k+"</td>";
                }
                result += "</tr>";
            }
            result += "</table>";
        
            return result;
        }
        

        Test here with JSFIDDLE - Paste directly from Microsoft Excel to get table

        【讨论】:

          【解决方案10】:

          let data = [
            ['Title', 'Artist', 'Duration', 'Created'],
            ['hello', 'me', '2', '2019'],
            ['ola', 'me', '3', '2018'],
            ['Bob', 'them', '4.3', '2006']
          ];
          
          function getCell (cell, type='td') {
                  return `<${type}>${cell}</${type}>`
          }
          function getCells(cells, type='td') {
                  return cells.map(cell => getCell(cell, type)).join('');
          }
          
          function getRow(row) {
                  return `<tr> ${getCell(row[0], 'th')} ${getCells(row.slice(1))} </tr>`
          } 
                    
          function createTable(data) {
            const [headings, ...rows] = data;
                
              return `
                    <table>
                      <thead>${getCells(headings, 'th')}</thead>
                      <tbody>${rows.map(getRow).join('')}</tbody>
                    </table>
              `;
          }
          
          document.body.insertAdjacentHTML('beforeend', createTable(data));
          table { border-collapse: collapse; }
          tr { border: 1px solid #dfdfdf; }
          th, td { padding: 4px;}

          这是@Andy's answer 的精确副本,稍作修改,每行的第一个单元格将是th

          【讨论】:

            【解决方案11】:

            我知道这是一个老问题,但对于像我这样浏览网络的人来说,这是另一个解决方案:

            在逗号上使用replace() 并创建一组字符来确定一行的结尾。我只是将-- 添加到内部数组的末尾。这样您就不必运行for 函数。

            这是一个 JSFiddle:https://jsfiddle.net/0rpb22pt/2/

            首先,您必须在 HTML 中获取一个表格并为其指定一个 ID:

            <table id="thisTable"><tr><td>Click me</td></tr></table>
            

            这是您为此方法编辑的数组:

            thisArray=[["row 1, cell 1__", "row 2, cell 2--"], ["row 2, cell 1__", "row 2, cell 2"]];
            

            注意每个数组末尾添加的--

            因为数组中也有逗号 inside,所以您必须以某种方式区分它们,以免最终弄乱表格 - 在单元格后添加 __(除了最后一个行)有效。如果您的单元格中没有逗号,则无需执行此步骤。

            现在这是你的函数:

            function tryit(){
              document
                .getElementById("thisTable")
                .innerHTML="<tr><td>"+String(thisArray)
                .replace(/--,/g,"</td></tr><tr><td>")
                .replace(/__,/g,"</td><td>");
            }
            

            它是这样工作的:

            1. 致电您的餐桌并开始设置innerHTMLdocument.getElementById("thisTable").innerHTML
            2. 首先添加 HTML 标记以开始一行和数据。 "&lt;tr&gt;&lt;td&gt;"
            3. thisArray 添加为String()+String(thisArray)
            4. 将在新行之前结束的每个-- 替换为数据和行的关闭和打开。 .replace(/--,/g,"&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;")
            5. 其他逗号表示单独的数据行内。所以替换所有逗号关闭和打开数据。在这种情况下,不是所有逗号都在行之间,因为单元格有逗号,所以我们必须用__区分它们:.replace(/__,/g,"&lt;/td&gt;&lt;td&gt;")。通常你只需要.replace(/,/g,"&lt;/td&gt;&lt;td&gt;")

            只要您不介意在数组中添加一些杂散字符,它占用的代码就会少很多,而且实现起来也很简单。

            【讨论】:

            • 未来的我。我学到了很多东西。不要这样做。请。
            • 但我保留这个是为了后代,因为它很有趣。对于那些仍在编写这样的 hackey 代码的人:继续前进,这对您找出您还没有看到更好的方法的方法有好处!
            【解决方案12】:

            这是带有“表头”实现的 holmberd 答案

            function createTable(tableData) {
              var table = document.createElement('table');
              var header = document.createElement("tr");
              // get first row to be header
              var headers = tableData[0];
            
              // create table header
              headers.forEach(function(rowHeader){
                var th = document.createElement("th");
                th.appendChild(document.createTextNode(rowHeader));
                header.appendChild(th);
              });      
              console.log(headers);
            
              // insert table header 
              table.append(header);
              var row = {};
              var cell = {};
            
              // remove first how - header
              tableData.shift();
              tableData.forEach(function(rowData, index) {
                row = table.insertRow();
                console.log("indice: " + index);
                rowData.forEach(function(cellData) {
                  cell = row.insertCell();
                        cell.textContent = cellData;
                });
              });
              document.body.appendChild(table);
            }
            

            createTable([["第 1 行,单元格 1","第 1 行,第 2 单元格"],["第 2 行,第 1 行单元格","第 2 行,第 2 行单元格"],["第 3 行,第 1 行单元格" , "第 3 行,第 2 单元格"]]);

            【讨论】:

              【解决方案13】:

              这是一个示例,说明如何在 JavaScript 中从矩阵 m x n... 生成和读取数据

              let createMatrix = (m, n) => {
                    let [row, column] = [[], []],
                        rowColumn = m * n
                    for (let i = 1; i <= rowColumn; i++) {
                      column.push(i)
                      if (i % n === 0) {
                        row.push(column)
                        column = []
                      }
                    }
                    return row
                  }
              
              let setColorForEachElement = (matrix, colors) => {
                let row = matrix.map(row => {
                  let column = row.map((column, key) => {
                    return { number: column, color: colors[key] }
                  })
                  return column
                })
                return row
              } 
              
              const colors = ['red', 'green', 'blue', 'purple', 'brown', 'yellow', 'orange', 'grey']
              const matrix = createMatrix(6, 8)
              const colorApi = setColorForEachElement(matrix, colors)
              
              let table ='<table>'
              colorApi.forEach(row => {
                table+= '<tr>'
                  row.forEach(column =>  table += `<td style='background: ${column.color};'>${column.number}<td>` )
                table+='</tr>'
              })
              table+= '</table>'
              document.write(table);
              

              【讨论】:

                【解决方案14】:

                没有新行的纯功能表(只是为了好玩)

                const pureFunctionalTable = data => 
                    [document.createElement('table')].filter(table => !table.appendChild(
                        data.reduce((tbody, row) =>
                            !tbody.appendChild(row.reduce((tr, cell) =>
                                !tr.appendChild(document.createElement('td'))
                                   .appendChild(document.createTextNode(cell)) || tr
                                , document.createElement('tr'))
                            ) || tbody, document.createElement('tbody'))) || table)[0];
                
                
                

                用法

                document.body.appendChild(pureFunctionalTable([
                    ['row 1, cell 1', 'row 1, cell 2'],
                    ['row 2, cell 1', 'row 2, cell 2']
                ]));
                

                【讨论】:

                  【解决方案15】:

                  我的 10cent 以 ar 为数组:

                  '&lt;table&gt;&lt;tr&gt;'+ar.map(e=&gt;'&lt;td&gt;'+e.join('&lt;/td&gt;&lt;td&gt;')+'&lt;/td&gt;').join('&lt;/tr&gt;&lt;tr&gt;')+'&lt;/tr&gt;&lt;/table&gt;'

                  【讨论】:

                    【解决方案16】:

                    如果你不介意 jQuery,我使用的是this

                    <table id="metaConfigTable">
                        <caption>This is your target table</caption>
                        <tr>
                            <th>Key</th>
                            <th>Value</th>
                        </tr>
                    </table>
                    
                    <script>
                    
                        function tabelajzing(a){ 
                        // takes (key, value) pairs from and array and returns
                        // corresponding html, i.e. [ [1,2], [3,4], [5,6] ] 
                          return [
                            "<tr>\n<th>",
                            a.map(function (e, i) {
                              return e.join("</th>\n<td>")
                            }).join("</td></tr>\n<tr>\n<th>"),
                            "</td>\n</tr>\n"
                          ].join("")
                        }
                    
                      $('#metaConfigTable').find("tr").after(
                          tabelajzing( [ [1,2],[3,4],[5,6] ])
                      );
                    </script>
                    

                    【讨论】:

                      猜你喜欢
                      • 2012-04-27
                      • 2011-06-24
                      • 2015-03-31
                      • 2020-02-13
                      • 2020-06-29
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      相关资源
                      最近更新 更多