angular下载文件

1、window.open()打开新页面下载文件
window.open(`url`, '_self')
优点:最简洁;

缺点:当参数错误时,或其它原因导致接口请求失败,这时页面会停留在新打开的页面中,无法监听到接口返回的错误信息,只在页面中直接输出错误,尽量不适用此方法下载文件

2、a标签打开新页面下载文件
export const exportFile = (url, fileName) => {
  const link = document.createElement('a')
  const body = document.querySelector('body')
 
  link.href = url
  link.download = fileName
 
  // fix Firefox
  link.style.display = 'none'
  body.appendChild(link)
 
  link.click()
  body.removeChild(link)
}
通过a标签下载的方式,同window.open()是一样的

优点:可以自定义下载后的文件名,a标签里有download属性可以自定义文件名。

缺点:同window.open()方式一样,无法监听错误信息。

问题:以上两种方式,当在下载 mp3、mp4、flv等格式时,浏览器会直接播放该文件,而达不到直接下载的功能,此时,当下载音视频文件时无法使用以上两种方式。

3、通过文件流的方式下载
为了解决 mp3、mp4、flv 等文件下载所带来的问题,通过ajax请求返回Blob对象,或者ArrayBuffer对象。

(1)、获取文件

通过原生ajax请求,返回Blob对象

const getBlobFile = (url) => {
  return new Promise((resolve) => {
    const xhr = new XMLHttpRequest()
 
    xhr.open('GET', url, true)
    xhr.responseType = 'blob'
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.response)
      }
    }
 
    xhr.send()
  })
}
也可以通过axios返回ArrayBuffer对象,同等作用

import axios from 'axios'
const getFileFile = url => {
    return new Promise((resolve, reject) => {
        axios({
            method:'get',
            url,
            responseType: 'arraybuffer'
        }).then(data => {
            resolve(data.data)
        }).catch(error => {
            reject(error.toString())
        })
    })
}
 

ArrayBuffer(又称类型化数组)

ArrayBuffer对象用来表示通用的、固定长度的原始二进制数据缓冲区。

ArrayBuffer 不能直接操作,而是要通过类型数组对象或 DataView 对象来操作,它们会将缓冲区中的数据表示为特定的格式,并通过这些格式来读写缓冲区的内容。

Blob(Binary Large Object): 二进制大数据对象

Blob 对象表示一个不可变、原始数据的类文件对象。Blob 表示的不一定是JavaScript原生格式的数据。File 接口基于Blob,继承了 blob 的功能并将其扩展使其支持用户系统上的文件。

注:

如果下载文件是文本类型的(如: .txt, .js之类的), 那么用responseType: 'text'也可以, 但是如果下载的文件是图片, 视频之类的, 就得用arraybuffer或blob,

(2)、保存文件

当获取到文件后,这时需要保存文件

const saveAsFile = (blob, filename) => {
  if (window.navigator.msSaveOrOpenBlob) {
      navigator.msSaveBlob(blob, filename)
  }
 else {
    const link = document.createElement('a')
    const body = document.querySelector('body')
 
    link.href = window.URL.createObjectURL(blob) // 创建对象url
    link.download = filename
 
    // fix Firefox
    link.style.display = 'none'
    body.appendChild(link)
 
    link.click()
    body.removeChild(link)
 
    window.URL.revokeObjectURL(link.href) // 通过调用 URL.createObjectURL() 创建的 URL 对象
  }
}
 

为了解决IE(ie10 - 11)和Edge无法打开Blob URL链接的方法,

微软自己有一套方法  window.navigator.msSaveOrOpenBlob(blob, filename),打开并保存文件。

以上代码做了简单的兼容,navigator.msSaveBlob(blob, filename)是直接保存。注意,此为非标准功能,详情请查看相关文档。

贴上完整代码

const getFileBlob = (url) => {
  return new Promise((resolve) => {
    const xhr = new XMLHttpRequest()
 
    xhr.open('GET', url, true)
    xhr.responseType = 'blob'
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.response)
      }
    }
 
    xhr.send()
  })
}
 
const saveAsFile = (blob, filename) => {
  if (window.navigator.msSaveOrOpenBlob) {
      navigator.msSaveBlob(blob, filename)
  } 
  else {
    const link = document.createElement('a')
    const body = document.querySelector('body')
 
    link.href = window.URL.createObjectURL(blob) // 创建对象url
    link.download = filename
 
    // fix Firefox
    link.style.display = 'none'
    body.appendChild(link)
 
    link.click()
    body.removeChild(link)
 
    window.URL.revokeObjectURL(link.href) // 通过调用 URL.createObjectURL() 创建的 URL 对象
  }
}
 
 
export const downloadFile = (url, filename = '测试文件') => {
  getFileBlob (url).then((blob) => {
      saveAsFile(blob, filename)
  })
}
 
