manny
manny

Reputation: 317

Read a csv or excel (xlsx) file with just javascript and html?

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

Answers (3)

FreeSoftwareServers
FreeSoftwareServers

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

Tom Faltesek
Tom Faltesek

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

Peter
Peter

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

Related Questions