Reputation: 317
Is it possible to read a excel xlsx or csv, preferably xlsx, using just JavaScript and html. All the solutions (sheetsJS, d3{d3 uses the Fetch API}) I have found require a webserver. I understand I can get a simple webserver using web server for chrome or python or node.js. Futhermore, I understand I can run chrome with certain flags, but I would like to not do this because of security concerns. I am building a demo for someone who is not web savvy and would like to avoid doing this.
my file structure is very simple :
TestFolder
| index.html
| js/
| test.js
| data/
| test.xlsx
| css/
| test.css
I simply need to read the xlsx and then display that data in html page.
Upvotes: 9
Views: 41624
Reputation: 2791
Here is how I ended up doing it:
I got error w/ readAsBinaryString
so I went out w/ the below. I noted that sheet_to_json
didn't work w/ csv
so I ran that first and checked results and parsed sheet_to_csv
if sheet_to_json === 0
.
HTML:
<!-- SheetsJS CSV & XLSX -->
<script src="xlsx/xlsx.full.min.js"></script>
<!-- SheetsJS CSV & XLSX -->
<!-- CSV/XLSX -->
<div class="ms-font-xl ms-settings__content__subtitle">CSV/XLSX Upload:</div>
<input type="file" id="csv-xlsx-file" accept=".csv,application/vnd.ms-excel,.xlt,application/vnd.ms-excel,.xla,application/vnd.ms-excel,.xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,.xltx,application/vnd.openxmlformats-officedocument.spreadsheetml.template,.xlsm,application/vnd.ms-excel.sheet.macroEnabled.12,.xltm,application/vnd.ms-excel.template.macroEnabled.12,.xlam,application/vnd.ms-excel.addin.macroEnabled.12,.xlsb,application/vnd.ms-excel.sheet.binary.macroEnabled.12">
<!-- CSV/XLSX -->
JS:
var csv_file_elm = document.getElementById("csv-xlsx-file")
csv_file_elm.addEventListener('change', CSV_XLSX_File_Selected_Event)
async function CSV_XLSX_File_Selected_Event() {
var id = this.id
var inputElement = document.getElementById(id)
let ext = inputElement.value
ext = ext.split(".")
ext = ext[ext.length - 1]
var files = inputElement.files || [];
if (!files.length) return;
var file = files[0];
var reader = new FileReader();
reader.onloadend = async function (event) {
var arrayBuffer = reader.result;
var options = { type: 'array' };
var workbook = XLSX.read(arrayBuffer, options);
//console.timeEnd();
var sheetName = workbook.SheetNames
var sheet = workbook.Sheets[sheetName]
var sheet_to_html = XLSX.utils.sheet_to_html(sheet)
var sheet_to_json = XLSX.utils.sheet_to_json(sheet)
if (sheet_to_json.length === 0) {
var sheet_to_csv = [XLSX.utils.sheet_to_csv(sheet)]
var results = sheet_to_csv
}
if (sheet_to_json.length > 0) {
var results = sheet_to_json
}
let Parsed_File_Obj = {
"sheet_to_html": sheet_to_html,
"results": results,
"ext": ext,
}
console.log('Parsed_File_Obj')
console.log(Parsed_File_Obj)
};
reader.readAsArrayBuffer(file);
}
Upvotes: 2
Reputation: 2818
You could try using the Fetch API to download the file and process it with JavaScript.
fetch('data/test.xlsx').then(function(resp) {
// Process the data here...
console.log('Data Response: ', resp);
});
It would be much easier to work with if your data file was in JSON format, but this might work for your needs.
Update - Example when the data is in JSON format
fetch('data/test.xlsx').then(function(resp) {
var records = resp.json(); // Assuming that we receive a JSON array.
console.log('Records: ', records.length);
records.forEach(function(record){
console.log('Record Name: ', record.name); // Assuming each record has a name property
});
});
Upvotes: 1
Reputation: 2927
I've added a simple example that accepts Excel or CSV files (current example accepts a single file), uses the SheetJS library to parse the Excel file type, convert the data to JSON and logs the contents to the console.
This should be more than enough to complete your demo. Hope this helps!
var file = document.getElementById('docpicker')
var viewer = document.getElementById('dataviewer')
file.addEventListener('change', importFile);
function importFile(evt) {
var f = evt.target.files[0];
if (f) {
var r = new FileReader();
r.onload = e => {
var contents = processExcel(e.target.result);
console.log(contents)
}
r.readAsBinaryString(f);
} else {
console.log("Failed to load file");
}
}
function processExcel(data) {
var workbook = XLSX.read(data, {
type: 'binary'
});
var firstSheet = workbook.SheetNames[0];
var data = to_json(workbook);
return data
};
function to_json(workbook) {
var result = {};
workbook.SheetNames.forEach(function(sheetName) {
var roa = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], {
header: 1
});
if (roa.length) result[sheetName] = roa;
});
return JSON.stringify(result, 2, 2);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.14.3/xlsx.full.min.js"></script>
<label for="avatar">Choose an Excel or CSV file:</label>
<input type="file" id="docpicker" accept=".csv,application/vnd.ms-excel,.xlt,application/vnd.ms-excel,.xla,application/vnd.ms-excel,.xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,.xltx,application/vnd.openxmlformats-officedocument.spreadsheetml.template,.xlsm,application/vnd.ms-excel.sheet.macroEnabled.12,.xltm,application/vnd.ms-excel.template.macroEnabled.12,.xlam,application/vnd.ms-excel.addin.macroEnabled.12,.xlsb,application/vnd.ms-excel.sheet.binary.macroEnabled.12">
<div id="dataviewer">
Upvotes: 21