The simplest should be C V big method!!

instructions

This article focuses on the implementation of features, not much else. If you want to use it, you can directly CV to your own project. If you want to further study, there is also an official website to view it by yourself 🍺

SheetJS jS-XLSX is an easy-to-use excel library that requires only PURE JS to read and export Excel files in a variety of formats, including XLS, XLSX, ODS, and more. This article takes the XLSX format as an example. Github:github.com/SheetJS/she…

Why use Web Workers? In order to speed up the resolution and improve the user experience 🤡. See Ruan’s blog 😀 How to use Web Worker – Ruan yifeng’s weblog

Supporting demo warehouse:Gitee.com/ardeng/work…

Results demonstrate

In the code

HTML

Plain old, simple Element UI upload component

<el-upload
    ref="input"
    action="/"
    :show-file-list="false"
    :auto-upload="false"
    :on-change="importExcel"
    type="file"
>
    <el-button type="primary">upload</el-button>
</el-upload>
Copy the code

JS part

Let’s start with a version without Web workers

Once a Worker thread is created, it is always running and is not interrupted by activity on the main thread, such as a user clicking a button or submitting a form. This facilitates communication that responds to the main thread at any time. However, this also causes the Worker to consume resources, so it should not be overused and should be closed once it is used.

There are several considerations for using Web workers.

  1. Origin limit The script files assigned to Worker threads must be the same origin as the script files of the main thread.
  2. DOM limitUnlike the main thread, the DOM object of the page where the main thread resides cannot be read or useddocument,window,parentThese objects. However, Worker threads cannavigatorThe objects andlocationObject.
  3. Communication the Worker thread and the main thread are not in the same context, they cannot communicate directly and must be done via messages.
  4. Script limitThe Worker thread cannot executealert()Methods andconfirm()Method, but you can make AJAX requests using the XMLHttpRequest object.
  5. File limitWorker threads cannot read local files, i.e. cannot open the local file system (file://), the script it loads must come from the network.

Due to the above restrictions, it is ok not to engage in Worker work. Directly parse the file object conversion data.

importExcel(file) {
  // Verify that the file is excel
  if (!/\.(xlsx|xls|csv)$/.test(file.name)) {
    alert("Format error! Please choose again.")
    return
  }
  this.fileToExcel(file).then(tabJson= > {
    // Get excel data here
    console.log(tabJson)
  })
},
// Excel data is converted to JSON array
fileToExcel(file) {
  // It makes more sense to just make the file read asynchronous instead of using Promise
  return new Promise(function (resolve, reject) {
    const reader = new FileReader()
    reader.onload = function (e) {
        // Get file data
        const result = e.target.result
        Type: 'binary' Mandatory
        const excelData = XLSX.read(result, { type: 'binary' })
        // Note the addition of {header: 1}. This configuration item generates a two-dimensional array
        const data = XLSX.utils.sheet_to_json(excelData.Sheets[excelData.SheetNames[0]] and {header: 1 }) / /! Read removes data from workbook
        resolve(data)
      }
      // Call the method to read the binary string
      reader.readAsBinaryString(file.raw)
    })
  }
Copy the code

Web Worker version

It is essential to use Worker to do some front-loading work

  1. Download the worker – loader
npm i -D worker-loader
Copy the code
  1. Configure loader in vue.config.js
// Set worker-loader to parse worker.js files
chainWebpack: config= > {
  config.module.rule('worker')
    .test(/\.worker\.js$/)
    .use('worker-loader')
    .loader('worker-loader')
    .options({ inline: 'fallback'})}Copy the code

Enter the Web Worker

The Web Worker naming rules are encapsulated as follows: xxx.worker.js

In the following code, self represents the child thread itself, the global object of the child thread.

// src\utils\excel.worker.js

import XLSX from 'xlsx'

/** * The main thread of the error-handling function can listen for Worker errors. * If an error occurs, the Worker raises an 'error' event for the main thread. * /
const ERROR = () = > {
    // Send an error message
    self.postMessage({ message: 'error'.data: []})// 'self.close()' closes itself within the Worker.
    self.close()
}

// Error handling
self.addEventListener('error'.(event) = > {
    ERROR()

    // Output error information
    console.log('ERROR: Line ', event.lineno, ' in ', event.filename, ':', event.message)
})

/ * * *@description: Worker threads need to have a listener function inside that listens for 'message' events. The worker thread received a message from the main thread@param {object} Event Event. data Receives data from the main thread */
self.addEventListener('message'.async (event) => {
    // Send messages to the main thread
    // postMessage(event.data);

    // Parse Excel data
    parsingExcel(event.data)
}, false)

/ * * *@description: Parse Excel data *@param {object} Data. excelFileData File data *@param {object} Data. config Configuration information */
const parsingExcel = (data) = > {
    try {
        // Notice that {header: 1} generates a two-dimensional array
        const { excelFileData, config = { header: 1 } } = data

        // Create the instantiated object
        const reader = new FileReader()

        // Process data
        reader.onload = function (e) {
            // Get file data
            const result = e.target.result;
            const excelData = XLSX.read(result, { type: 'binary' })
            const data = XLSX.utils.sheet_to_json(excelData.Sheets[excelData.SheetNames[0]], config) / /! Read removes data from workbook

            // Send a message
            self.postMessage({ message: 'success', data })
        };
        // Call the method to read the binary string
        reader.readAsBinaryString(excelFileData.raw);
    } catch (err) {
        ERROR()
        console.log('Catch error while parsing Excel data ===>', err)
    }
}
Copy the code

use

The introduction of the file

import Worker from '@/utils/excel.worker.js'
Copy the code

Business related logic

importExcel(file) {
  if (!/\.(xlsx|xls|csv)$/.test(file.name)) {
    alert("Format error! Please choose again.")
    return;
  }
  
  // Create a real column
  const worker = new Worker()

  // The main thread calls the worker.postmessage () method to send a message to the worker
  worker.postMessage({
    excelFileData: file,
    config: { header: 1}})// The main thread receives the message from the child thread by specifying the listener function 'worker.onmessage'
  worker.onmessage = (event) = > {
    const { message, data } = event.data
    if (message === 'success') {
      // Data is a two-dimensional array with the header at the top
      console.log(data)
      // When the Worker completes the task, the main thread can close it.
      worker.terminate()
    }
  }
}
Copy the code

Possible problems

  1. npm run devFailed to start and Webpack reported an error: checkwebpack worker-loaderVersion.
  2. The console reported an error containingnot a function 或 not a constructor: Check the WebPCK configuration. It is best to check the English documentationwebpackBecause the Chinese document is not updated in time.
  3. Console errorwindow is not defined: change toselfGive it a try. referenceWebpack worker-loader-import doesn’t work