找回密码
 立即注册

QQ登录

只需一步,快速开始

helloworldplus

注册会员

5

主题

11

帖子

44

积分

注册会员

积分
44
最新发帖
helloworldplus
注册会员   /  发表于:2024-9-6 14:01  /   查看:422  /  回复:4
1金币
本帖最后由 helloworldplus 于 2024-9-6 15:00 编辑

需要实现批量将xlsx转换为sjs的功能,常规思路是遍历数组,使用import导入,然后再回调中使用save拿到blob数据。
现在测试遍历1000份文件相同文件调用import和save时,执行到300左右的文件save的回调基本就不触发了。无论是使用一个实例还是每个文件一个实例都会卡在300左右的节点,xlsx的文件大小是149kb左右。经测试发现13kb的文件是正常的。



        const input = document.createElement('input')
        input.type = 'file'
        input.multiple = true
        input.accept = '.xlsx'
        input.style.display = 'none'
        document.body.appendChild(input)
        input.click()

        input.onchange = async function(e)  {
          // 处理后的buferr数据
          let bufferData: IExcelData[] = []
          let num: number = 0
          // @ts-ignore
          let files: any[] = Array.from(e?.target?.files)
          files = files.map((item, index) => {
            return {
              // @ts-ignore
              spread: new GC.Spread.Sheets.Workbook(String(index)),
              file: item,
              bufferData: null
            }
          })

          async function dealFileData(file: any, spread: any) {
            return new Promise((resolve, reject) =>  {
              console.log('开始加载');
              spread.import(
                file,
                function () {
                  console.log('加载成功');
                  spread.save(async function(blob: any){
                    console.log('保存成功');
                    spread.clearSheets()
                    const dataArray: any = await  turnBlobToBuffer(blob)
                    resolve({
                      name: file.name,
                      size: file.size,
                      dataArray: dataArray
                    })
                  })
                },
                function () {},
                // @ts-ignore
                { fileType: GC.Spread.Sheets.excel}
              )
            })
          }
         
          for(let i = 0; i < files.length; i++) {
            const res: any = await dealFileData(files.file, files.spread)
            files.spread.destroy()
            files = {
              spread: null,
              file: null,
              bufferData: res
            }
            num = num+1
            console.log('完成进度:' + num + '/' + files.length);
            setInfoStr('完成进度:' + num + '/' + files.length);
          }

        }

最佳答案

查看完整内容

正如您说的,在您的需求场景中,批量转换的文件量达到了1000个,且每个.xlsx文件大小在149kb左右。您采取了async/await异步机制读取.xlsx文件,即File对象,File对象涉及直接的I/O操作,在读取大文件时可能对主线程产生阻塞;而Blob对象不涉及直接的I/O操作,更高效。而且,处理File对象时的内存管理和垃圾回收也可能会影响性能,但Blob对象在内存管理上更高效。 您可以按照您当前能正常操作的方式实现您的需求。

4 个回复

倒序浏览
最佳答案
最佳答案
Wilson.Zhang
超级版主   /  发表于:2024-9-6 14:01:20
来自 4#
helloworldplus 发表于 2024-9-8 12:05
我目前尝试了几种方式:1. 同一个实例的情况下,使用async/await 依次对每个文件先进行 spread.import () ...

正如您说的,在您的需求场景中,批量转换的文件量达到了1000个,且每个.xlsx文件大小在149kb左右。您采取了async/await异步机制读取.xlsx文件,即File对象,File对象涉及直接的I/O操作,在读取大文件时可能对主线程产生阻塞;而Blob对象不涉及直接的I/O操作,更高效。而且,处理File对象时的内存管理和垃圾回收也可能会影响性能,但Blob对象在内存管理上更高效。

您可以按照您当前能正常操作的方式实现您的需求。
回复 使用道具 举报
Wilson.Zhang
超级版主   /  发表于:2024-9-6 15:52:27
2#
您好!根据您的描述,我理解CPU和浏览器对批量操作1000份单个文件大小为149kb左右的文件也存在一定程度的性能影响。如您所言,对13kb的文件执行批量转换时的性能正常,考虑到您的批量操作文件数量为1000,建议您采用异步操作限制并发数量来控制性能,您可以尝试下看能否满足需求。
回复 使用道具 举报
helloworldplus
注册会员   /  发表于:2024-9-8 12:05:44
3#
本帖最后由 helloworldplus 于 2024-9-8 12:07 编辑
Wilson.Zhang 发表于 2024-9-6 15:52
您好!根据您的描述,我理解CPU和浏览器对批量操作1000份单个文件大小为149kb左右的文件也存在一定程度的性 ...

我目前尝试了几种方式:1. 同一个实例的情况下,使用async/await 依次对每个文件先进行 spread.import ()以及 spread.save();2. 使用async/await,每次都是新建实例进行spread.import ()以及 spread.save();以上两种方法都会被卡住,而且从内存上看也没有发生暴涨,卡住之后内存和cpu也正常;其他:经测试,我将save()出来的blob复制1000份,然后再使用相同的方法(此时import的参数就是blob对象了)操作却正常,不知道是否是因为1 2 中操作的是file对象的关系。
回复 使用道具 举报
Wilson.Zhang
超级版主   /  发表于:2024-9-24 16:26:40
5#
您好!由于您较长时间未回贴,且从跟帖回复中了解到问题已得到有效解答,那就结帖了。如有问题,欢迎发新帖沟通。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部