react、vue、js实现文件下载导出(iframe,form,a标签)

54 篇文章 3 订阅
34 篇文章 7 订阅

项目中用到下载导出功能实现:

 第一、二、三种方法是通用方法,vue\react\js都可以使用,当然也有react专用的(实际上是react的方法实现)。

一般都是从接口获取到文件地址,然后调用下面的方法即可,如果下载多个文件就只能循环调用了。

第一种方法iframe实现:

只需要传一个文件下载地址的url即可 

downloadFile = (url) => {//下载方法
    console.log(url)
    const iframe = document.createElement("iframe");
    iframe.style.display = "none"; // 防止影响页面
    iframe.style.height = 0; // 防止影响页面
    iframe.src = url;
    document.body.appendChild(iframe); // 这一行必须,iframe挂在到dom树上才会发请求
    // 5分钟之后删除(onload方法对于下载链接不起作用,就先抠脚一下吧)
    setTimeout(() => {
      iframe.remove();
    }, 5 * 60 * 1000);
  }

第二种方法a标签:

downloadFile = ((fileurl, filename) => { //fileurl文件地址(一般是接口返回) filename文件下载后的名字
        console.log("3333")
        var a = document.createElement('a');
        a.download = filename; //下载后文件名
        a.style.display = 'none';
        var blob = new Blob([fileurl]);  // 字符内容转变成blob地址 二进制地址
        a.href = URL.createObjectURL(blob);
        document.body.appendChild(a);
        a.click();                        // 触发点击
        document.body.removeChild(a);    // 然后移除

    });

文件名必须要和你下载得文件后缀名一致。要不然下载下来打不开。 

2023-05-31补充:

上面的方法有些问题,传了文件名会导致文件损毁。所以把filename去掉了

 const downloadFile = (fileurl,filename) => { //fileurl文件地址(一般是接口返回)
       const a = document.createElement("a");
       a.style.display = "none";
       a.href = fileurl;
       a.download = filename || ""; //需要把这行加上,告诉浏览器是下载行为 ,可以传空
       document.body.appendChild(a);
       a.click();
       document.body.removeChild(a);
   
    };

第三中方法form表单:

exportCallBack = (fileUrl) => {
        var bodyElement = document.body; //获取body
        var divElement = document.createElement("div"); //创建div
        var downloadUrl = fileUrl; //文件地址
        divElement.innerHTML = `<form action=${downloadUrl} method="post" id="formBox"></form>` //form标签
        bodyElement.appendChild(divElement); //追加到body
        document.getElementById("formBox").submit(); //自动提交表单
        bodyElement.removeChild(divElement); //移除form
    }

react里专用的方法(显得很鸡肋):

这个方法很麻烦,需要先引入

 import ReactDOM from "react-dom";

然后再项目中跟组件加上这一行或者在使用的组件,render里加上这一行

<div id="exportBoxBank"></div>

exportCallBack = (fileUrl) => {
        var divElement = document.getElementById('exportBoxBank'); //获取div  也可以用ref获取
        var downloadUrl = fileUrl; //文件地址
        ReactDOM.render(<form action={downloadUrl} method="post" id="formBox"></form>, divElement);
        document.getElementById("formBox").submit(); //自动提交表单
        ReactDOM.unmountComponentAtNode(divElement) //ReactDOM.unmountComponentAtNode()方法,参数为一个结点,调用方法会卸载该容器中的渲染
    }

大致的伪代码:

import React, { Component } from 'react';
import ReactDOM from "react-dom";

class Index9 extends Component {
    exportCallBack = (fileUrl) => {
        var divElement = document.getElementById('exportBoxBank'); //获取div  也可以用ref获取
        var downloadUrl = fileUrl; //文件地址
        ReactDOM.render(<form action={downloadUrl} method="post" id="formBox"></form>, divElement);
        document.getElementById("formBox").submit(); //自动提交表单
        ReactDOM.unmountComponentAtNode(divElement) //ReactDOM.unmountComponentAtNode()方法,参数为一个结点,调用方法会卸载该容器中的渲染
    }
    exportFile=()=>{//点击导出
      //一般都是先请求接口获取到文件地址然后调用事件(涉及跨域的使设置用代理解决)
      this.exportCallBack(url);
    }
    render() {
        return (
            <div>
                
                <button onClick={exportFile}>导出</button>
                {/* 放到末尾 */}
                <div id="exportBoxBank"></div> 
            </div>
        );
    }
}

export default Index9;

解决下载文件乱码和有空格问题(2023-10-17补充):

当下载的url路径中有 # 、空格、+等特殊字符时可以使用 js里的 encodeURIComponent 对有些参数进行编码。

比如:fileUrl="http://api/download?filename=aa#b" 

如果不加 encodeURIComponent 的话是无法下载的,需要处理一下:

fileUrl=`http://api/download?filename=${encodeURIComponent(aa#b)}` 

其实我还遇到了个问题就是如果我的 文件名有空格。下载的时候浏览器自动转换成了+号。、这个应该跟浏览器版本有关,新版本应该就没这个问题了。

不过空格被转换成+号,应该跟 浏览器版本有关

js编码、解码方法(escape,encodeURI,encodeURIComponent区别及用法)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

崽崽的谷雨

漫漫前端路,摸爬滚打

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值