js實(shí)現(xiàn)根據(jù)文件url批量壓縮下載成zip包
前言
項(xiàng)目開發(fā)中,產(chǎn)品經(jīng)理提了這樣一個(gè)需求:將系統(tǒng)中的附件實(shí)現(xiàn)批量打包下載功能。本來系統(tǒng)中是有單個(gè)下載及批量下載功能,現(xiàn)在應(yīng)業(yè)務(wù)方的需求,需要多加個(gè)批量打包下載。
初步設(shè)想是:由后端編寫接口實(shí)現(xiàn)。但后來經(jīng)過思考:現(xiàn)在系統(tǒng)中已經(jīng)有文件的url地址了,何必讓后端寫接口重復(fù),前端處理就行。
1. 所需包
- jszip
- file-saver
- axios
JSZip 是一個(gè)用于創(chuàng)建、讀取和編輯 ZIP 文件的 JavaScript 庫,并且擁有有友好而簡單的API,可直接在瀏覽器上創(chuàng)建 zip 壓縮檔。
file-saver
2. 安裝
npm install jszip --save / yarn add jszip -S npm install file-saver --save / yarn add file-saver -S // axios 相信大家安裝的都有
3. 引入
import JSZip from 'jszip' import FileSaver from 'file-saver' import axios from 'axios';
4. 完整代碼解析使用
import React, { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import JSZip from 'jszip'
import FileSaver from 'file-saver'
import axios from 'axios';
// 在這里定義一個(gè)數(shù)據(jù)源,格式為 文件url + 文件名,可以根據(jù)自己的項(xiàng)目獲取
const dataSouce = [
{
fileUrl: 'http://dev.imuyuan.com/file/fetch/v1/7lGQFepQllMVl8ZTbMftS5',
fileName: '文件一'
},
{
fileUrl: 'http://dev.imuyuan.com/file/fetch/v1/5SNVT9QI6g791pHBSjLRsE',
fileName: '文件二'
},
{
fileUrl: 'http://dev.imuyuan.com/file/fetch/v1/4m0Qy7k1qMrh8QIA8DbHce',
fileName: '文件三'
},
{
fileUrl: 'http://dev.imuyuan.com/file/fetch/v1/2GCtdxKkrlVTSHAt00sHXJ',
fileName: '文件四'
},
]
const Index = () => {
// 將文件 url 格式轉(zhuǎn)換為 Bolb 類型格式 或者 arraybuffer 格式
const getFileData = (fileUrl: string) => {
return new Promise((resolve, reject) => {
axios(fileUrl, {
method: 'GET',
responseType: 'blob' // 返回的數(shù)據(jù)會(huì)被強(qiáng)制轉(zhuǎn)為blob類型 ,轉(zhuǎn)換成arraybuffer 也行
}).then((res) => {
console.log('res', res)
resolve(res)
}).catch(error) => {
reject(error)
}
})
}
// 批量打包下載事件
const handleBatchDown = async () => {
const zip = new JSZip() // 創(chuàng)建實(shí)例對(duì)象
const promises: any = []
dataSource.forEach((item: any) => {
const promise = getFile(item.fileUrl).then((res: any) => {
const fileName = item.fileName + ''
// 創(chuàng)建文件用file(),創(chuàng)建文件夾用 floder()
zip.file(fileName, res, {binary: true})
})
promises.push(promise)
})
/**
Promise.all 方法用于將多個(gè) Promise 實(shí)例,包裝成一個(gè)新的 Promise 實(shí)例,
只有當(dāng)all([p1, p2, p3]) 中的每一個(gè) Promise 實(shí)例的狀態(tài)都變成 fulfilled, Promise.all()的狀態(tài)才會(huì)變成 fulfilled,此時(shí) p1, p2, p3 的返回值組成一個(gè)數(shù)據(jù),傳給 Promise.all()的回調(diào)函數(shù)
只要 p1, p2, p3 中任何一個(gè)被 rejected, Promise.all() 的狀態(tài)就會(huì)變成 rejected,此時(shí)第一個(gè)被 rejected 的實(shí)例的返回值,會(huì)傳給 Promise.all()的回調(diào)函數(shù)。
在上面的代碼中,promises 數(shù)組中的每一個(gè)元素,都是 Promise 實(shí)例,所以需要用到 Promise.all()
*/
// 生成 zip 文件
Promise.all(promises).then(() => {
// 生成zip 文件
zip.generateAsync({
type: 'blob',
compression: 'DEFLATE', // STORE: 默認(rèn)不壓縮, DEFLATE:需要壓縮
compressionOptions: {
level: 9 // 壓縮等級(jí) 1~9 1 壓縮速度最快, 9 最優(yōu)壓縮方式
}
}).then((res: any) => {
FileSaver.saveAs(res, '測試.zip') // 使用FileSaver.saveAs保存文件,文件名可自定義
})
})
}
return (
<div>
<Button onClick = {handleBatchDown}>批量打包下載文件</Button>
</div>
)
}
export default memo(Index)
5. 部分代碼解析
const zip = new JSZip() // 創(chuàng)建實(shí)例對(duì)象
zip.file(fileName, res, {binary: true})
- zip.file(name, content, options),用于創(chuàng)建文件,有三個(gè)參數(shù),其中 name 為文件名,content 為文件內(nèi)容
- zip.folder(name),用于創(chuàng)建文件夾
這兩個(gè)函數(shù)都有返回值,返回值為 JSZip 對(duì)象,即可以鏈?zhǔn)秸{(diào)用
比如:創(chuàng)建一個(gè)text.txt 文件和 測試文件夾 ,測試文件夾下面又有一個(gè)text2.txt 文件,可以使用下面的鏈?zhǔn)綄懛ā?/p>
const zip = new JSZip()
zip.file('test.txt', '哈哈哈哈哈').folder('測試文件夾').file('text2.txt', '我是另一個(gè)文件')
在上面中,我們只需用到 zip.file 即可。
zip.file 的第三個(gè)參數(shù)是選填,是一個(gè)對(duì)象,常見的值有: binary 、 base64 等,在這里是將其設(shè)置為 { binary: true } 是為了返回二進(jìn)制的數(shù)據(jù)。
解析 Bolb 與 arraybuffer
Blob 表示二進(jìn)制類型的大對(duì)象,在 JavaScript 中 Blob 類型的對(duì)象表示不可變,
Blob 對(duì)象包含兩個(gè)屬性:size 、 type
- size 屬性用于表示數(shù)據(jù)的大小
- type 是MIME 類型的字符串
如下圖,就是上面的 getFileData 方法打印出來的 Bolb 對(duì)象

