How to convert HTML table to Javascript Object with jQuery

I am trying to convert this HTML table:

enter image description here


<table id="students" border="1">
        <tr class="student">
        <tr class="student">
        <tr class="student">

Into a javascript object using jQuery:

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

The above code will output the following array:

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

Everything is good at this point but how can I do if I want the javascript objects inside the array to have the following structure:

[{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

Just to be more specific…

  • The id is obtained from the tr
  • The name, age and grade values are obtained from each row

I made this jsfiddle to test:


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()               

I needed this exact thing, except I needed more features to be able to override column names and ignore any hidden rows. I wrote a jQuery plugin that does just that, located here

for your example you would do: (

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

One thing to note is that the id’s aren’t part of the resulting object. You could just get the id from the object’s array location. Or if you really needed it to be part of the object, you could create an hidden column for the ID’s and then they would be included

Read More:   JSON.parse(fs.readFileSync()) returning a buffer - string of numbers

The following should work:

var cols = [];
var result = [];
    var row = {'id': id+1};
        row[cols[index]] = $(this).text();


Basically, I find the object properties from the table head, next I create an object for each row, assigning values to property names as deduced from the earlier array.

Some obvious flaws:

  • If the table data actually differs for some reason, (eg; empty rows for cosmetic), this system will put empty objects in the resulting array.
  • If you use colspan attribute in the table, this system won’t automatically replicate the same value in different object properties, but rather limit to setting up to the remaining <td>s.

Seeing Josiah’s approach, it’s probably faster than mine since mine tries to be smarter by finding property names. I would recommend his technique if you know for sure your table structure will not change. Otherwise, you would need something on the lines of my code.

Oh, and for the sake of completeness, here’s a JSFiddle with mine.

See updated fiddle. The additional array map is unnecessary because you are looking for a literal object for your JSON at this point.

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

Dunno if jQuery helps much in this case, here’s a plain JS solution that is reasonably independent of the table structure. It just requires that the first row is a header (can be a different table section element or not) and the rows 1+ are data.

Read More: is sending a GET request

The table can have as many columns or rows as you like, if there are rowspan or colspans in there it will mess with the result (but jQuery won’t help you with that either).

It could easily be adapted to specifically use the header section for the property names and to ignore a footer section:

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;
  return results;

Try below approach for n columns


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


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;


The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 .

Similar Posts