<!-- https://github.com/SheetJS/js-xlsx -->
<template>
  <th-dialog
    ref="dialog"
    class="th-export-excel"
    v-bind="dialogProps"
  >
    <div class="export-wrap">
      <span>文件名：</span>
      <el-input v-model="fileName" :placeholder="placeholder" />
      <el-select
        v-model="exportType"
        size="small"
      >
        <el-option
          v-for="option in options"
          :key="option.value"
          :label="option.label"
          :value="option.value">
        </el-option>
      </el-select>
      <el-button
        :loading="loading"
        type="primary"
        size="small"
        @click="handleExport">导出</el-button>
    </div>
  </th-dialog>
</template>
<script>
import XLSX from 'xlsx'

export default {
  name: 'ThExportExcel',
  props: {
    // 提示文件名
    placeholder: {
      type: String,
      default: '请输入'
    },
    // 文件后缀格式
    bookType: {
      type: String,
      default: 'xlsx'
      // xlsx,csv,txt,html
    },
    // 表格数据
    data: {
      type: Array,
      default: () => [
        // {
        //   id: 1,
        //   name: 'name'
        // }
      ]
    },
    // 表格列字段名
    columns: {
      type: Array,
      default: () => [
        // 'id',
        // 'name'
      ]
    },
    // 表格标题头
    captions: {
      type: Array,
      default: () => [
        // '编号',
        // '名称'
      ]
    },
    // 是否自动转换数据
    autoFilter: {
      type: Boolean,
      defalut: true
    },
    // 列宽
    width: {
      type: [Array, Number],
      default: 20
    },
    // 头高
    headHeight: {
      type: Number,
      default: 25
    },
    // 行高
    rowHeight: {
      type: Number,
      default: 50
    },
    // 导出全部记录时所有数据条数
    totalCount: {
      type: Number,
      default: 0
    }
  },
  data() {
    return {
      loading: false,
      dialogProps: {
        title: '导出选项',
        width: '600px',
        buttons: [],
        showCancelButton: false,
        props: {
          appendToBody: true
        }
      },
      options: [
        {
          value: 1,
          label: '当前记录'
        },
        {
          value: 2,
          label: '全部记录'
        }
      ],
      fileName: '',
      exportType: 1
    }
  },
  methods: {
    // 显示弹框
    showDialog() {
      this.$refs.dialog.showDialog()
    },
    // 点击导出
    handleExport() {
      switch (this.exportType) {
        case 2:
          this.exportExcelAll()
          break
        default:
          this.exportExcelCurrent()
          break
      }
    },
    // 导出当前页
    exportExcelCurrent() {
      this.loading = true
      this.exportExcel(this.data)
    },
    // 导出所有数据
    exportExcelAll() {
      if (this.totalCount > 2000) {
        this.$message.warning('最大请求数为2000条，请重新设置查询条件！')
        return
      }
      this.loading = true
      this.$emit('exportExcelAll', this.exportExcel)
    },
    // 导出Excel
    exportExcel(arr) {
      // 自动过滤数据
      const filter = function(obj) {
        const data = []
        this.columns.forEach(c => {
          data.push(obj[c] || '')
        })
        return data
      }
      let data = [
        this.captions
      ]
      if (this.autoFilter) {
        data = data.concat(arr.map(filter))
      } else {
        data = data.concat(arr)
      }

      // 生成sheet数据
      const ws = XLSX.utils.aoa_to_sheet(data)

      // 处理每列样式
      if (Array.isArray(this.width)) {
        ws['!cols'] = this.width.map(w => ({
          wch: w
        }))
      } else {
        ws['!cols'] = []
        for (let index = 0; index < this.captions.length; index++) {
          ws['!cols'].push({ wch: this.width || 20 })
        }
      }

      // 处理每行样式
      ws['!rows'] = []
      for (let index = 0; index <= arr.length; index++) {
        if (index === 0) {
          ws['!rows'].push({ hpx: this.headHeight })
        } else {
          ws['!rows'].push({ hpx: this.rowHeight })
        }
      }

      // 导出文件
      const wb = XLSX.utils.book_new()
      const fileName = this.fileName || this.placeholder || '导出文件'
      XLSX.utils.book_append_sheet(wb, ws, fileName)
      XLSX.writeFile(wb, fileName + '.' + this.bookType, {
        bookType: this.bookType,
        bookSST: false,
        cellStyles: true
      })
      this.loading = false
    }
  }
}
</script>
