PerKins Zhu

Le vent se lève,il faut tenter de vivre.

导航

ajax下载文件笔记

Posted on 2021-05-26 16:00  PerKins.Zhu  阅读(972)  评论(0编辑  收藏  举报

思路:

  后端把文件数据转化为 base64字符串返回给前端、前端ajax获取到字符串之后,解码转换为blob,之后模拟<a>标签点击事件下载文件。

相关代码:

/**
     * <p>将文件转成base64 字符串</p>
     *
     * @param path 文件路径
     * @return
     * @throws Exception
     */
    public static String encodeBase64File(String path) throws Exception {
        File file = new File(path);
        FileInputStream inputFile = new FileInputStream(file);
        byte[] buffer = new byte[(int) file.length()];
        inputFile.read(buffer);
        inputFile.close();
        return new BASE64Encoder().encode(buffer);
    }

 

//ajax 下载文件
        $.ajax({
            url: url,
            type: 'get',
            data: {},
            success: function (res) {
                //返回的是base64字符串
                saveFile(res, '下载结果.xlsx');
            },
            error: function (err) {
                console.log(err)
            }
        });

    function saveFile(base64, fileName) {
        base64ToBlob({b64data: base64, contentType: 'application/vnd.ms-excel'}).then(blob => {
            // 转后的blob对象
            if (window.navigator.msSaveOrOpenBlob) {
                navigator.msSaveBlob(blob, fileName)
            } else {
               //模拟<a>标签的点击事件
                let link = document.createElement('a')
                link.href = window.URL.createObjectURL(blob)
                link.download = fileName
                link.click()
                window.URL.revokeObjectURL(link.href)
            }
        })
    }

    //base64转blob
    function base64ToBlob({b64data = '', contentType = '', sliceSize = 512} = {}) {
        return new Promise((resolve, reject) => {
            // 使用 atob() 方法将数据解码
            let byteCharacters = atob(b64data);
            let byteArrays = [];
            for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
                let slice = byteCharacters.slice(offset, offset + sliceSize);
                let byteNumbers = [];
                for (let i = 0; i < slice.length; i++) {
                    byteNumbers.push(slice.charCodeAt(i));
                }
                // 8 位无符号整数值的类型化数组。内容将初始化为 0。
                // 如果无法分配请求数目的字节,则将引发异常。
                byteArrays.push(new Uint8Array(byteNumbers));
            }
            let result = new Blob(byteArrays, {
                type: contentType
            })
            result = Object.assign(result, {
                // 这里一定要处理一下 URL.createObjectURL
                preview: URL.createObjectURL(result),
                name: `下载文件.xlsx`
            });
            resolve(result)
        })
    }