import * as xlsx from 'xlsx'

export type Column = {
  name: string
  prop: string
}

/**
 * 导出xlsx文件
 * @param title 文件名，不包含后缀
 * @param column 导出对象结构
 * @param data 导出数据
 * @param strongData 是否强数据，默认true，若数据空则返回错误
 */
export const exportExcel = (
  title: string,
  columns: Column[],
  data: any[] = [],
  strongData?: boolean
) => {
  return new Promise<void>((RES, REJ) => {
    try {
      if (columns.length <= 0) {
        REJ(Error('未设置表头'))
        return
      }
      if (strongData !== false && data.length === 0) {
        REJ(Error('无可导出数据'))
        return
      }
      const wb = xlsx.utils.book_new()
      wb.SheetNames.push('sheet')
      wb.Sheets.sheet = xlsx.utils.json_to_sheet(
        (data.length === 0 ? [{}] : data).map((item) => {
          const obj: any = {}
          columns.forEach((t) => {
            obj[t.name] = item[t.prop]
          })
          return obj
        })
      )
      xlsx.writeFile(wb, `${title}.xlsx`)
      RES()
    } catch (e: any) {
      REJ(e)
      throw e
    }
  })
}

/**
 * 导入excel，返回excel数据
 * @param file 文件
 * @param columns 数据结构
 * @returns Promise<any[]>
 */
export const importExcel = (file: File | undefined, columns: Column[]) => {
  return new Promise<any[]>((RES, REJ) => {
    if (file === undefined || file === null) {
      REJ(Error('文件不存在'))
      return
    }
    const reader = new FileReader()
    reader.readAsBinaryString(file)
    reader.onload = (ev: any) => {
      const workBook = xlsx.read(ev.target.result, { type: 'binary', cellDates: true, raw: false })
      const workSheet = workBook.Sheets[workBook.SheetNames[0]]
      const data: Array<any> = xlsx.utils.sheet_to_json(workSheet)
      const res = []
      for (let i = 0; i < data.length; i += 1) {
        const obj: any = {}
        columns.forEach((t) => {
          obj[t.prop] = data[i][t.name]
        })
        res.push(obj)
      }
      RES(res)
    }
    reader.onerror = (e) => {
      REJ(e)
    }
  })
}
