Skip to content

Instantly share code, notes, and snippets.

@friendlyanon
Created April 11, 2019 17:29
Show Gist options
  • Save friendlyanon/04e15b877c5a2ef7563247dc25962e77 to your computer and use it in GitHub Desktop.
Save friendlyanon/04e15b877c5a2ef7563247dc25962e77 to your computer and use it in GitHub Desktop.
const csvEscape = function() {
const map = {
";": ",",
"\n": "\\n"
};
const replacerRe = /./gsm;
const replacer = x => `\\x${x.charCodeAt(0).toString(16).padStart(2, 0)}`;
const escaped = Object.keys(map).map(x => x.replace(replacerRe, replacer));
const escapeRe = new RegExp(escaped.join("|"), "g");
const escape = x => map[x];
return el => {
const span = el.getAttribute("colspan") | 0;
const escaped = el.textContent.trim().replace(escapeRe, escape);
return span < 2 ? escaped : Array(span).fill(escaped).join(";");
};
}();
function processRow({ children: row }) {
const length = row.length;
if (!length) return "";
const str = length > 50 ? Array(length) : [];
str[0] = csvEscape(row[0]);
for (let i = 1; i < length; ++i) {
str[i] = `;${csvEscape(row[i])}`;
}
return str.join("");
}
function processHead(table, target) {
const { tHead } = table;
if (!tHead) return;
const { rows } = tHead;
switch (rows.length) {
case 0: return;
case 1: break;
default: throw new RangeError("can't have more than one head row");
}
target.push(processRow(rows[0]));
}
function processBodies(table, target) {
for (const body of table.tBodies) {
for (const row of body.children) {
if (row.tagName === "TR") {
target.push(processRow(row));
}
}
}
}
function processFoot(table, target) {
const { tFoot } = table;
if (!tFoot) return;
for (const row of tFoot.rows) {
target.push(processRow(row));
}
}
export default function tableToCsv(table) {
if (table == null || table.tagName !== "TABLE") {
throw new TypeError("invalid argument");
}
const result = [];
processHead(table, result);
processBodies(table, result);
processFoot(table, result);
return result.join("\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment