找回密码
 立即注册

QQ登录

只需一步,快速开始

leo_

最新发帖
leo_
注册会员   /  发表于:2024-7-9 18:20:55
13#
那一般spreadjs的数据都是怎么来的?都是先写道Excel里面,然后导入到spreadjs吗?100万数据也是这样?
回复 使用道具 举报
Joestar.XuSpreadJS 开发认证
超级版主   /  发表于:2024-7-10 09:58:04
14#
您好,我的意思是,这些数据已经不是SpreadJS能控制的范围之内了,举个简单的例子,您将您获取到的数据放在了变量A里面,然后将变量A以数据绑定的形式绑定到了SpreadJS中,SpreadJS仅能控制其内部的数据,无法控制变量A。

以下是我在网上检索到的一些关于垃圾清理的信息,供您参考:

在 JavaScript 中,内存管理是由垃圾回收机制自动处理的,通常不需要手动释放内存。不过,有一些方法可以帮助您确保变量尽快被垃圾回收器回收。

1. 将变量设置为 null 或 undefined
将变量设置为 null 或 undefined 可以解除对该对象的引用,从而让垃圾回收器识别并回收内存。

let myVar = { key: "value" };
myVar = null; // 或 myVar = undefined;

2. 通过块作用域限制变量的范围
使用 let 或 const 声明变量在块作用域中,这样当块作用域结束时,变量会被垃圾回收器回收。

{
    let myVar = { key: "value" };
    // 使用 myVar
}
// 此处 myVar 超出了作用域,内存可以被回收

3. 解除事件
如果变量是一个 DOM 元素,并且有事件**绑定到它,确保在不再需要时移除**。

const button = document.getElementById("myButton");
function handleClick() {
    console.log("Button clicked");
}
button.addEventListener("click", handleClick);

// 当不再需要时移除
button.removeEventListener("click", handleClick);

4. 清理全局变量
尽量避免使用全局变量,因为它们会一直存在于内存中。可以通过将变量封装在函数或模块中来限制其作用域。

function doSomething() {
    let myVar = { key: "value" };
    // 使用 myVar
} // myVar 在函数结束时超出作用域

5. 使用 delete 操作符(仅用于对象的属性)
delete 操作符用于删除对象的属性,从而解除对该属性的引用。

let myObj = { key: "value" };
delete myObj.key;

6. 手动清空数组
如果变量是一个数组,可以通过设置数组的长度为 0 来清空它。

let myArray = [1, 2, 3];
myArray.length = 0;

7. 手动清空对象
如果变量是一个对象,可以通过手动删除所有属性来清空它。

let myObj = { key1: "value1", key2: "value2" };
for (let key in myObj) {
    if (myObj.hasOwnProperty(key)) {
        delete myObj[key];
    }
}

总之,通过解除对变量的引用,可以帮助 JavaScript 的垃圾回收器更快地回收内存。使用上述方法可以有效地管理内存,从而提高程序的性能。
回复 使用道具 举报
leo_
注册会员   /  发表于:2024-7-10 14:30:25
15#
Joestar.Xu 发表于 2024-7-10 09:58
您好,我的意思是,这些数据已经不是SpreadJS能控制的范围之内了,举个简单的例子,您将您获取到的数据放在 ...

感谢您的回答,我又重新验证了一下,整个过程是这样的,我从数据库抽出数据20000条,然后用这两万条数据,往新创建的5个sheet里面设置,每个sheet里面放2万条数据,在这个过程中,发现内存一值升高,最终可以达到6GB,但是这2万条数据,才不到150MB,为什么内存会一直升高那么多呢
回复 使用道具 举报
Joestar.XuSpreadJS 开发认证
超级版主   /  发表于:2024-7-10 17:53:20
16#
您好,理论上不应该出现这样的问题,您具体是怎么“每个sheet里面放2万条数据”的呢?需要结合实际的代码调研一下看看。
回复 使用道具 举报
leo_
注册会员   /  发表于:2024-7-11 17:29:05
17#
Joestar.Xu 发表于 2024-7-10 17:53
您好,理论上不应该出现这样的问题,您具体是怎么“每个sheet里面放2万条数据”的呢?需要结合实际的代码调 ...

