純前端完成批量下載文件功能,可以下載任何文件,開箱即用


最近工作中遇到了一個批量下載文件的需求,要求在前端實現,本來打算在網上找一下CV完事。但是找一圈下來沒有一個合適的,不是只支持下載圖片,就是寫的過於簡略。無奈,只能自己搞!自己動手,豐衣足食,本着我為人人,人人為我的原則。特寫下此篇博客,以供參考。

這個批量下載支持多種文件格式混合下載,下載結果都會放進一個壓縮包中

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<script src="./js/FileSaver.js"></script>
<script src="./js/jquery-2.0.0.min.js"></script>
<script src="./js/jszip.min.js"></script>
<script src="./layer/layer.js"></script>

<body>
    <button onclick="downlist()">下載</button>
</body>
<script>
    // 文件列表數組,支持線上路徑和本地路徑
    let pafurl = [
        { url: "https://dss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1546500353,2204894501&fm=26&gp=0.jpg", name: "0.jpg" },
        { url: "https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2771978851,2906984932&fm=26&gp=0.jpg", name: "1.jpg" },
        { url: "https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=3922290090,3177876335&fm=26&gp=0.jpg", name: "2.jpg" },
        { url: "./pdf/0.pdf", name: "1.pdf" },
        { url: "./pdf/2.xlsx", name: "2.xlsx" },
        { url: "./pdf/3.docx", name: "3.docx" }
    ]
    // 壓縮包名稱
    const downLoadName = "批量下載壓縮包.zip";
    // 點擊下載按鈕
    function downlist() {
        /*
            批量下載方法,傳入文件列表,
            路徑key名稱必須為url,文件key名必須為name
            文件名稱必須攜帶后綴且不能重復
        */
        dowmurls(pafurl).then(res => {
            console.log(res);
            // 下載成功的個數
            let successCount = pafurl.length - res.errUrls.length;
            // 下載失敗的個數
            let errorCount = res.errUrls.length;
            if (res.code === "success") {
                // 下載失敗的文件
                console.log(res.errUrls);
                // 提示
                layer.confirm(`${successCount}個文件獲取成功,${errorCount}個文件獲取失敗`, {
                    btn: ['確定', '取消']
                }, function (e) {
                    // 點擊確定關閉彈框並下載
                    layer.close(e)
                    // 利用file-saver保存文件
                    saveAs(res.content, downLoadName);
                })
            } else {
                layer.alert("文件下載失敗", { icon: 2 })
            }
        });
    }
    // 接收一個文件路徑的集合
    function dowmurls(fileUrls) {
        return new Promise((resolve, reject) => {
            if (fileUrls.length > 0) {
                const zip = new JSZip();
                const cache = {};
                const downAll = [];
                // 錯誤文件
                const errlist = [];
                for (let key in fileUrls) {
                    const promise = getFile(fileUrls[key].url).then(data => {
                        // 成功的文件
                        if (data !== "downerr") {
                            // 獲取文件名
                            const file_name = fileUrls[key].name;
                            // 逐個添加文件
                            zip.file(file_name, data, {
                                binary: true
                            });
                            // 保存文件
                            cache[file_name] = data;
                        } else {
                            // 保存錯誤文件
                            errlist.push(fileUrls[key])
                        }
                    })
                    // 保存所有的文件
                    downAll.push(promise)
                }
                // 統一下載
                Promise.all(downAll).then(() => {
                    // 生成二進制流
                    zip.generateAsync({
                        type: "blob"
                    }).then(content => {
                        // 封裝的返回文件
                        let resData = {
                            // 狀態碼
                            code: "success",
                            // 存放錯誤文件數據
                            errUrls: [],
                            // 文件流數據
                            content: null,
                        }
                        // 判斷是否存在錯誤文件                        
                        resData.errUrls = errlist.length > 0 ? errlist : []
                        // 判斷錯誤文件的個數是否等於要下載的文件個數
                        errlist.length !== fileUrls.length ? resData.content = content : resData.code = "error"
                        // 返回下載結果信息
                        resolve(resData);
                    })
                })
            }
        })
    }
    // 根據文件路徑獲取這個文件的文件流
    function getFile(url) {
        return new Promise((resolve, reject) => {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url, true);
            // 設置響應類型為ArrayBuffer對象,目的是讓JSZip正確識別並下載
            xhr.responseType = 'arraybuffer';
            xhr.onreadystatechange = function (e) {
                // 判斷獲取文件的狀態,非200時為獲取異常,返回錯誤碼
                if (e.target.status === 200) {
                    // 直接返回arraybuffer格式的文件
                    if (xhr.response) {
                        resolve(xhr.response);
                    }
                } else {
                    resolve("downerr");
                }
            }
            xhr.send();
        })
    };
</script>
</html>

 

本篇采用的是原生js來實現,使用vue實現只需要改一下方法調用方式和引入一下 jszip 和 FileSaver就可以了,下面是程序運行截圖

 

 

 

 

 

 解壓后就可以看到下載的文件了,希望能夠幫助大家,給我評論個好用

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM