还在为Vue导出Excel而头疼?试试我这个组件!

还在为Vue导出Excel而头疼?试试我这个组件!

一、组件开发目的

重写 Element 的 el-button 组件,实现在点击按钮的同时,将需要导出的数据导出到Excel文件中。

二、组件开发依赖

  • exceljs:^4.3.0
  • file-saver:^2.0.5

三、组件代码

<!-- 该组件重写了el-button组件,支持el-button所有用法 -->
<!-- 1、增加了导出excel的功能:父组件通过传递book参数,将表格数据传递给本组件,由本组件负责导出为excel -->
<template>
  <button
    class="el-button"
    @click="handleClick"
    :disabled="buttonDisabled || loading"
    :autofocus="autofocus"
    :type="nativeType"
    :class="[
      type ? 'el-button--' + type : '',
      buttonSize ? 'el-button--' + buttonSize : '',
      {
        'is-disabled': buttonDisabled,
        'is-loading': loading,
        'is-plain': plain,
        'is-round': round,
        'is-circle': circle
      }
    ]"

  >

    <i class="el-icon-loading" v-if="loading"></i>
    <i :class="icon" v-if="icon && !loading"></i>
    <span v-if="$slots.default"><slot></slot></span>
  </button>
</template>
<script>
import resolveResponse from '@/util/response';
import ExcelJS from 'exceljs';
import FileSaver from 'file-saver';

export default {
  name'ExportToExcelButton',
  inject: {
    elForm: {
      default'',
    },
    elFormItem: {
      default'',
    },
  },
  props: {
    type: {
      typeString,
      default'default',
    },
    sizeString,
    icon: {
      typeString,
      default'',
    },
    nativeType: {
      typeString,
      default'button',
    },
    loadingBoolean,
    disabledBoolean,
    plainBoolean,
    autofocusBoolean,
    roundBoolean,
    circleBoolean,
    book: {
      typeObject,
      default() {
        return {
          fileName'',
          sheets: [
            {
              sheetName'',
              sheetData: [[], [], []],
            },
          ],
        };
      },
    },
  },
  computed: {
    // eslint-disable-next-line no-underscore-dangle
    _elFormItemSize() {
      return (this.elFormItem || {}).elFormItemSize;
    },
    buttonSize() {
      // eslint-disable-next-line no-underscore-dangle
      return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
    },
    buttonDisabled() {
      return this.disabled || (this.elForm || {}).disabled;
    },
  },
  data() {
    return {
      loadingFlagfalse,
      workbook: {},
    };
  },
  methods: {
    // el-button原生方法
    handleClick(evt) {
      this.$emit('click', evt); // 将click事件传给父组件
      this.exportToExcel(); // 导出excel
    },
    // excel导出相关方法
    exportToExcel() {
      // 1.创建工作簿
      this.createWorkBook();
      // 2.创建工作表
      const promise = [];
      this.book.sheets.forEach((sheet) => {
        promise.push(this.createWorkSheet(sheet.sheetName, sheet.sheetData));
      });
      Promise.all(promise);
      // 3.下载excel表格
      this.downloadExcel();
    },
    createWorkBook() {
      this.workbook = new ExcelJS.Workbook();
      this.workbook.created = new Date();
      this.workbook.modified = new Date();
      this.workbook.lastPrinted = new Date();
    },
    createWorkSheet(sheetName, sheetData) {
      const workSheet = this.workbook.addWorksheet(sheetName);
      workSheet.addRows(sheetData);
    },
    downloadExcel() {
      this.workbook.xlsx.writeBuffer()
        .then((buffer) => {
          FileSaver.saveAs(new Blob([buffer]), `${this.book.fileName}_${Date.now()}.xlsx`);
        })
        .catch((err) => {
          this.$message.error(`excel导出失败,原因为:${err}`);
        });
    },
  },
};
</script>

四、组件使用方法

  • 在vue项目里导入exceljs和file-saver相关依赖。
  • 新建一个名为ExportToExcelButton的vue文件,把第三部分的代码复制进去。
  • 在父组件里注册ExportToExcelButton组件,并把需要导出的数据通过ExportToExcelButton组件的book参数传给ExportToExcelButton组件。
  • 由于是重写的el-buton组件,所以ExportToExcelButton组件支持el-button组件的所有方法,且不需要element-ui依赖。el-button组件的用法可以参考:官方文档(https://element.eleme.cn/#/zh-CN/component/button)
  • 使用Demo:
<template>
  <export-to-excel-button
    type="primary"
    :book="book"
  >

    Demo
  </export-to-excel-button>
</template>

<script>
import ExportToExcelButton from '@/components/button/ExportToExcelButton.vue';

export default {
  name'Demo',
  components: { ExportToExcelButton },
  data() {
    return {
      book: {
        fileName'Demo',
        sheets: [
          {
            sheetName'sheet1',
            sheetData: [
              ['A1'],
              ['A2''B2'],
              ['A3''B3''C3'],
            ],
          },
          {
            sheetName'sheet2',
            sheetData: [
              ['A1''B1''C1'],
              ['A2''B2'],
              ['A3'],
            ],
          },
        ],
      },
    };
  },
};
</script>

<style scoped>

</style>

五、不足之处

目前组件还不支持富文本和图片,有兴趣的可以根据ExcelJS官网教程(https://gitcode.net/mirrors/exceljs/exceljs/-/blob/master/README_zh.md?from_codechina=yes),自行封装。

文章出自:https://juejin.cn/post/7085190593046904846

作者:达娃里氏


原文始发于微信公众号(前端24):还在为Vue导出Excel而头疼?试试我这个组件!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/51248.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!