2

I am trying to load a file into the browser and render it in a vue-excel-editor component. To do this I have a Vuetify v-file-input component into which the user can enter a .xlsx file. That works fine. I then listen to the change event on this component to see when the file is put in. I log the event and it looks like this (copied from the console):

File
  lastModified: 1613740797643
  name: "Book1.xlsx"
  size: 8129
  type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
  webkitRelativePath: ""
  <prototype>: FilePrototype { name: Getter, lastModified: Getter, webkitRelativePath: Getter, … }

I don't understand how I can read the contents of this file, which I am trying to do with js-xlsx. It has an example on its npm page using an HTML5 file input:

function handleFile(e) {
  var files = e.target.files;
  var i, f;
  
  for (i = 0, f = files[i]; i != files.length; ++i) {
    var reader = new FileReader();
    var name = f.name;
    reader.onload = function(e) {
      var data = e.target.result;
 
      var workbook = XLSX.read(data, {type: 'binary'});
 
      /* DO SOMETHING WITH workbook HERE */
    };
    reader.readAsBinaryString(f);
  }
}
input_dom_element.addEventListener('change', handleFile, false);

I am trying to adapt this into Vue but it complains that e doesn't have a target property, which is obviously true becuase of what I printed in the console earlier. Is this not the right way to do this? Here are the relevant bits from my Vue component:

<script>
  <template>
    <v-file-input
      label="Upload XLSX"
      filled
      @change="handleExcelBrowserUpload"
    ></v-file-input>
  </template>
<script>

import XLSX from "js-xlsx";
export default {
  name: 'LoadCurveUpload',
  methods: {
    handleExcelBrowserUpload(e) {
      console.log(e);  // This prints the first code block in this question

      var files = e.target.files;
      var i, f;

      for (i = 0, f = files[i]; i != files.length; ++i) {
        var reader = new FileReader();
        reader.onload = function(e) {
          var data = e.target.result;

          var workbook = XLSX.read(data, {type: 'binary'});
          console.log(workbook);
        }
      }
    }
  }
wfgeo
  • 2,716
  • 4
  • 30
  • 51

1 Answers1

1

I use the following code in Vuetify to read xlsx and turn it into an array.

Code

Template

<v-row>
    <v-col cols="8">
      <template>
        <v-file-input
          accept=".xlsx"
          label="File input(xlsx)"
          outlined
          v-model="selectXlsx"
          show-size
        >
        </v-file-input>
      </template>
    </v-col>

    <v-col cols="4">
      <v-btn
        color="primary"
        @click="uploadXlsx"
        class="mt-3"
      >
        Upload
      </v-btn>
    </v-col>
</v-row>

Script

import XLSX from "xlsx";
export default {
    name: "App",
    data() {
        return {
            selectXlsx: null,
    }
    methods: {
        uploadXlsx() {
          if (!this.selectXlsx) {
            console.log("Please upload a xlsx file")
            return;
          }
          if (this.selectXlsx) {
            const reader = new FileReader();
            reader.onload = (e) => {
              /* Parse data */
              const bstr = e.target.result;
              const wb = XLSX.read(bstr, { type: "binary" });
              /* Get first worksheet */
              const wsname = wb.SheetNames[0];
              const ws = wb.Sheets[wsname];
              /* Convert array of arrays */
              const data = XLSX.utils.sheet_to_json(ws, { header: 1 });
               
              console.log(data);
            };

            reader.readAsBinaryString(this.selectXlsx);
          }
          this.selectXlsx = null;
        },
    }
}
shark.tar.gz
  • 61
  • 1
  • 2