vue2 下载excel文件的时候添加进度条

发布于:2025-05-01 ⋅ 阅读:(31) ⋅ 点赞:(0)

<template>
  <div class="download-wrap">
    <div class="download-dialog" v-if="visible">
      <div class="file-list">
        <div
          class="file-item"
          v-for="item in menuList.records"
          :key="item.taskId"
        >
          <img class="file-icon" src="../../../../public/img/excel-icon.png" />
          <div class="file-info">
            <div class="file-name">{{ item.fileName }}</div>
            <el-progress
              style="display: flex; align-items: center; height: 20px"
              class="file-progress"
              :percentage="item.progress"
              :status="item.progress === 100 ? 'success' : 'warning'"
            />
          </div>
          <div class="file-actions">
            <el-button
              type="text"
              icon="el-icon-download"
              size="mini"
              @click="handleDownload(item)"
              :loading="item.downloading"
              >下载</el-button
            >
            <el-button
              style="color: #f56c6c"
              type="text"
              icon="el-icon-delete"
              size="mini"
              @click="handleRemove(item)"
              >删除</el-button
            >
          </div>
        </div>
      </div>
      <el-link type="primary" @click="handleMore">查看更多</el-link>
    </div>
  </div>
</template>

<script>
import { fileTaskPage, fileDownloadTask } from "@/api/admin/user";
export default {
  data() {
    return {
      visible: false,
      menuList: {},
      serchFormf: {
        page: 1,
        pageSize: 5,
      },
    };
  },
  methods: {
    init() {
      this.visible = true;
      this.getList();
    },
    getList() {
      this.loading = true;
      fileTaskPage({
        pageSize: this.serchFormf.pageSize,
        pageNum: this.serchFormf.page,
      }).then((response) => {
        this.menuList = response.data.data;
        this.menuList.records.forEach((item) => {
          item.progress = item.progress || 0;
          item.downloading = false;
        });
        //console.log(this.menuList)
        this.loading = false;
      });
    },
    handleClose() {
      this.visible = false;
    },
    handleMore() {
      this.$emit("handleMore");
      this.handleClose();
    },
    handleDownload(file) {
      file.downloading = true;
      const simulateProgress = () => {
        file.progress += Math.floor(Math.random() * 5) + 1
        if (file.progress >= 99) return
        this.$forceUpdate() // 强制更新
        setTimeout(simulateProgress, 10)
      };
      simulateProgress();
      console.log('好像没到这里');
      
      //this.$emit('download', file)
      fileDownloadTask({ taskId: file.taskId })
        .then((res) => {
          // 实际下载完成处理
          const finishDownload = () => {
            file.progress = 100;
            file.downloading = false;
            this.$forceUpdate() // 强制更新

            // 原有下载逻辑
            const patt = /filename=(\S*)/;
            const contentDisposition = decodeURI(
              res.headers["content-disposition"]
            );
            const fileName = contentDisposition.match(patt)[1];
            const blob = new Blob([res.data]);

            const a = document.createElement("a");
            a.href = URL.createObjectURL(blob);
            a.download = fileName;
            a.click();
            URL.revokeObjectURL(a.href);
          };

          // 确保进度动画完成
          if (file.progress >= 95) {
            finishDownload();
          } else {
            setTimeout(finishDownload, 300);
          }
        })
        .catch(() => {
          file.downloading = false;
          file.progress = 0;
        });
    },
    handleRemove(file) {
      this.$emit("remove", file);
    },
  },
};
</script>

<style lang="scss" scoped>
.mask {
  position: absolute;
  z-index: 8;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.5);
}

.download-dialog {
  position: absolute;
  left: 0;
  top: 64px;
  z-index: 99;
  padding: 20px;
  background: #fff;
  border-radius: 10px;
}

.file-list {
  height: 340px;
}

.file-item {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
  height: 56px;
}

.file-icon {
  width: 30px;
  height: 30px;
  margin-right: 12px;
}

.file-info {
  flex: 1;
}

.file-name {
  width: 200px;
  font-size: 12px;
  margin-bottom: 4px;
  color: #333;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.file-progress {
  width: 100%;
}

.file-actions {
  margin-right: 10px;
  display: flex;
  gap: 8px;
}
</style>


网站公告

今日签到

点亮在社区的每一天
去签到