当我们涉及到文件上传,文件下载,视频播放等等,很多时候都会想到分片进行,导出百万条excel数据也不例外,依旧采用分片下载的形式,既然是前端,那今天就来说说前端分片下载百万条excel数据的实现吧
模拟后端数据请求
const getData = (limit) => {
return new Promise((resolve, reject) => {
try{
const {Random} = mock;
const data = new Array(limit).fill('').map((_,index)=>{
return {
id: `202312-${index}`,
username: Random.cname(),
url: Random.url('https'),
price: Random.float(0, 210000, 0, 2),
createAt: Random.datetime('yyyy-MM-dd HH:mm:ss'),
}
})
resolve(data)
}catch(error){
reject(error)
}
})
}
分片导出
const exportCSV = async(total = 0, size: 1000, onProcess = () => {}) => {
try{
if(!total) throw Error('无数据~')
const count = total / size // 分片
const csvArray = [] // 缓存传入blob的100* 10000条数据
csvArray.push(`${['id','username','url','price','createAt']}`) // 表头
// 处理分片数据组合到缓存数组
for(let i = 0; i < count; i++) {
return new Promise(async(resolve, reject) => {
try{
const data = await getData(size)
data.map(d => {
csvArray.push(Object.values(d).join() + '\n')
})
onProcess(i / count)
resolve(true)
}catch(e){ reject(e) }
})
}
onProcess(100)
// 导出
const blob = new Blob([...csvArrat], {
type: 'text/plain;charset=utf-8',
})
// 这里导出直接采用fileSaver的库了...没有自己组装workbook, 太麻烦...
// 若要自己组装workbook,且采用xlsx库进行导出,见文章:
// https://juejin.cn/post/7314703290577813545
await FileSaver.saveAs(blob, 'xxx.csv')
} catch(e) {
return Promise.reject(e)
}
}