Loading

vue2项目中使用webworker(二):导出Excel

需求

有的时候我们导出的数据量很大,如果在主进程中操作的话可能会导致页面卡顿的问题

代码

App.vue

<template>
  <div class="app">
    <button @click="exportExcel">导出Excel</button>
  </div>
</template>

<script>
import ExcelWorker from './worker/excel.worker.js'

import * as XLSX from 'xlsx-js-style'

export default {
  created() {
    const worker = new ExcelWorker()
    this.worker = worker
    this.worker.addEventListener('message', (e) => {
      const { workbook, excelName } = e.data
      XLSX.writeFile(workbook, excelName)
    })
  },
  methods: {
    exportExcel() {
      this.worker.postMessage({
        data: [
          {
            name: 'zs',

            age: 20,

            date: '1991-06-01',

            address: '广州市',
          },

          {
            name: 'ww',

            age: 14,

            date: '2001-09-01',
          },

          {
            name: 'ls',

            age: 31,

            date: '1993-04-14',
          },
        ],
        columns: [
          {
            prop: 'name',

            label: '姓名',

            width: 150,

            excelStyle: {
              font: { bold: true },

              alignment: {
                horizontal: 'center',

                vertical: 'center',
              },

              fill: {
                fgColor: {
                  rgb: 'FFFF00',
                },
              },
            },
          },

          {
            prop: 'age',

            label: '年龄',

            width: 300,
          },

          {
            prop: 'date',

            label: '出生日期',

            excelStyle: {
              fill: {
                fgColor: {
                  rgb: '00FFFF',
                },
              },
            },
          },
        ],
        excelName: '测试',
      })
    },
  },
}
</script>

<style lang="less" scoped></style>

excel.worker.js

import { exportExcel } from '@/utils/excel.js'


self.onmessage = (e) => {
  const { columns, data, excelName } = e.data

  exportExcel(excelName, data, columns, (workbook, excelName) => {
    self.postMessage({
      workbook,
      excelName
    })
  })
}

utils/excel.js

import * as XLSX from 'xlsx-js-style'



export function exportExcel(excelName, data, columns, cb) {

  const newData = []

  const keys = columns.map((item) => item['prop'])

  const headers = columns.map((item) => item['label'])



  data.forEach((item) => {

    const row = []

    for (let key of keys) {

      row.push(item[key])

    }

    newData.push(row)

  })

  // 添加表头

  newData.unshift(headers)



  const workbook = XLSX.utils.book_new()

  const worksheet = XLSX.utils.json_to_sheet(newData, {

    skipHeader: true,

  })



  // 设置列宽

  const columnsWidth = columns.map((item) => {

    return {

      wpx: item.width,

    }

  })

  worksheet['!cols'] = columnsWidth



  // 设置表头样式

  columns.forEach((item, index) => {

    if (item['excelStyle']) {

      const cell = indexToLetters(index) + 1

      worksheet[cell].s = item['excelStyle']

    }

  })



  XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')

  // XLSX.writeFile(workbook, `${excelName}.xlsx`)
  cb(workbook, `${excelName}.xlsx`)
}



function indexToLetters(i) {

  if (i >= 0 && i <= 25) {

    return String.fromCharCode(65 + i)

  } else {

    return undefined

  }

}

posted @ 2024-09-02 19:33  ^Mao^  阅读(106)  评论(0编辑  收藏  举报