Skip to content

Instantly share code, notes, and snippets.

@earlgreyxxx
Last active February 20, 2022 05:09
Show Gist options
  • Save earlgreyxxx/ceec2a6536ac73a87ca0b4791df8b460 to your computer and use it in GitHub Desktop.
Save earlgreyxxx/ceec2a6536ac73a87ca0b4791df8b460 to your computer and use it in GitHub Desktop.
/*****************************************************************************
*
* table to json
*
*****************************************************************************/
(function() {
HTMLTableElement.prototype.toJSON = toJSON;
HTMLTableElement.prototype.toArray = toArray;
function toJSON(indent,fn,headers)
{
return JSON.stringify(this.toArray(fn,headers),null,indent);
}
// fn: filter function. prototype: function fn(v);
// in filter function this point to HTMLTableCellElement
function toArray(fn,headers)
{
if(!(this instanceof HTMLTableElement))
throw new Error('not table element');
const oTable = this;
let heads = [];
let rows = [];
let excludes = new Set;
if(headers instanceof Array && headers.length > 0)
{
heads = headers;
}
else
{
let oThead = oTable.tHead;
if(!oThead)
throw new Error('thead element not found');
let oTR = oThead.querySelector('thead > tr');
oTR.querySelectorAll('tr > *').forEach(el => heads.push('key' in el.dataset && el.dataset.key.length > 0 ? el.dataset.key : el.innerText.trim().replace(/[\r\n]/g,'')));
}
let oTbodies = oTable.tBodies;
if(oTbodies.length == 0)
throw new Error('tbody element not found');
let oTbody = oTbodies[0];
let filter = fn || (v => v);
oTbody.querySelectorAll('tbody > tr').forEach((el,r) => {
let row = rows[r] === undefined ? {} : rows[r];
let oTDs = el.querySelectorAll('tr > *');
let columnnum = heads.length;
for(let c=0,h=0;c<columnnum;c++,h++)
{
while(heads[h] in row)
h++;
let td = oTDs.item(c);
if(!td)
continue;
let colspan = parseInt(td.getAttribute('colspan')) || 1;
let rowspan = parseInt(td.getAttribute('rowspan')) || 1;
let cellText = filter.call(td,td.innerText.trim());
if(h < heads.length && !(heads[h] in row))
row[heads[h]] = cellText;
if(rowspan > 1)
{
for(let i=1;i<rowspan;i++)
{
if(rows[r+i] === undefined)
rows[r+i] = {};
rows[r+i][heads[h]] = cellText;
}
}
if(colspan > 1)
h+=(colspan - 1);
};
if(rows[r] === undefined)
rows[r] = row;
if('exclude' in el.dataset && el.dataset.exclude === 'true')
excludes.add(r);
});
return rows.filter((v,i) => !excludes.has(i));
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment