vue2项目实现excel文件导入导出和拖拽上传

13 篇文章 0 订阅


文件导入导出实现逻辑图:
在这里插入图片描述

一、excle文件导出

在这里插入图片描述

  • 导出员工接口返回的是二进制流
  • axios配置responseType为blob接收二进制流文件为Blob格式
  • 安装file-saver包,实现下载Blob文件 yarn add file-saver
  • 封装导出员工excel的API-代码位置
//excel模板下载接口
export function exportTemplate(){
	return request({
		url:/cms/userSession/enterprise/enterpriseConfigImportTemplate",
		method:'post',
		responseType:'blob',// 改变接收数据的类型,使用blob接收二进制文件流
	})
}
  • 拦截器判断是不是blob类型,如果是直接返回数据,不再进行解构-代码位置(src/utils/request.js)
// 响应拦截器
service.interceptors.response.use((response) => {
  // axios默认包裹了data
  // 判断是不是Blob
  if (response.data instanceof Blob) return response.data // 返回了Blob对象
  const { data, message, success } = response.data // 默认json格式
  if (success) {
    return data
  } else {
    Message({ type: 'error', message })
    return Promise.reject(new Error(message))
  }
},
  • 安装file-saver
$ npm i file-saver
$ yarn add file-saver
  • 点击“下载模版”按钮调用接口,使用file-saver将blob转化成文件下载-代码位置
// 员工下载模版-----------------------
    async downloadEmployee() {
      const blob = await downloadEmployee()
      FileSaver.saveAs(blob, '员工表模版.xlsx')
    },

二、excel文件导入

实现逻辑:

  1. 点击上传按钮,用refs触发type=“file” 的input文件选择事件;input文件选择框隐藏;
  2. 将input上传的文件参数加入到formData中,调取接口传参;
  3. 通知父组件跟新页面,关闭弹框,提示上传成功
  4. 清空input的value值,不然下次无法上传

三、文件拖拽上传

实现逻辑:

  1. 在需要拖动的dom节点上添加以下属性和事件
  2. 然后获取拖拽的文件
  3. 调取封装的上传的方法

@dragover.prevent // 防止事件冒泡
@drop=“handleDrop”

四、完整代码

<template>
  <el-dialog
    width="500px"
    title="员工导入"
    :visible="showExcelDialog"
    @close="$emit('update:showExcelDialog', false)"
  >
    <el-row type="flex" justify="center">
      <div class="upload-excel">
        <input
          ref="excel-upload-input"
          class="excel-upload-input"
          type="file"
          accept=".xlsx, .xls"
          @change="selectFile"
        >
        <div
          class="drop"
          @dragover.prevent
          @drop="handleDrop"
        >
          <i class="el-icon-upload" />
          <el-button type="text" @click="downloadEmployee">下载导入模板</el-button>
          <span>将文件拖到此处或
            <el-button type="text" @click="uploadExcel">点击上传</el-button>
          </span>
        </div>
      </div>
    </el-row>
    <el-row type="flex" justify="end">
      <!-- update:props属性名,值 直接修改 .sync修饰符的属性值 -->
      <el-button size="mini" type="primary" @click="$emit('update:showExcelDialog', false)">取消</el-button>
    </el-row>
  </el-dialog>
</template>
<script>
import { downloadEmployee, UploadExcel } from '@/api/employee'
import FileSaver from 'file-saver'

export default {
  props: {
    showExcelDialog: {
      type: Boolean,
      default: true
    }
  },
  methods: {
    // 员工下载模版-----------------------
    async downloadEmployee() {
      const blob = await downloadEmployee()
      console.log(1111, blob)
      FileSaver.saveAs(blob, '员工表模版.xlsx')
    },
    // 上传excel文件--------------------------
    uploadExcel() {
      this.$refs['excel-upload-input'].click()
    },
    // 点击文件选择-------------------------------
    selectFile(e) {
      // 获取选择的文件列表
      const files = e.target.files
      if (files.length > 0) {
        this.uploadFiles(files[0])
      }
      // 判断是否选择了文件,上传第一个文件
      // if (files.length > 0) {
      //   const fd = new FormData()
      //   fd.append('file', files[0])
      //   try {
      //     await UploadExcel(fd)
      //     // 通知父组件
      //     this.$emit('uploadSuccess')
      //     this.$emit('update:showExcelDialog', false)
      //     this.$message.success('上传成功')
      //   } catch (error) {
      //     // 清空文件选择器
      //   //   this.$refs['excel-upload-input'].value = ''
      //   } finally {
      //     // 无论成功还是失败都会来到这里执行清空选择器
      //     this.$refs['excel-upload-input'].value = ''
      //   }
      // }
    },
    // 选择了文件后上传的方法,两处都用到了,所以封装了方法
    async uploadFiles(file) {
      const fd = new FormData()
      fd.append('file', file)
      try {
        await UploadExcel(fd)
        // 通知父组件
        this.$emit('uploadSuccess')
        this.$emit('update:showExcelDialog', false)
        this.$message.success('上传成功')
      } catch (error) {
        // 清空文件选择器
        //   this.$refs['excel-upload-input'].value = ''
      } finally {
        // 无论成功还是失败都会来到这里执行清空选择器
        this.$refs['excel-upload-input'].value = ''
      }
    },
    // 拖拽文件选择
    handleDrop(event) {
      event.preventDefault()
      const files = event.dataTransfer.files
      if (files.length > 0) {
        this.uploadFiles(files[0])
      }
    }
  }
}
</script>

<style scoped lang="scss">
    .upload-excel {
      display: flex;
      justify-content: center;
      margin: 20px;
      width: 360px;
      height: 180px;
      align-items: center;
      color: #697086;
      .excel-upload-input {
        display: none;
        z-index: -9999;
      }
      .btn-upload,
      .drop {
        border: 1px dashed #dcdfe6;
        width: 100%;
        height: 100%;
        text-align: center;
        line-height: 160px;
        border-radius: 8px;
        display: flex;
        flex-direction: column;
        justify-content: center;
      }
      .drop {
        line-height: 40px;
        color: #bbb;
        i {
          font-size: 60px;
          display: block;
          color: #c0c4cc;
        }
      }
    }
</style>

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
很抱歉,我之前的回答有误,x-data-spreadsheet是基于JavaScript的电子表格库,而不是Vue组件。 以下是一个使用x-data-spreadsheet库实现Excel文件导入导出和可编辑单元格样式的示例代码: HTML模板代码: ``` <template> <div> <button @click="exportExcel">导出Excel文件</button> <input type="file" ref="file" style="display:none" @change="importExcel" /> <button @click="() => { this.$refs.file.click() }">导入Excel文件</button> <div ref="spreadsheet"></div> </div> </template> ``` JS代码: ``` <script> import Spreadsheet from 'x-data-spreadsheet' import 'x-data-spreadsheet/dist/xspreadsheet.css' export default { mounted() { const el = this.$refs.spreadsheet const options = { data: [], columns: [ { title: '姓名', field: 'name', width: 120 }, { title: '年龄', field: 'age', width: 80 }, { title: '性别', field: 'gender', width: 80 }, ], style: { bgcolor: '#f1f1f1', align: 'center', valign: 'middle', textwrap: true }, row: { len: 20, height: 30 } } this.spreadsheet = new Spreadsheet(el, options) }, methods: { async exportExcel() { const data = this.spreadsheet.getData() const blob = new Blob([data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }) const url = URL.createObjectURL(blob) const link = document.createElement('a') link.href = url link.download = 'excel.xlsx' link.click() }, async importExcel() { const file = this.$refs.file.files[0] const reader = new FileReader() reader.onload = async (event) => { const data = event.target.result const { arrayBuffer } = await import('xlsx') const workbook = arrayBuffer(data) const worksheet = workbook.Sheets[workbook.SheetNames[0]] const sheetData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }) const headerRow = sheetData[0] const tableData = [] for (let i = 1; i < sheetData.length; i++) { const rowData = {} for (let j = 0; j < headerRow.length; j++) { const key = headerRow[j] rowData[key] = sheetData[i][j] } tableData.push(rowData) } this.spreadsheet.loadData(tableData) } reader.readAsArrayBuffer(file) } } } </script> ``` 这个示例中,我们使用了x-data-spreadsheet库来渲染一个电子表格。在mounted钩子函数中,我们创建了一个Spreadsheet对象,并将其挂载到了页面上的一个div元素上。我们指定了表格的数据、列定义、单元格样式和行高等选项。 导出Excel文件的方法是通过调用Spreadsheet对象的getData方法获取表格的数据,然后使用Blob对象将数据转换为Excel文件格式,并创建一个a标签下载文件导入Excel文件的方法是通过一个input元素来获取用户选择的文件,然后使用FileReader对象将文件读取为ArrayBuffer二进制格式。接下来,我们使用xlsx库解析文件数据,获取到表格数据后,我们将其转换为x-data-spreadsheet库所需的数据格式,并使用Spreadsheet对象的loadData方法加载数据。 希望这个示例能够对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值