mask2012 / MaskBlog

all blogs are in issues.
12 stars 5 forks source link

antd中post获取二进制流保存成文件 #80

Open mask2012 opened 5 years ago

mask2012 commented 5 years ago

关于post获取二进制流,然后保存成文件,网上已经有很多写得很详细的例子了,比如这个 axios+post获取并下载后台返回的二进制流 可是到antd里应该怎么做比较优雅呢 貌似还没有人说过,经过实践,获得如下经验

业务里用axios直接发请求

axios({
            method: 'post',
            url: 'http://localhost:8001/dev/parent/JT0084/downExcel/order/queryOrderDetail',
            responseType: 'arraybuffer',
            data:{
                stUserInfo: getStUserInfo(),
                stPagination: { pageSize: 999, pageNum: 0 },
                sOrderStartDate,
                sOrderEndDate,
                sKey,
                iOrdSource,
                iDetCat,
                eTaskStatus: iTaskStatus,
            },
            responseType: 'arraybuffer',
        })
            .then(res => {
                Common.downloadExcel('委托详细', res);
            })

downloadExcel是个公共方法,就是改名,保存。

downloadExcel(filename, res) {
        console.log('res',res);
        const url = window.URL.createObjectURL(new Blob([res.data], { type: "application/octet-stream" }))
        // const url = window.URL.createObjectURL(new Blob([res.data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }))
        const link = document.createElement('a')
        link.style.display = 'none'
        link.href = url
        link.setAttribute('download', filename+'.xlsx')
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
    }

在发请求的时候responseType: 'arraybuffer',很关键,如果不标识为arraybuffer的话,得到的实际上会是字符串,保存出来的文件体积比正常的大 image 标识后,得到的就是array buffer image 需要注意的是axios和request不一样,他支持 array buffer,接着就可以用createObjectURL得到一个url,然后后边的就是改名保存了。

至于createObjectURL的时候,究竟是哪个type,我两个都试的结果一样。这个写法在这篇文章里有提及

const url = window.URL.createObjectURL(new Blob([res.data], { type: "application/octet-stream" }))
const url = window.URL.createObjectURL(new Blob([res.data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }))

集成到antd里

这个核心问题解决了,接下来合到antd的套路里,发现给request写responseType: 'arraybuffer'是无效的。于是直接把service/api.js里的request换成了axios image 不过使用axios的前提是cnpm install axios --save-dev 安装axios,然后 import axios from 'axios'引入

那么,在写业务的时候还是原来的写法,不需要特立独行了。 image

request方法

后发现request也是可以做的,需要extend一下 https://juejin.im/post/5db7af846fb9a0202b5ee13c