點燈坊

失くすものさえない今が強くなるチャンスよ

Reading Excel on Alpine

Sam Xiao's Avatar 2022-11-22

Although we can’t read Excel files on Alpine directly, we can use the xlsx package to finish the task.

Version

Alpine 3.9

xlsx

excel000

Excel file is read on Alpine.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://unpkg.com/alpinejs" defer></script>
    <script
      lang="javascript"
      src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script>
    <title>Alpine Lab</title>
  </head>
  <body>
    <input
      x-data
      type="file"
      @change="onChange($el)"
      accept=".csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" />
  </body>
  <script>
    let { read, utils } = XLSX

    let onChange = ({ files: [file, _] }) => {
      let fileReader = new FileReader()
      fileReader.readAsArrayBuffer(file)

      fileReader.onload = e => {
        let workbook = read(e.target.result)
        let sheetName = workbook.SheetNames[0]
        let sheet = workbook.Sheets[sheetName]
        let data = utils.sheet_to_json(sheet)[0]

        console.log(data)
      }
    }
  </script>
</html>

Line 7

<script
  lang="javascript"
  src="https://cdn.sheetjs.com/xlsx-latest/package/dist/xlsx.full.min.js"></script>
  • Load XLSX package by CDN

Line 13

<input
  x-data
  type="file"
  @change="onChange($el)"
  accept=".csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" />
  • x-data:define <input> as component
  • @change:fire onChange() on change event and pass $el as current element to onChange(), so we don’t have to use x-ref to define the reference to DOM element
  • accpet:only Excel files accept

Line 20

let { read, utils } = XLSX
  • Extract read() and utils() from XLSX

Line 22

let onChange = ({ files: [file, _] }) => {
  let fileReader = new FileReader()
  fileReader.readAsArrayBuffer(file)     
}
  • file:extract file Object from parameter list
  • fileReader:create FileReader instance
  • readAsArrayBuffer():use readAsArrayBuffer() to fill fileReader from file Object

Line 26

fileReader.onload = e => {
  let workbook = read(e.target.result)
  let sheetName = workbook.SheetNames[0]
  let sheet = workbook.Sheets[sheetName]
  let data = utils.sheet_to_json(sheet)[0]

  console.log(data)
}
  • onload():read Excel file when fileReader Object finishes loading
  • read():read selected file from e.target.result, which is an ArrayBuffer
  • SheetName[]:get the name of the sheets
  • Sheets:use Sheets[] by the sheetName to get the sheet
  • utils.sheet_to_json():convert sheet to JSON

Conclusion

  • In simple scenarios, we may not have to use x-ref to define a reference for the DOM element. Just pass $el to get selected files