4、如何实现批量下载,且打包文件
在第3点的基础上,如果要实现批量下载,那能做到的只是连续多次调用download方法,这样无法批量集中的下载文件。这个时候就需要能够对已获取到的文件流,进行一个打包的操作,然后一次下载完毕。

这时,需要用到两个库jszip 和 file-saver

完整的思路,通过ajax获取文件,然后用 jszip 压缩文件, 再用 file-saver 生成文件

(1)、获取文件

通过原生的ajax获取和axios两种方式,上方有代码,不再赘述

(2)、打包文件

export const downloadFile = () => {
  const urls = ['url', 'url']   //下载路径
  const zip = new JSZip()
  const cache = {}
  const promises = []
  urls.forEach((item) => {
    const promise = getFileBlob(item)
    .then((data) => { // 下载文件, 并存成ArrayBuffer对象
      zip.file('下载文件名', data, { binary: true }) // 逐个添加文件
      cache[item.fileName] = data
    })
    promises.push(promise)
  })
 
  Promise
    .all(promises)
    .then(() => {
        zip.generateAsync({ type: 'blob' })
        .then((content) => { // 生成二进制流
            FileSaver.saveAsFile(content, `打包下载.zip`) // 利用file-saver保存文件
        })
  })
}
 

贴上完整代码

/**
 * 获取文件
 * @param url
 * @returns {Promise<any>}
 */
const getFileBlob = (url) => {
  return new Promise((resolve) => {
    const xhr = new XMLHttpRequest()
 
    xhr.open('GET', url, true)
    xhr.responseType = 'blob'
    xhr.onload = () => {
        if (xhr.status === 200) {
            resolve(xhr.response)
        }
    }
 
    xhr.send()
  })
}
 
/**
 * 批量打包zip包下载
 * @param urlArr Array [{url: 下载文件的路径, fileName: 下载文件名称}]
 * @param filename zip文件名
 */
export const downloadFile = (urlArr, filename = '打包下载') => {
  if (!urlArr.length > 0) return
  const zip = new JSZip()
  const cache = {}
  const promises = []
  urlArr.forEach((item) => {
      const promise = getFileBlob(item.url)
          .then((data) => {                                   // 下载文件, 并存成ArrayBuffer对象
              zip.file(item.fileName, data, { binary: true }) // 逐个添加文件
              cache[item.fileName] = data
          })
      promises.push(promise)
  })
 
  Promise
    .all(promises)
    .then(() => {
        zip.generateAsync({ type: 'blob' })
        .then((content) => {                                 // 生成二进制流
            FileSaver.saveAsFile(content, `${filename}.zip`) // 利用file-saver保存文件
        })
  })
}
 
————————————————
版权声明:本文为CSDN博主「极地雪狼li」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xuehu837769474/article/details/108824134

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Angular 中,你可以使用 `HttpClient` 模块来下载文件。下面是一个简单的示例代码: ```typescript import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-download', templateUrl: './download.component.html', styleUrls: ['./download.component.css'] }) export class DownloadComponent { constructor(private http: HttpClient) {} downloadFile() { const url = 'http://example.com/file.pdf'; // 替换为你要下载文件地址 this.http.get(url, { responseType: 'blob' }) .subscribe((blob: Blob) => { const downloadUrl = URL.createObjectURL(blob); const link = document.createElement('a'); link.href = downloadUrl; link.download = 'file.pdf'; // 替换为你希望保存的文件名 link.click(); URL.revokeObjectURL(downloadUrl); }); } } ``` 在这个示例中,我们使用 `HttpClient` 发起一个 GET 请求,指定 `responseType` 为 `'blob'`,以获取文件的二进制数据。然后,我们创建一个链接元素 `<a>`,设置其 `href` 属性为文件数据的 URL,设置 `download` 属性为你希望保存的文件名,并触发点击事件以触发下载。最后,我们使用 `URL.revokeObjectURL()` 来释放 URL 对象。 请注意,为了使上述代码正常工作,你需要在应用的模块中导入 `HttpClientModule`: ```typescript import { HttpClientModule } from '@angular/common/http'; @NgModule({ imports: [ // ... HttpClientModule ], // ... }) export class AppModule { } ``` 这样,当用户点击一个按钮或执行某个操作时,你可以调用 `downloadFile()` 方法来下载文件。记得将 `url` 替换为你要下载文件地址,并设置合适的文件名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值