The front end gets the files in bulk and packages the compression solution
preface
Front-end file download I believe many partners are not unfamiliar, download the form of the file also have many, for example, the back end returns a file address, we put the address in the < A >
tag inside click download; Or we return the file stream through the back-end interface, and we do a series of operations on the stream and so on.
There are many solutions to single download, but when we need to batch download files, how do we do it?
In the face of such demands, we proposed the following solutions:
Scheme 1: directly obtain the back-end file address array, and then one by one to download. However, each time a file is downloaded, the browser will show more downloading tasks;
Scheme 2: the back-end is used to package and compress files first, and then the front-end only needs to download a compressed file, but this will have a great impact on the server performance;
Plan three: or directly obtain the file address array returned by the back end, one by one to download, and then the front end to package compression processing.
To tell the truth, when it came to front-end packaging compression, I was like a part of my friends, how to front-end packaging compression? Here are two excellent libraries to solve our problem.
Here it is mentioned that the React environment is used as an example. However, the ideas and usage in other environments are basically the same. You can refer to the following content.
JSZip and Filesaver.js This section briefly introduces the APIS and usage of JSZip and filesaver.js.
Install NPM install jszip file-saverCopy the code
JSZip is a javascript library for creating, reading, and editing.zip files with a friendly and simple API. A simple example. Let’s start by implementing a simple example to get a feel for this very useful tool
import React , { useState } from 'react'
import JSZip from 'jszip'
import FileSaver from 'file-saver'
const MyButton = () = > {
const downloadFile = () = > {
const zip = new JSZip();
zip.file("Hello.txt"."Hello World\n");
zip.generateAsync({type:"blob"})
.then((content) = > {
FileSaver(content, "example.zip"); })}return (
<div>
<button onClick={()= >{downloadFile()}}> Download</button>
</div>)}export default MyButton
Copy the code
Click the download button to get a compressed file named example.zip. Open the compressed file and there will also be a file named hello.txt.
API
A couple of apis.
Create JSZip instance:
const zip = new JSZip()
Copy the code
Create file:
zip.file("hello.txt"."Hello World")
Copy the code
Create folder:
zip.folder("file")
Copy the code
Create folders and files simultaneously:
zip.file("file/hello.txt"."Hello World\n")
/ / is equivalent to
zip.folder("file").file("hello.txt"."Hello World\n")
Copy the code
Generate a compressed file:
We can generate a compressed file with.generateAsync(options) or.GeneratenodeStream (options) :let promise = null
if (JSZip.support.uint8array) {
promise = zip.generateAsync({type : "uint8array"})}else {
promise = zip.generateAsync({type : "string"})}Copy the code
For details on the API, click on the official documentation
FileSaver.js
In the previous example we used JSZip and the filesaver.js library. FileSaver. Js is a solution for saving files on the client and is ideal for generating files on the client.
In the example in the previous section, we saved our.zip file using filesaver.js.
grammar
FileSaver saveAs(Blob/File/Url, optional DOMString filename, optional Object { autoBom })
Copy the code
example
import FileSaver from 'file-saver'
const blob = new Blob(["Hello, world!"] and {type: "text/plain; charset=utf-8"})
FileSaver.saveAs(blob, "hello world.txt")
Copy the code
Click on the official documentation for more usage
We’re going to bulk get the files and package them and download these two libraries and we’re going to have to implement what we need. Here in two steps, the first step is to get the file; The second step is package compression.
Source file address the file address here is just a simple example and depends on the actual development situation.
const data = [
{
fileUrl: 'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx'.fileName: 'File 1'
},
{
fileUrl: 'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx'.fileName: 'Paper 2'
},
{
fileUrl: 'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx'.fileName: 'File 3'
},
{
fileUrl: 'https://www.xxx.com/data/data_service/20210429/144b4b1e4e457485c10fed54b8bc8d48.docx'.fileName: 'Paper 4'},]Copy the code
Access to the file
import JSZip from 'jszip';
import FileSaver from 'file-saver';
import requestFile from './requestFile'; // Here is the wrapped request function, you can use your own wrapper or Axios
const getFile = (url: string) = > {
return new Promise((resolve, reject) = > {
requestFile(url, {
method: 'GET'.responseType: 'blob'
}).then((res:any) = > {
resolve(res)
}).catch((error: any) = > {
reject(error)
})
})
}
Copy the code
Package compression download here is mainly through traversing the address array, and then through the address from the back end to obtain the file, and then a batch compression package file operation, and finally the compressed file saved.
/** ** package compressed download *@param Data source file array *@param FileName Specifies the name of the compressed file */
const compressAndDownload = (data: any[], fileName ? : string) = > {
const zip = new JSZip();
const promises: any[] = []; // Used to store multiple promises
data.forEach((item: any) = > {
const promise = getFile(item.fileUrl).then((res: any) = > {
const fileName = item.fileName
zip.file(fileName, res ,{binary: true});
})
promises.push(promise)
})
Promise.all(promises).then(() = > {
zip.generateAsync({
type: "blob".compression: "DEFLATE".// STORE: DEFLATE is not compressed by default
compressionOptions: {
level: 9 // Compression levels 1 to 9 1 Has the fastest compression speed and 9 has the best compression mode
}
}).then((res: any) = > {
FileSaver.saveAs(res, fileName ? fileName : "Zip package. Zip") // Use file-saver to save the file})})}export default compressAndDownload
Copy the code
Reference stuk. Making. IO/jszip
Github.com/eligrey/Fil…
Finally, by using JSZip and FileSaver. Js, we can integrate and compress the batch files at the back end, which not only reduces the pressure on the server to a certain extent, but also gives people the feeling that they have downloaded a file and will not pop up many download tasks at one time. It also enhances the experience to some extent.
Links: juejin. Cn/post / 697086… Source: juejin