2012-09-05 53 views
20

我想这HTML表格转换:使用如何HTML表格转换为JavaScript对象与jQuery

<table id="students" border="1"> 
    <thead> 
     <tr> 
      <th>Name</th> 
      <th>Age</th> 
      <th>Grade</th> 
     </tr> 
    </thead> 
    <tbody> 
     <tr class="student"> 
      <td>Oscar</td> 
      <td>23</td> 
      <td>16.5</td>   
     </tr> 
     <tr class="student"> 
      <td>Antonio</td> 
      <td>32</td> 
      <td>14</td>   
     </tr> 
     <tr class="student"> 
      <td>Jessica</td> 
      <td>21</td> 
      <td>19</td>   
     </tr> 
    </tbody> 
</table>​​​​​​ 

转换为JavaScript对象:

enter image description here

代码jQuery:

var tbl = $('table#students tr').map(function() { 
    return $(this).find('td').map(function() { 
    return $(this).text(); 
    }).get(); 
}).get(); 

上面的代码将输出下面的数组:

["Oscar", "23", "16.5", "Antonio", "32", "14", "Jessica", "21", "19"] 

一切都很好,在这一点上,但我该怎么办,如果我想在阵列内的JavaScript对象有以下结构:

[{id:1, name: "Oscar", age: 23, grade: 16.5}, {id:2, name: "Antonio", age: 32, grade: 14}, {id:3, name: "Jessica", age: 21, grade: 19}] 

enter image description here

只是更具体...

  • idtr
  • nameagegrade值从每行

获得获得我做了这个jsfiddle测试:

http://jsfiddle.net/oscarj24/ptVDm/

感谢

+1

第二个示例是** NOT JSON **。这是一个** JavaScript对象**。太多人已经对JSON的内容感到困惑,所以我会挑剔并指出这一点。 – Aesthete

+0

这很简单,但我必须说我需要一些时间来让它正确:JSON是一种序列化('字符串化')格式。如果它不是字符串,那不是JSON;如果它是一个字符串,它可能会或可能不会解析为有效的JSON。当有人说'一个JSON对象'时,它们可能意味着'一个数据值很容易被序列化为JSON'(所有值都不是这样)。 – flow

回答

24
var tbl = $('#students tr:has(td)').map(function(i, v) { 
    var $td = $('td', this); 
     return { 
       id: ++i, 
       name: $td.eq(0).text(), 
       age: $td.eq(1).text(), 
       grade: $td.eq(2).text()    
       } 
}).get(); 

7

下面应该工作:

var cols = []; 
var result = []; 
$('#students>thead>th').each(function(){ 
    cols.push($(this).text().toLowerCase()); 
}); 
$('#students>tbody>tr').each(function(id){ 
    var row = {'id': id+1}; 
    $(this).find('td').each(function(index){ 
     row[cols[index]] = $(this).text(); 
    }); 
    result.push(row); 
}); 

console.log(result); 

基本上,我觉得从表头的对象属性,接下来我创建一个对象的每一行,指定值属性名称从早先的数组中推导出来。

一些明显的缺陷:

  • 如果表数据实际上不同出于某种原因(例如,用于化妆品空行),该系统将放空对象所得阵列英寸
  • 如果您在表中使用colspan属性,则此系统不会自动在不同的对象属性中复制相同的值,而是限制设置为剩余的<td>

看到Josiah的方法,它可能比我的更快,因为我的设法通过寻找属性名称来变得更聪明。如果你知道你的表格结构不会改变,我会推荐他的技术。否则,你需要我的代码行。噢,为了完整起见,here's a JSFiddle with mine

4

请参阅updated小提琴。附加数组map是不必要的,因为此时您正在为您的JSON查找文字对象。

var data = $('table#students tbody tr').map(function(index) { 
    var cols = $(this).find('td'); 
    return { 
     id: index + 1, 
     name: cols[0].innerHTML,   // use innerHTML 
     age: (cols[1].innerHTML + '') * 1, // parse int 
     grade: (cols[2].innerHTML + '') * 1 // parse int 
    }; 
}).get(); 
+0

在你的小提琴中,你需要console.log(数据)而不是console.log(tbl)。 – VictorKilo

+0

谢谢,更新。 –

1

尝试以下方法为n列

DEMO:http://jsfiddle.net/ptVDm/7/

var tblhdr = $('table#students th').map(function() { 
    return $(this).text(); 
}).get(); 

console.log(tblhdr); 

var tbl = $('table#students tbody tr').map(function(idx, el) { 
    var td = $(el).find('td'); 
    var obj = {id: idx+1}; 

    //Can work on number of columns 
    for (var i = 0; i < tblhdr.length; i++) { 
     obj[tblhdr[i]] = td.eq(i).text(); 
    } 

    return obj; 
}).get(); 

console.log(tbl); 
1

说不上如果jQuery的帮助很多在这种情况下,这里有一个简单的JS解决方案是合理地独立于表结构。它只是要求第一行是一个标题(可以是不同的表格段元素),而1+行是数据。

该表可以有任意多的行或列,只要你喜欢,如果有rowspan或colspans在那里它会搅乱结果(但jQuery也不会帮你这么做)。

它可以很容易地适应具体使用的标题部分的属性名称,并忽略页脚部分:

function tableToObj(table) { 
    var rows = table.rows; 
    var propCells = rows[0].cells; 
    var propNames = []; 
    var results = []; 
    var obj, row, cells; 

    // Use the first row for the property names 
    // Could use a header section but result is the same if 
    // there is only one header row 
    for (var i=0, iLen=propCells.length; i<iLen; i++) { 
    propNames.push(propCells[i].textContent || propCells[i].innerText); 
    } 

    // Use the rows for data 
    // Could use tbody rows here to exclude header & footer 
    // but starting from 1 gives required result 
    for (var j=1, jLen=rows.length; j<jLen; j++) { 
    cells = rows[j].cells; 
    obj = {}; 

    for (var k=0; k<iLen; k++) { 
     obj[propNames[k]] = cells[k].textContent || cells[k].innerText; 
    } 
    results.push(obj) 
    } 
    return results; 
} 
8

我需要这个确切的事情,但我需要更多的功能,能够覆盖列名称并忽略任何隐藏的行。我写了一个jQuery插件,做到了这一点,设在这里https://github.com/lightswitch05/table-to-json

为你的榜样,你会怎么做:(http://jsfiddle.net/ptVDm/118/

var table = $('#students').tableToJSON(); 

有一点要注意的是,ID是不能得到的对象的一部分。你可以从对象的数组位置获取id。或者,如果您确实需要将其作为对象的一部分,则可以为该ID创建一个隐藏列,然后将其包含在内。

+0

当您要在表中使用'rowspan'或'colspan'时,这种方法存在问题。对于普通桌子来说,这很完美。 – D3V

+0

@ D3V - 你说得对,我没有添加任何对'rowspan'或'colspan'的支持。如果您喜欢 – lightswitch05

+0

@ lightswitch05,我们欢迎您添加支持,我会合并这些更改:我有一个需要考虑的要求。我计算出了每个属性值的索引,并有一个缓存来存储它们并传递这些值,以便所有的键都可以与列名正确对齐。我将尝试使该代码更通用,并将其与插件合并。 – D3V

相关问题