感谢您的回答,
,具体代码如下,先抽取5万条数据,每一行是58列,然后创建5个sheet,每个sheet的数据一样

  1. var spread = new GC.Spread.Sheets.Workbook(document.getElementById("aa"));
  2. spread.fromJSON(json);
  3. designer.setWorkbook(spread);

  4. var getResult = async function() {
  5.     var data = await call_sql_api("mysqldb", "");// 返回50000条数据,每行58列
  6.     console.log("data=========>", data);
  7.   
  8.     var showData = [];
  9.     showData.push(data.columns);
  10.     var newData = data.rows.slice(0, 20000); // 截取20000条
  11.     console.log("newData=========>", newData);
  12.     newData.forEach(function(row) {
  13.         showData.push(row);
  14.     });
  15.   
  16.     console.log("showData=========>", showData);
  17.   
  18.     // Function to add data to sheet in chunks
  19.     const addDataInChunks = (sheet, data, chunkSize) => {
  20.         return new Promise(resolve => {
  21.             let index = 0;

  22.             const addChunk = () => {
  23.                 let end = Math.min(index + chunkSize, data.length);

  24.                 for (let i = index; i < end; i++) {
  25.                     data[i].forEach((item, colIndex) => {
  26.                         sheet.setValue(i + 1, colIndex, item); // +1 to account for header row
  27.                     });
  28.                 }

  29.                 index = end;

  30.                 if (index < data.length) {
  31.                     setTimeout(addChunk, 0); // Yield to the browser
  32.                 } else {
  33.                     resolve();
  34.                 }
  35.             };

  36.             addChunk();
  37.         });
  38.     };

  39.     spread.suspendPaint();
  40.     spread.suspendCalcService();
  41.     // Loop to create 5 new sheets and fill with data
  42.     for (let i = 0; i < 5; i++) {
  43.         let sheetName = `Sheet${i + 2}`;
  44.         let newSheet = new GC.Spread.Sheets.Worksheet(sheetName);

  45.         // Setting the number of rows and columns
  46.         newSheet.setRowCount(showData.length);
  47.         newSheet.setColumnCount(showData[0].length);

  48.         // Adding the new worksheet to the workbook
  49.         spread.addSheet(spread.getSheetCount(), newSheet);

  50.         // Write headers to the first row
  51.         showData[0].forEach((item, index) => {
  52.             newSheet.setValue(0, index, item);
  53.         });

  54.         // Write data in chunks to avoid freezing the browser
  55.         await addDataInChunks(newSheet, showData.slice(1), 1000);
  56.     }

  57.     // Refresh the workbook to make sure the changes take effect
  58.     spread.repaint();
  59.         spread.resumeCalcService(false);
  60.     spread.resumePaint();
  61. };

  62. setButton("Sheet1", "H5", "count");
  63. setButtonClickEvent("Sheet1", "H5", getResult);
复制代码
回复 使用道具 举报
Joestar.XuSpreadJS 开发认证
超级版主   /  发表于:2024-7-11 18:03:09
18#
您好,我看了一下您的代码,如此大规模的数据加载,极不推荐使用setValue设置,建议使用数据绑定,或者报表来实现,请参考:

数据绑定:https://demo.grapecity.com.cn/sp ... evel-binding/purejs

报表:https://demo.grapecity.com.cn/sp ... eet/overview/purejs
回复 使用道具 举报
leo_
注册会员   /  发表于:2024-7-15 10:30:41
19#
本帖最后由 leo_ 于 2024-7-15 15:38 编辑
Joestar.Xu 发表于 2024-7-11 18:03
您好,我看了一下您的代码,如此大规模的数据加载,极不推荐使用setValue设置,建议使用数据绑定,或者报表 ...

