<template>
  <el-button @click="onDownload" v-loading="props.exportInfo.loading" :disabled="props.exportInfo.disabled"
    ><el-icon><Download /></el-icon><span>导出</span>
  </el-button>

  <section class="sheets-wrapper">
    <el-table v-for="(sheet, i) in props.exportSheets.filter(item => item.data.length > 0)" :key="i" :data="sheet.data">
      <el-table-column align="center" :label="sheet.title">
        <el-table-column label="序号" type="index" align="center" width="55" v-if="sheet.index" />
        <el-table-column :prop="item.prop" :label="item.title" v-for="(item, j) in sheet.column" :key="j">
          <template #default="scope">
            <span v-if="item.slot">
              <template v-if="item.prop === 'sblx'">
                <dict-tag :options="props.ditData.D_TB_JCYWLX" :value="scope.row[item.prop]" :tag="false" />
              </template>
              <template v-if="item.prop === 'changeType'">
                <dict-tag :options="props.ditData.D_TB_BGLB" :value="scope.row[item.prop]" :tag="false" />
              </template>
              <template v-if="item.prop === 'hazardousfactors'">
                {{ getLabels(scope.row[item.prop]) }}
              </template>
              <template v-if="item.prop === 'state'">
                <dict-tag
                  v-if="scope.row[item.prop]"
                  :options="props.ditData.D_BZ_SYZT"
                  :value="scope.row[item.prop]"
                  :tag="false"
                  :color="scope.row[item.prop] == '01' ? 'green' : 'red'"
                />
                <span v-else>无</span>
              </template>
              <template v-if="item.prop === 'blockingDeviceFlag'">
                {{ scope.row[item.prop] == "true" ? "是" : "否" }}
              </template>
              <template v-if="['coveraera', 'buildaera'].includes(item.prop)">
                <span v-if="scope.row[item.prop]">{{ scope.row[item.prop] }}/㎡</span>
                <span v-else>无</span>
              </template>
              <template v-if="item.prop === 'status'">
                <dict-tag v-if="scope.row[item.prop]" :options="props.ditData.D_BZ_SGZT" :value="scope.row[item.prop]" :tag="false" />
                <span v-else>无</span>
              </template>
            </span>
            <span v-else>{{ scope.row[item.prop] }}</span>
          </template>
        </el-table-column>
      </el-table-column>
    </el-table>
  </section>
</template>

<script setup>
import { nextTick, watch } from "vue"
import FileSaver from "file-saver"
import * as XLSX from "xlsx"
import * as XLSXStyle from "xlsx-style"
const emit = defineEmits(["getSheets"])

const props = defineProps({
  exportSheets: Object,
  exportInfo: Object,
  ditData: Object
})
const onExport = () => {
  nextTick(() => {
    var xlsxParam = {
      raw: true,
      styles: true
    }
    let _arr = props.exportSheets.filter(item => item.data.length > 0)
    let workbook = XLSX.utils.book_new()
    document.querySelectorAll(".sheets-wrapper .el-table").forEach((dom, i) => {
      let ws = XLSX.utils.table_to_sheet(dom, xlsxParam)
      setExcelStyle(ws)
      XLSX.utils.book_append_sheet(workbook, ws, _arr[i].name)
    })

    let wbout = XLSXStyle.write(workbook, {
      bookType: "xlsx",
      bookSST: true,
      type: "binary"
    })
    try {
      FileSaver.saveAs(
        new Blob([s2ab(wbout)], {
          type: 'application/octet-stream;charset=utf-8"'
        }),
        props.exportInfo.name + ".xlsx"
      )
    } catch (e) {
      if (typeof console !== "undefined") console.log(e, wbout)
    }
    return wbout
  })
}

const s2ab = s => {
  var buf = new ArrayBuffer(s.length)
  var view = new Uint8Array(buf)
  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff
  return buf
}

const setExcelStyle = ws => {
  let borderAll = {
    top: {
      style: "thin"
    },
    bottom: {
      style: "thin"
    },
    left: {
      style: "thin"
    },
    right: {
      style: "thin"
    }
  }

  // return ws
  for (let key in ws) {
    const itemWidth = []
    // 所有单元格列宽为15
    // itemWidth.push({ wch: 25 })
    if (key !== "!cols" && key !== "!ref" && key !== "!rows") {
      //https://blog.csdn.net/weixin_44945533/article/details/133994847
      if (ws[key] instanceof Object) {
        // console.log(ws[key])
        ws[key].s = {
          border: borderAll,
          alignment: {
            horizontal: "center",
            vertical: "center"
          },
          font: {
            sz: 11
          },
          bold: true,
          numFmt: 0
        }
      }
    }

    // ws["!cols"] = itemWidth // 列宽
  }

  let range = XLSX.utils.decode_range(ws["!ref"])
  let cWidth = []
  for (let C = range.s.c; C < range.e.c; ++C) {
    //SHEET列
    let len = 100 //默认列宽
    let len_max = 400 //最大列宽
    for (let R = range.s.r; R <= range.e.r; ++R) {
      //SHEET行
      let cell = { c: C, r: R } //二维 列行确定一个单元格
      let cell_ref = XLSX.utils.encode_cell(cell) //单元格 A1、A2
      // console.log('cell_ref', cell_ref)
      if (ws[cell_ref] && !cell_ref.includes("A")) {
        //动态自适应：计算列宽
        let va = JSON.parse(JSON.stringify(ws[cell_ref].v))
        var card1 = JSON.parse(JSON.stringify(va)).match(/[\u4e00-\u9fa5]/g) //匹配中文
        var card11 = ""
        if (card1) {
          card11 = card1.join("")
        }
        var card2 = JSON.parse(JSON.stringify(va)).replace(/([^\u0000-\u00FF])/g, "") //剔除中文
        let st = 0
        if (card11) {
          // st += card11.length * 16  //中文字节码长度
          st += card11.length * 20 //中文字节码长度
        }
        if (card2) {
          // st += card2.length * 8  //非中文字节码长度
          st += card2.length * 10 //非中文字节码长度
        }
        if (st > len) {
          len = st
        }
      }
    }
    if (len > len_max) {
      //最大宽度
      len = len_max
    }

    cWidth.push({ wpx: len }) //列宽
  }
  ws["!cols"] = cWidth

  // console.log(77, ws)

  return ws
}
const getLabels = keys => {
  if (!keys) return ""
  keys = keys.split(",")
  let res = []
  keys.forEach(key => {
    props.ditData.D_TB_ZYJK_WHYS.forEach(item => {
      if (item.value == key) {
        res.push(item.label)
      }
    })
  })

  return res.toString()
}
const onDownload = () => {
  emit("getSheets", onExport)
}
</script>

<style lang="scss" scoped>
.sheets-wrapper {
  opacity: 0;
  height: 0;
  width: 0;
  overflow: hidden;
}
</style>
