js实现字符串/图片/excel文件下载

传统做法:后端存储或临时生成文件供前端下载

优势:权限控制、数据二次处理

缺点:额外发起请求,增加服务器压力,下载速度慢

前端js下载

背景:HTML5的标准发布,前端目前已经能够做到独自下载各种文件。

开始之前需要先了解三个API: BlobURLFileReader

Blob数据

Blob即 二进制类型数据大对象,一个不可变的原始数据的类文件对象。 上传文件时常用的 File对象也继承于Blob

新建Blob对象目前只能通过Blob构造函数创建

const json = { test: 'blob' }

const blob = new Blob([JSON.stringify(json)], { type: 'application/json' })

// blob对象只存在俩个只读属性
Blob {size: 15, type: 'application/json'}
1
2
3
4
5
6

URL对象

用以创建可供下载的URL对象。

// 静态方法
// 创建URL,此URL生命周期与创建它的document绑定。在document关闭时会自动释放。
const objectURL = URL.createObjectURL(blob)
// 销毁 URL.createObjectURL(blob)创建的URL
URL.revokeObjectURL(objectURL)
1
2
3
4
5

FileReader

读取Blob数据的唯一方法。

const reader = new FileReader()

reader.addEventListener('loadend', function() {
  // reader.result 文件的内容。该属性仅在读取操作完成后才有效,数据的格式取决于使用哪个方法来启动读取操作
  console.log(reader.result)
})

// 读取blob的内容

// reader.readAsArrayBuffer(blob) 
// reader.result 属性中保存的将是被读取文件的 ArrayBuffer 数据对象.

// reader.readAsDataURL(blob) 
// reader.result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容。
// base64  data:application/json;base64,eyJ0ZXN0IjoiYmxvYiJ9

reader.readAsText(blob)
// reader.result属性中将包含一个字符串以表示所读取的文件内容。
// {"test":"blob"}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

下载图片

// 通过src获取图片的blob对象
function getImgBlob(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest()
    xhr.open('get', url, true)

    // 设置返回类型为blob对象
    xhr.responseType = 'blob'

    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4 && xhr.status === 200 ) {
        resolve(xhr.response)
      }
    }
    xhr.send()
  })
}
// 下载图片
async function downloadImg(src) {
  // 获取 图片src链接的 blob对象
  const imgBlob = await getImgBlob(src)

  // 下载
  // 创建URL对象
  const url = URL.createObjectURL(imgBlob)
  const a = document.createElement('a')

  a.href = url
  // 下载图片名字
  a.download = 'test.png'
  document.body.appendChild(a)
  // 模拟点击
  a.click()
  // 销毁URL对象
  URL.revokeObjectURL(imgBlob)
  // 移除a标签
  document.body.removeChild(a)

  // 以下是转base64显示页面
  // 创建FilerReader对象
  // const reader = new FileReader()
  // function getResult() {
  //   // 图片的base64格式
  //   console.log(reader.result)
  //   reader.removeEventListener('loadend', getResult)
  // }
  // reader.addEventListener('loadend', getResult)

  // reader.readAsDataURL(imgBlob)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

第三方库

提供大部分常用数据的下载: download.jsopen in new window

下载表格导出excel: tableExport.jsopen in new window

上次更新: 2021/10/22 下午4:10:00
贡献者: 陈书进