前端文件下载多方式集合

基于vue+element UI框架

javascript 复制代码
// @ts-ignore
import axios from "axios";
import { ElMessage } from "element-plus";
import webConfig from "@/config";

class FileDownload {
  /**
   * 文件流下载
   *  @param url string 下载地址
   *  @param params object 请求参数
   *  @param fileName string 文件名
   * @param method
   */
  // eslint-disable-next-line @typescript-eslint/ban-types
  static streamDownLoad(url: string, params: object, fileName: string, method = "GET"): void {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    return axios({
      url: url,
      params,
      data: params,
      method,
      headers: {
        "X-Access-Token": window.lxLocalStorage.getItem("token"),
        token: window.lxLocalStorage.getItem("token"),
      },
      responseType: "blob",
    })
      .then(async (res: { data: any }) => {
        console.log(res);
        // @ts-ignore
        const contentDispositio = res.headers["content-disposition"];
        if (contentDispositio) {
          const f = contentDispositio.match(/filename=.+/gi, "$0");
          if (f && f.length) {
            fileName = window.decodeURI(f[0].replace(/filename=/gi, ""));
          }
        }
        const fileBlob = res.data;
        const fileType = fileBlob.type;
        if (fileType === "application/json") {
          const text = await fileBlob.text();
          const jsonText = JSON.parse(text);
          // @ts-ignore
          ElMessage.error(`文件下载失败:${jsonText?.message}`);
        } else if (fileBlob instanceof Blob) {
          const blob = new Blob([fileBlob]);
          const downloadElement = document.createElement("a");
          const href = window.URL.createObjectURL(blob);
          downloadElement.href = href;
          downloadElement.download = fileName;
          document.body.appendChild(downloadElement);
          downloadElement.click();
          document.body.removeChild(downloadElement);
          window.URL.revokeObjectURL(href);
        }
      })
      .catch((err: Error) => {
        // @ts-ignore
        ElMessage.error(`文件下载失败:${err.message}`);
      });
  }

  /**
   * 直接通过 a 标签下载文件 最好不要用这种方式 缺少一定的安全验证
   */
  static aDownLoad(url: string, fileName: string): void {
    const link = document.createElement("a");
    link.style.display = "none";
    link.href = `${webConfig.fileServer}/file/file/download?url=${url}&fileName=${fileName}`;
    link.download = fileName || "无标题文件";
    link.setAttribute("target", "_blank");
    link.click();
    link.remove();
  }
  /**
   * base64下载
   */
  static base64DownLoad(content: string, fileName: string, suffix: string): void {
    const DOWNLOAD_TYPE_MAP: any = {
      xls: "application/vnd.ms-excel",
      xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
      doc: "application/msword",
      docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
      pdf: "application/pdf",
    };
    const prefix = "data:" + DOWNLOAD_TYPE_MAP[suffix] + ";base64,";
    const url = prefix + content;
    const name = `${fileName}.${suffix}`;
    const link = document.createElement("a");
    link.style.display = "none";
    link.href = url;
    link.setAttribute("download", name);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }

  /**
   * 导出文件
   * @param api
   * @param params
   */
  static exportFile(api: string, params?: any) {
    let api_url = api;
    if (params) {
      api_url = `${api_url}?${Object.keys(params)
        .map(k => k + "=" + encodeURIComponent(params[k] != null ? params[k] : ""))
        .join("&")}`;
    }
    console.log(api_url);
    window.open(api_url);
  }
}

export default FileDownload;

技术交流+V: bloxed

相关推荐
龙在天几秒前
ts中的函数重载
前端
卓伊凡15 分钟前
非常经典的Android开发问题-mipmap图标目录和drawable图标目录的区别和适用场景实战举例-优雅草卓伊凡
前端
前端Hardy16 分钟前
HTML&CSS: 谁懂啊!用代码 “擦去”图片雾气
前端·javascript·css
前端Hardy18 分钟前
HTML&CSS:好精致的导航栏
前端·javascript·css
天下无贼29 分钟前
【手写组件】 Vue3 + Uniapp 手写一个高颜值日历组件(含跨月补全+今日高亮+选中状态)
前端·vue.js
我是天龙_绍31 分钟前
🔹🔹🔹 vue 通信方式 eventBus
前端
一个不爱写代码的瘦子1 小时前
迭代器和生成器
前端·javascript
拳打南山敬老院1 小时前
漫谈 MCP 构建之概念篇
前端·后端·aigc
前端老鹰1 小时前
HTML <output> 标签:原生表单结果展示容器,自动关联输入值
前端·html
OpenTiny社区1 小时前
OpenTiny NEXT 内核新生:生成式UI × MCP,重塑前端交互新范式!
前端·开源·agent