ArrayBuffer 對(duì)象表示一段二進(jìn)制數(shù)據(jù),用來模擬內(nèi)存里的數(shù)據(jù)。通過這個(gè)對(duì)象,JavaScript 可以讀寫二進(jìn)制數(shù)據(jù),這個(gè)數(shù)據(jù)可以看做是內(nèi)存數(shù)據(jù)的表達(dá)。
兩者區(qū)別:
- Bolb 對(duì)象用于操作二進(jìn)制文件,通常用來讀寫文件
- ArrayBuffer 用于操作內(nèi)存
如下圖,這個(gè)上面的文件使用 responseType: 'arraybuffer' 打印出的結(jié)果

到此這篇關(guān)于js實(shí)現(xiàn)根據(jù)文件url批量壓縮下載成zip包的文章就介紹到這了,更多相關(guān)js url批量壓縮下載成zip包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript無刷新評(píng)論實(shí)現(xiàn)方法
這篇文章主要介紹了javascript無刷新評(píng)論實(shí)現(xiàn)方法,涉及javascript動(dòng)態(tài)添加表格元素的技巧,需要的朋友可以參考下2015-05-05
淺談JavaScript中面向?qū)ο蟮牡纳羁截惡蜏\拷貝
下面小編就為大家?guī)硪黄獪\談JavaScript中面向?qū)ο蟮牡纳羁截惡蜏\拷貝。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-08-08
JavaScript將字符串轉(zhuǎn)換為整數(shù)的方法
這篇文章主要介紹了JavaScript將字符串轉(zhuǎn)換為整數(shù)的方法,涉及javascript中parseInt函數(shù)的使用技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
javascript超過容器后顯示省略號(hào)效果的方法(兼容一行或者多行)
下面小編就為大家?guī)硪黄猨avascript超過容器后顯示省略號(hào)效果的方法(兼容一行或者多行)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-07
js實(shí)現(xiàn)表格拖動(dòng)選項(xiàng)
這篇文章主要為大家詳細(xì)介紹了原生js實(shí)現(xiàn)表格拖動(dòng)選項(xiàng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04
JS實(shí)現(xiàn)圖片元素轉(zhuǎn)BASE64編碼的簡單示例
在Web開發(fā)中,我們經(jīng)常需要將圖片轉(zhuǎn)換為Base64格式,以便在不依賴外部資源的情況下直接在HTML中使用,在這篇文章中,我將向您展示如何使用JavaScript將圖片元素轉(zhuǎn)BASE64編碼,需要的朋友可以參考下2023-12-12
實(shí)例解析package.json和最常見的scripts字段
日常開發(fā)中,現(xiàn)在的前端開發(fā)已經(jīng)被三大框架取代,其中最主流的不過vue和react,而開發(fā)這些項(xiàng)目的時(shí)候不得不接觸package.json這個(gè)文件,可你真的了解這個(gè)文件嗎?今天給大家聊聊package.json和最常見的scripts字段,感興趣的朋友一起看看吧2023-04-04
JS實(shí)現(xiàn)選項(xiàng)卡插件的兩種寫法(jQuery和class)
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)選項(xiàng)卡插件的兩種寫法:jQuery和class,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12

