模拟导出百万条excel数据

272 阅读1分钟

当我们涉及到文件上传,文件下载,视频播放等等,很多时候都会想到分片进行,导出百万条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)
    }
}