前端 文件打包下载

2,099 阅读2分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

前端下载文件

前端下载文件的几种方式

  1. window.location.href
  2. window.open
  3. <a>标签

以上下载方式在下载浏览器无法识别的文件时均可行,但如果遇到浏览器可以直接解析文件,如html,jpg,png等,则不会触发浏览器的文件下载,而是被浏览器直接解析并展示,遇到这种情况,我们可以使用<a>标签的download属性进行下载即可。

<a href="/images/a.jpg" download="photo">

有时需要js来触发下载,这种情况下我们可以通过动态创建a标签来解决。

const a = document.createElement('a');
a.href = downLoadUrl;
a.download = downLoadUrl;
a.click();
return false;

但是如果需要下载打包后的压缩文件,解决方案有多种,可以在服务端打包后返回下载url,前端通过<a>标签下载,亦或是前端去请求每个文件,打包后再下载,为了减轻服务端压力,这次需要在WEB端实现多文件的打包下载。

安装依赖

jszip

JSZip 是一个用于创建、读取和编辑 .zip 文件的 javascript 库,具有可爱而简单的 API。

stuk.github.io/jszip/

demo

var zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
var img = zip.folder("images");
img.file("smile.gif", imgData, {base64: true});
zip.generateAsync({type:"blob"})
.then(function(content) {
    // see FileSaver.js
    saveAs(content, "example.zip");
});

Support

OperaFirefoxSafariChromeInternet ExplorerNode.js
YesYesYesYesYesYes
Tested with the latest versionTested with 3.0 / 3.6 / latest versionTested with the latest versionTested with the latest versionTested with IE 6 / 7 / 8 / 9 / 10Tested with node.js 0.10 / latest version


file-saver

FileSaver.js 是在客户端保存文件的解决方案,非常适合在客户端生成文件的 Web 应用程序

github.com/eligrey/Fil…

demo:

import { saveAs } from 'file-saver';

// Saving text
var blob = new Blob(["Hello, world!"], {type"text/plain;charset=utf-8"});
FileSaver.saveAs(blob, "hello world.txt");


// Saving URLs
FileSaver.saveAs("https://httpbin.org/image""image.jpg");

Supported Browsers

BrowserConstructs asFilenamesMax Blob SizeDependencies
Firefox 20+BlobYes800 MiBNone
Firefox < 20data: URINon/aBlob.js
ChromeBlobYes2GBNone
Chrome for AndroidBlobYesRAM/5None
EdgeBlobYes?None
IE 10+BlobYes600 MiBNone
Opera 15+BlobYes500 MiBNone
Opera < 15data: URINon/aBlob.js
Safari 6.1+*BlobNo?None
Safari < 6data: URINon/aBlob.js
Safari 10.1+BlobYesn/aNone

 

代码实现

template

<el-button class="button success" @click="downloadPhoto">批量下载</el-button>

script

<script>
import JSZip from 'jszip'
import axios from 'axios'
import { saveAs } from 'file-saver'


export default {
  name: 'Download',
  data() {
    return {
      fileList:[
        'https://xxx/xxx/xxx.jpg',
        'https://xxx/xxx/xxx.jpg',
        'https://xxx/xxx/xxx.mp4',
      ]
    }
  },
  methods: {
    // 批量下载
    downloadPhoto() {
      // 获取文件流
      const getFile = (url) => {
        return new Promise((resolve, reject) => {
          axios
            .get(url, {
              responseType: 'arraybuffer',
            })
            .then((res) => {
              resolve(res.data)
            })
            .catch((err) => {
              reject(err.toString())
            })
        })
      }
      // 创建JSZip实例
      const zip = new JSZip()
      // promise对象
      const promises = []
      // 创建下载列表
      const downList = this.fileList
      // 生成每个文件
      downList.forEach((v) => {
        // 获取文件名
        const fileName = v.split('/').slice(-1)
        // 生成promise
        const promise = getFile(v).then((res) => {
          zip.file(fileName, res)
        })
        promises.push(promise)
      })
      // 异步处理
      Promise.all(promises).then(() => {
        // 生成二进制流
        zip
          .generateAsync({
            type: 'blob',
          })
          .then((content) => {
            saveAs(content, this.order.task.title)
          })
      })
    },
  }
}


</script>

 

实现效果:

image.png

image.png


END

「欢迎在评论区讨论,掘金官方将在掘力星计划活动结束后,在评论区抽送100份掘金周边,抽奖详情见活动文章」。