js读取后端base64字符串生成文件(excel),js读取后端二进制数组生成文件(excel)

后端如何将文件传给前端??
一般后端通过流输出文件,前端直接get请求下载,但是这样功能受限了,这个请求的响应中很难附带其他信息,虽然其他信息可以放在请求头中,但是这样很不优雅。很多时候一个请求的响应中应该即包含文件,也包含其他信息,例如:在这里插入图片描述

后端向前端传文件的方式有很多种:
1、对于js可以创建的文件,如excel pdf等,可以将文件数据通过json传给前端,由前端生成文件
2、后端创建文件 ,读取文件的二进制数组,通过List传给前端(在spring mvc中 byte[] 会自动转成base64字符串)
3、后端创建文件,读取文件的二进制数组,转成base64字符串传给前端
4、后端将文件串给云存储(七牛云),然后返给前端下载链接。

ps: 很多数格式的文件都不需要在后端生成物理文件,拿到二进制数据即可:

  public static byte[] getByte(String sheetName, Class clazz, List data){
      ByteArrayOutputStream bout = new ByteArrayOutputStream();
      EasyExcel.write(bout, clazz).excelType(ExcelTypeEnum.XLSX).sheet(sheetName).doWrite(data);
      return bout.toByteArray();
  }

方法 1 js生成excel pdf 的工具包通常比较大,其实不太友好
方法 1,2,3 文件不持久化,文件与数据一起返回给前端,占用应用服务器带宽资源,只适合访问压力小的 B端 、A端(管理端)应用
方法 4 文件会持久化(可能需要定期删除),但是不占用应用服务器资源(云存储服务的带宽和流量非常便宜),适合压力较大的 C端应用

这里介绍 方法 2,3 的实现方式:

public class Result {
    List<Byte> data ;
    String base64Str;
}

前端 读取base64生成文件:

const util = {
    /** 通过base64字符串生成文件 */
    downloadFileByBase64: function(base64Str, fileName) {
        var myBlob = this.dataURLtoBlob(base64Str)
        var myUrl = URL.createObjectURL(myBlob)
        this.downloadFile(myUrl, fileName)
    },
    /**封装base64Str blob对象*/
    dataURLtoBlob: function (base64Str) {
        var bstr = atob(base64Str), n = bstr.length, u8arr = new Uint8Array(n);
        alert(JSON.stringify(bstr))
        while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr]);
    },
    /**创建一个a标签,并做下载点击事件*/
    downloadFile: function (hrefUrl, fileName) {
        var a = document.createElement("a")
        a.setAttribute("href", hrefUrl)
        a.setAttribute("download", fileName)
        a.setAttribute("target", "_blank")
        let clickEvent = document.createEvent("MouseEvents");
        clickEvent.initEvent("click", true, true);
        a.dispatchEvent(clickEvent);
    }
}
export default util

LoadFileUtil.downloadFileByBase64(response.data.base64Str,“test.xlsx”)

核心代码:
这里最重要的代码
window.atob(base64Str) -------- 解码base64 不过解码后依然是字符串
u8arr = new Uint8Array(n); u8arr[n] = bstr.charCodeAt(n); ------- 返回字符串编码 且用位长为 8 的数组保存(后端一个byte长度也是8)

前端 读取二进制数组生成文件:

const util = {
    /**创建一个a标签,并做下载点击事件*/
    downloadFile: function (hrefUrl, fileName) {
        var a = document.createElement("a")
        a.setAttribute("href", hrefUrl)
        a.setAttribute("download", fileName)
        a.setAttribute("target", "_blank")
        let clickEvent = document.createEvent("MouseEvents");
        clickEvent.initEvent("click", true, true);
        a.dispatchEvent(clickEvent);
    },
    buildBlobByByte:function(data){
        let len = data.length;
        let u8arr = new Uint8Array(len);
        while(len -- ){
            u8arr[len] = data[len];
        }
        return new Blob([u8arr]);
    },
    /**二进制数组 生成文件 */
   downloadFileByByte:function(data, fileName) {
        var myBlob = this.buildBlobByByte(data)
        var myUrl = URL.createObjectURL(myBlob)
        this.downloadFile(myUrl, fileName)
    }
}
export default util

LoadFileUtil.downloadFileByByte(response.data.data,“test-byte.xlsx”)

核心代码:
let u8arr = new Uint8Array(len);
while(len – ){
u8arr[len] = data[len];
}
后端的byte数组传递的时候通过json传递,实际上js可能用整数接收的,所有在内存中占有的空间大(后端一个byte是8位,前端可能用16位接收),得到的二进制数组实际上是不对的,所有通过赋值给Uint8Array将它们转成正常的

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值