index.vue 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. <template>
  2. <el-button type="primary" @click="exportToExcel">
  3. <img src="@/assets/imgs/OA/open.png" class="mr-8px" alt="" />
  4. 导出
  5. </el-button>
  6. </template>
  7. <script setup lang="ts">
  8. /**
  9. * @description 导出为excel
  10. */
  11. import * as XLSX from 'xlsx'
  12. import { saveAs } from 'file-saver'
  13. interface IProp {
  14. data: any[][] // 数据 [[表头,表头,表头],[数据,数据,数据]]
  15. fileName?: string // 文件名
  16. mergeRanges?: {
  17. s: { r: number; c: number } // 合并的起始单元格
  18. e: { r: number; c: number } // 合并的结束单元格
  19. }[] // 合并单元格列表
  20. colsWidth?: { wch: number }[] // 列宽
  21. }
  22. // 定义组件props
  23. const props = defineProps<IProp>()
  24. // 导出Excel函数
  25. const exportToExcel = () => {
  26. // 从props获取数据
  27. const data = props.data
  28. // 创建一个工作簿
  29. const wb = XLSX.utils.book_new()
  30. // 创建一个工作表
  31. const ws = XLSX.utils.aoa_to_sheet(data)
  32. // 合并表头的单元格,定义多个合并范围
  33. ws['!merges'] = props.mergeRanges ?? []
  34. // 设置列宽,定义多个列宽
  35. ws['!cols'] = props.colsWidth ?? []
  36. // 将工作表添加到工作簿中
  37. XLSX.utils.book_append_sheet(wb, ws, 'Sheet1')
  38. // 生成Excel文件
  39. const wbout = XLSX.write(wb, { type: 'binary', bookType: 'xlsx' })
  40. // 下载Excel文件
  41. saveAs(
  42. new Blob([s2ab(wbout)], { type: 'application/octet-stream' }),
  43. props.fileName || 'exported_data.xlsx'
  44. )
  45. }
  46. // 将二进制字符串转换为字节数组
  47. const s2ab = (s: string) => {
  48. const buf = new ArrayBuffer(s.length)
  49. const view = new Uint8Array(buf)
  50. for (let i = 0; i < s.length; i++) view[i] = s.charCodeAt(i) & 0xff
  51. return buf
  52. }
  53. </script>
  54. <style scoped></style>