求大佬们指点,请问uniapp里, 在APP的环境中后端返回blob流, 如何下载成为Excel?或者可以手动生成Excel,用数据填充进去?

请问uniapp里, 在APP的环境中后端返回blob流, 如何下载成为Excel?或者可以手动生成Excel,用数据填充进去

uni.downloadFile({
    url: '/equipment/export',
    method: 'POST',
    header: {
      Authorization: `Bearer ${token}`,
    },
    success: (res) => {
      console.log('res: ================ ', res)
      if (res.statusCode === 200) {
        uni.saveFile({
          tempFilePath: res.tempFilePath,
          success: (e) => {
            uni.openDocument({
              filePath: e.savedFilePath,
              fail: (e) => {
                console.log('e: ======================= ', e)
                uni.showToast({
                  title: `打开失败${e}`,
                })
              },
            })
          },
          fail: (e) => {
            uni.showToast({
              title: `保存失败${e}`,
            })
          },
        })
      }
    },
    fail: (e) => {
      uni.showToast({
        title: `文件下载失败${e}`,
        icon: 'none',
      })
    },
  })

因为是post,还需要传递搜索条件,这个尝试了好像不行

阅读 2.1k
1 个回答
新手上路,请多包涵

后续有找到解决方法,再此记录,希望可以帮到有相同问题的同志
1.请求方式

// 导出
export function exportEquipmentledger(data: any) {
    return http<any>({
        url: '你的请求地址',
        method: 'POST',
        data,
        header: {
            'Content-Type': 'application/json',
        },
        responseType: 'arraybuffer',
    })
}

2.后端返回数据Blob格式,先转为base64

export function arrayBufferToBase64(buffer) {
    // 1. 将 ArrayBuffer 转换为 Uint8Array
    const uint8Array = new Uint8Array(buffer)

    // 2. 将 Uint8Array 的每个字节转为对应字符并合并为字符串
    const binaryString = Array.from(uint8Array)
        .map((byte) => String.fromCharCode(byte))
        .join('')

    // 3. 使用 btoa 进行 Base64 编码
    const base64String = btoa(binaryString)

    return base64String
}

3.有查到其余下载方式,我的场景为下载excel文件,确认可用,原文如下
https://blog.csdn.net/qq285679784/article/details/126838827

4.方法如下:

/**  
 * base64字符串转成文件
 * @param {String} base64Str // 允许包含前缀
 * @param {String} fileName // 文件名称:1663061363470.xlsx
 * @param {Object} callback  // 返回本地路径径URL,file:///xxx/doc/1663062980631.xlsx
 */
export function base64ToFile(base64Str, fileName, callback) {
    // 去除base64前缀
    var index = base64Str.indexOf(',')
    var base64Str = base64Str.slice(index + 1, base64Str.length)

    plus.io.requestFileSystem(plus.io.PRIVATE_DOC, function(fs) {
        fs.root.getFile(fileName, {
            create: true
        }, function(entry) {

            // 获得本地路径URL,file:///xxx/doc/1663062980631.xlsx
            var fullPath = entry.fullPath;

            let platform = uni.getSystemInfoSync().platform
            if (platform == 'android') {
                var Base64 = plus.android.importClass("android.util.Base64");
                var FileOutputStream = plus.android.importClass("java.io.FileOutputStream");
                try {
                    var out = new FileOutputStream(fullPath);
                    // 此处Base64.decode有长度限制,如果不能满足需求,可以考虑换成官方原生插件市场的【Base64转文件】
                    var bytes = Base64.decode(base64Str, Base64.DEFAULT);
                    out.write(bytes);
                    out.close();
                    // 回调  
                    callback && callback(entry.toLocalURL());
                } catch (e) {
                    console.log(e.message);
                }
            } else if (platform == 'ios') {
                var NSData = plus.ios.importClass('NSData');
                var nsData = new NSData();
                nsData = nsData.initWithBase64EncodedStringoptions(base64Str, 0);
                if (nsData) {
                    nsData.plusCallMethod({
                        writeToFile: fullPath,
                        atomically: true
                    });
                    plus.ios.deleteObject(nsData);
                }
                // 回调  
                callback && callback(entry.toLocalURL());
            }
        })
    })
}

5.使用方式

const handleExport = async () => {
    const res = await exportEquipmentledger(tansParams({ ...queryForm.value }))


    const base64String = arrayBufferToBase64(res)
    console.log(base64String) // 编码后的 Base64

    const fileName = 'xxx' + new Date().valueOf() + '.xlsx'
    base64ToFile(base64String, fileName, function (path) {
        console.log('result', path)
        plus.runtime.openFile(path) //用第三方程序打开文件
    })
}

6.补充,因为我要转换请求参数--tansParams方法()

/**
 * 参数处理
 * @param {*} params  参数
 */
export function tansParams(params) {
    let result = ''
    for (const propName of Object.keys(params)) {
        const value = params[propName];
        var part = encodeURIComponent(propName) + "=";
        if (value !== null && value !== "" && typeof(value) !== "undefined") {
            if (typeof value === 'object') {
                for (const key of Object.keys(value)) {
                    if (value[key] !== null && value[key] !== "" && typeof(value[key]) !== 'undefined') {
                        let params = propName + '[' + key + ']';
                        var subPart = encodeURIComponent(params) + "=";
                        result += subPart + encodeURIComponent(value[key]) + "&";
                    }
                }
            } else {
                result += part + encodeURIComponent(value) + "&";
            }
        }
    }
    return result
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题