I have written a function in javascript that identifies a table in a HTML webpage, parses through the data and downloads it as comma separated values that retains the correct structure of the table. I was hoping there would be a simple way to download the tables as a csv file instead, making sure it keeps the correct structure (i.e. blank cells when present etc).
function downloadTableData(){
try{
var file_string = "";
var table_number = window.prompt("Table number:") - 1;
var column_names = document.getElementsByTagName("table")[table_number].children[0].children[0].children;
col_names = "";
for(var i=0; i<column_names.length; i++){
col_names += column_names[i].innerText+",";
}
file_string += col_names += "\n";
var table_rows = document.getElementsByTagName("table")[table_number].children[1].children;
var extracted_rows = [];
for(var row_i=0; row_i<table_rows.length; row_i++){
var row_vals = ""
for(var col_i=0; col_i<table_rows[row_i].children.length; col_i++){
row_vals += table_rows[row_i].children[col_i].innerText + ",";
}
file_string += row_vals+"\n";
extracted_rows.push(row_vals);
}
var textInput = file_string;
alert('Table successfully detected');
var filename = window.prompt("Filename:");
var element = document.createElement('a');
element.setAttribute('href','data:text/plain;charset=utf-8, ' + encodeURIComponent(textInput));
element.setAttribute('download', filename);
document.body.appendChild(element);
element.click();
} catch(err){
alert('No table detected');
}
You can create a blob with type text/csv
let hiddenElement = document.createElement("a");
let csvData = new Blob([textInput], { type: "text/csv" });
let csvUrl = URL.createObjectURL(csvData);
element.href = csvUrl;
element.target = "_blank";
element.download = filename + ".csv";
element.click();
Given this HTML Table sample:
<table id="tableTest">
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
</tr>
</thead>
<tbody>
<tr>
<td>John</td>
<td>Doe</td>
</tr>
<tr>
<td>Anne</td>
<td>Mar</td>
</tr>
</tbody>
</table>
download() functiontableToCSV() function that converts a common HTML Table to CSV// DOM utility functions:
const
ELNew = (tag, prop) => Object.assign(document.createElement(tag), prop),
ELS = (sel, par) => (par || document).querySelectorAll(sel),
EL = (sel, par) => (par || document).querySelector(sel);
// Task functions:
const
download = (href, name = "unnamed") => {
const EL_a = ELNew("a", { href, download: name });
EL("body").append(EL_a);
EL_a.click();
EL_a.remove();
};
const
tableToCSV = (El_table, delimiter = ";") =>
[...ELS("tr", El_table)].map(EL_tr => [...ELS("th,td", EL_tr)].map(EL_cell => EL_cell.textContent).join(delimiter)).join("\n");
to get your Table as CSV String use:
const CSV = tableToCSV(EL("#tableTest"));
Tip: The default delimiter is ";". To change it to i.e a Comma use:
const CSV = tableToCSV(EL("#tableTest"), ",");
finally to download it use your download() function.
Here are two examples:
download(
"data:text/csv;charset=utf-8,\uFEFF" + encodeURIComponent(CSV),
`whatever.csv`
);
download(
URL.createObjectURL(new Blob([CSV], { type: "text/csv;charset=utf-8" })),
`whatever.csv`
);
Final output file:
whatever.csv
Name;Surname
John;Doe
Anne;Mar