现在发现的问题是,在最开始的时候使用
   spread.suspendPaint();
   spread.suspendEvent();
   spread.suspendCalcService(false);
禁止渲染,之后在使用
   spread.resumeCalcService(true);
   spread.rresumeEvent();
   spread.resumePaint();
重新渲染。之前都没问题。就是在重新渲染的时候,执行spread.resumeCalcService(true);一句,内存溢出了。

而且我将newSheet.setValue改为setArray,发现内存并没有释放出来。,没有什么改善



  1. spread.suspendPaint();
  2.     spread.suspendEvent()
  3.     spread.suspendCalcService(false);
  4.     // Loop to create 5 new sheets and fill with data
  5.     for (let i = 0; i < 5; i++) {
  6.         let sheetName = `Sheet${i + 2}`;
  7.         let newSheet = new GC.Spread.Sheets.Worksheet(sheetName);

  8.         // Setting the number of rows and columns
  9.         newSheet.setRowCount(showData.length);
  10.         newSheet.setColumnCount(showData[0].length);

  11.         // Adding the new worksheet to the workbook
  12.         spread.addSheet(spread.getSheetCount(), newSheet);

  13.         // Write headers to the first row
  14.         showData[0].forEach((item, index) => {
  15.             newSheet.setValue(0, index, item);
  16.         });

  17.         // Write data in chunks to avoid freezing the browser
  18.         await addDataInChunks(newSheet, showData.slice(1), 1000);
  19.     }

  20.     // Refresh the workbook to make sure the changes take effect
  21.     spread.resumeCalcService(true);
  22.         spread.rresumeEvent();
  23.     spread.resumePaint();
复制代码


回复 使用道具 举报
Joestar.XuSpreadJS 开发认证
超级版主   /  发表于:2024-7-15 17:33:48
20#
您好,spread.resumeCalcService(true);会使当前workBook中的所有公式进行重算,如果您的表单中存在大量的公式,是有可能出现这个问题的。
回复 使用道具 举报
leo_
注册会员   /  发表于:2024-7-16 09:05:10
21#
本帖最后由 leo_ 于 2024-7-16 15:37 编辑
Joestar.Xu 发表于 2024-7-15 17:33
您好,spread.resumeCalcService(true);会使当前workBook中的所有公式进行重算,如果您的表单中存在大量的 ...

感谢您的回答,下面四个问题,对我很重要,麻烦给出您的建议

1,那表单中出现,大量公式,应该什么时候计算呢?
2,另外使用spreadjs打开的Excel里面有15万数据(每个sheet大概50列),占用1.5个G,正常吗?
3,使用setValue和setArray为什么使用内存差不多呢?他们是在什么时候占用内存,是调用setValue和setArray的时候,
还是在使用
   spread.resumeCalcService(true);
   spread.rresumeEvent();
   spread.resumePaint();


4,大量数据往Excel里面设置,发现setValue和setArray这两个确实很占内存,13万的数据的话,大概需要占内存2GB,应该如何优化,因为之前也使用过数据绑定,发现也会发生内存溢出的状况。

回复 使用道具 举报
Joestar.XuSpreadJS 开发认证
超级版主   /  发表于:2024-7-16 17:33:14
22#
您好,具体的性能问题需要根据实际的用例进行调研,如果您目前使用SpreadJS遇到了较严重的性能问题,请您提供一个可以复现您问题的Demo,我们根据实际的Demo调研看看是否还有优化空间。

另外使用spreadjs打开的Excel里面有17万数据(每个sheet大概50列),占用1.5个G,正常吗?
——————————————————
不太确定,请您提供一下此Excel文件。

使用setValue和setArray为什么使用内存差不多呢?他们是在什么时候占用内存,是调用setValue和setArray的时候
——————————————————
猜测setArray实现上可能也是多次调用了setValue,可以尝试使用数据绑定看内存是否有下降。具体占用内存的时机涉及源码,这边也无从得知。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 立即注册
返回顶部