index.vue 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. <script lang="ts" setup>/**
  2. * @Name: index.vue
  3. * @Description: 文件下载组件
  4. * @Author: Cheney
  5. */
  6. import dayjs from 'dayjs';
  7. import { type ButtonProps, ElMessage } from 'element-plus';
  8. const props = defineProps<Partial<Omit<ButtonProps, 'loading'>>>();
  9. const attrs = useAttrs() as any;
  10. const loading = ref(false);
  11. async function handleDownload() {
  12. loading.value = true;
  13. try {
  14. const response = await attrs.api(attrs.query);
  15. const blob = new Blob([ response.data ], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
  16. // 创建一个临时 URL
  17. const url = window.URL.createObjectURL(blob);
  18. // 创建一个临时的 <a> 元素并触发下载
  19. const link = document.createElement('a');
  20. link.href = url;
  21. // 设置文件名
  22. const currentTime = dayjs().format('YYYY-MM-DD_HH_mm_ss');
  23. const filename = `${ currentTime }.xlsx`;
  24. link.setAttribute('download', filename);
  25. // 添加到 body, 触发点击, 然后移除
  26. document.body.appendChild(link);
  27. link.click();
  28. document.body.removeChild(link);
  29. // 释放 URL 对象
  30. window.URL.revokeObjectURL(url);
  31. if (response.code === 2000) ElMessage.success('文件下载成功');
  32. } catch (error) {
  33. console.error('==Error==:', error);
  34. ElMessage.error('文件下载失败,请重试');
  35. } finally {
  36. loading.value = false;
  37. }
  38. }
  39. </script>
  40. <template>
  41. <el-button :loading="loading" v-bind="props" @click="handleDownload">
  42. <slot></slot>
  43. </el-button>
  44. </template>
  45. <style scoped>
  46. </style>