web 网页中不同文件格式的常见导出下载方法

下载文件方式

web网页中下载文件一般利用a标签的方式下载,下载依赖浏览器特性,我们一般是通过接口请求返回 URL 链接或者文件流。

a标签添加download属性就有了下载功能。

需要注意的是download不支持跨域请求。
使用download属性,不符合同源策略(下载的文件和你的网站不是在一个域名下),该属性可能会失效,文档、图片等一些可预览文件就触发了浏览器的预览功能,而不是下载。

URL链接下载

download属性可以不设置值,默认使用链接中的文件名

<a href="./anime-8788959_1280.jpg" download>点击下载</a>

或者给标签绑定点击事件,在 js 中创建 a 标签

const a = document.createElement('a'); 
a.href = './anime-8788959_1280.jpg'; 
a.download = 'test.jpg'; 
a.target = '_blank';
a.click(); 

文件流下载

需要后端接口配合,调用接口返回文件流,然后再利用a标签下载。

导出Excel

适用于接口返回文件流的情况

  • 定义导出方法
// utils.js
import axios from "axios";

/**
 * exportExcel Excel 表格导出
 * @param {string} url 请求地址
 * @param {object} params 请求参数
 * @param {string} exportFileName 导出文件名
 * @param {string} service 服务名
 */
export function exportExcel(url, params = {}, exportFileName = "导出数据", service = "_api_vehicle") {
  axios.get(url, {
    headers:{
      'Access-Control-Allow-Origin': '*'
    },
    params,
    responseType: 'blob'
  }).then(res => {
    if(res.data.type === 'application/json') { // 错误信息处理
      console.log(res.data.type)
      let reader = new FileReader()
      reader.onload = ()=> {
        let content = reader.result
        let description = JSON.parse(content).description // 错误信息
        // TODO 错误处理
        Vue.prototype.$Notice.warning({ title: '导出失败', desc: description });
      }
      reader.readAsText(res.data)
      return false
    }
	
	// 使用a标签下载
    const link = document.createElement('a')
    let fileName = ""
    let blob = new Blob([res.data], {type: 'application/vnd.ms-excel'})
    let url = window.URL.createObjectURL(blob)
    link.style.display = 'none'
    link.href = url

	// 判断响应头里如果返回的有文件名,如果有使用响应头中的文件名
    if (!res.headers["content-disposition"]) {
      fileName = exportFileName
    }else {
      fileName = res.headers["content-disposition"]
        .split(";")[1]
        .split("=")[1]; //filename名称截取
    }
    // 命名下载名称,文件名需要解码一下
    link.download = decodeURIComponent(fileName);
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)

	// 下载完成进行释放
    window.URL.revokeObjectURL(url);
  }).catch((err) => {
    console.log("导出失败", err)
  })
}
  • 使用
import { exportExcel } from "@/utils"

export default {
  // ...
  methods: {
    download() {
	  exportExcel("/download", {}, "导出文件")
    }
  }
}

URL.createObjectURL() 静态方法会创建一个 DOMString,其中包含一个表示参数中给出的对象的URL。这个 URL 的生命周期和创建它的窗口中的 document 绑定。这个新的URL 对象表示指定的 File 对象或 Blob 对象。
createObjectURL()支持传入 File 对象、Blob 对象或者 MediaSource 对象(媒体资源)。

下载 HTML

在网页打不开右键菜单时可以试试这个方法

参考:下载html

fetch('https://xxx/xxx.htm').then(
  response => response.blob()
).then(blob => { 
  const url = URL.createObjectURL(blob); 
  const a = document.createElement('a'); 
  a.style.display = 'none'; 
  a.href = url; 
  a.download = '文件名.html'; 
  document.body.appendChild(a); 
  a.click(); 
  setTimeout(() => { 
    document.body.removeChild(a); 
    window.URL.revokeObjectURL(url); 
    }, 100); 
  }
);

导出txt文件

适用于接口返回文件流的情景

// result.data 为接口返回的二进制文件流
const data = result.data;
const link = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
const urlObject = window.URL || window.webkitURL || window;
const exportBlob = new Blob([data]);

link.style.display = 'none'
link.href = urlObject.createObjectURL(exportBlob);
link.download = `导出文件.txt`; //命名下载名称
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
// 下载完成进行释放
urlObject.revokeObjectURL(url);

导出PDF

如果接口返回的文件流,下载方式和上面的类似;

如果是链接,并且网站和文件在同一个域名下,使用a标签方式下载;

如果下载的PDF文件跨域,又要求下载,最简单的是在HTML中使用a标签打开新标签页,使用 Edge 或 Chrome 浏览器,利用浏览器解析预览,在预览页是支持下载的。

<a class="u-pdf" href="http://www.doe.zju.edu.cn/_upload/article/files/a0/22/595bdc2b4ca28f90f51ca3b3ffc5/45c3e922-550f-45a2-8602-64b9c202b33e.pdf" target="_blank"></a>

表单下载

适用于链接下载,同样受同源策略影响,不同域名下执行的是预览。

const form = document.createElement("form")
form.method = "get"
form.action = 'http://www.doe.zju.edu.cn/_upload/article/files/a0/22/595bdc2b4ca28f90f51ca3b3ffc5/45c3e922-550f-45a2-8602-64b9c202b33e.pdf' // 链接地址

const input = document.createElement("input")
input.name = "token"
input.type = "hidden"
// input.value = sessionStorage["token"]

form.appendChild(input)
document.body.appendChild(form)
form.submit();
document.body.removeChild(form)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值