Vue3处理Excel导入导出
图
Vue3项目遇到了表格的导入导出场景,需要进行数据的解析,后端数据的表格生成,发现xlsx组件能很好的解决这样的问题,于是封装为自定义组件,方便在项目中进行复用,提供一种表格处理的思路

安装

npm install xlsx

Excel数据导入

结合Element的上传组件获取文件流进行解析,以下是组件

<!-- 表格解析 -->
<template>
  <div>
    <el-upload
        action=""
        :file-list="fileList"
        :http-request="uploadHttp">
      <el-button type="primary">请选择上传文件</el-button>
    </el-upload>
  </div>
</template>

<script setup>
import {ref, getCurrentInstance, watch} from 'vue'
import {read, utils} from 'xlsx'

const props = defineProps({
  modelValue: {
    type: Array,
    default: [],
  },
})
const mv = ref(props.modelValue)
const {emit} = getCurrentInstance()
watch(() => props.modelValue, () => {
  mv.value = props.modelValue
})

// 文件列表,在上次第二个时删除第一个,该方式能解决覆盖不刷新问题
let fileList = ref([])

// 上传时读取表格
async function uploadHttp(file) {
  let dataBinary = await readFile(file.file)
  let workBook = read(dataBinary, {type: 'binary', cellDates: true})
  let workSheet = workBook.Sheets[workBook.SheetNames[0]]
  const data = utils.sheet_to_json(workSheet)
  emit('update:modelValue', data)
  // 保留最新的显示
  if (fileList.value.length > 1) {
    fileList.value.splice(0, 1)
  }
}

// 读取文件
const readFile = (file) => {
  return new Promise(resolve => {
    let reader = new FileReader()
    reader.readAsBinaryString(file)
    reader.onload = ev => {
      resolve(ev.target.result)
    }
  })
}
</script>

<style scoped>

</style>

使用方式:

<excelAnalysis v-model="importData.req.data"></excelAnalysis>

// 此时的数据格式为: [{"表格名":"值"}]

数据导出为Excel

import {utils, writeFile} from 'xlsx'

/**
 * 表格数据导出
 */
function excelExport(data, name) {
  // 要输出的数据,格式:对象中的key将会作为表头渲染,如:[{'姓名': '张三', '年龄': 20}]
  const new_sheet = utils.json_to_sheet(data)
  // 表格宽度
  new_sheet['!cols'] = [
    { wch: 10 },
    { wch: 10 },
    { wch: 10 },
    { wch: 20 },
    { wch: 15 },
    { wch: 20 },
    { wch: 10 },
    { wch: 20 },
    { wch: 20 },
    { wch: 20 },
    { wch: 20 },
    { wch: 20 },
    { wch: 20 },
  ]
  const new_book = utils.book_new()
  utils.book_append_sheet(new_book, new_sheet)
  writeFile(new_book, name + '.xlsx')
}