Node.js使用excelJS包时内存不足

3
我正在使用nodejs在服务器上创建Excel文件,当调用超过20个时,我会遇到堆内存错误。我已经尝试了以下技巧,但都无济于事。
npm install -g increase-memory-limit increase-memory-limit
我也遵循了下面的链接,但仍然没有运气。有什么建议吗? Node.js heap out of memory
pageNumbers = [1,2,3,4,5,6,7,8,9,10,11....40]; //example

for (const pageNumbers of p) {
    data = await getData(p,limit,organization_id,token, baseurl, sideFilter, null, client).then(response=>{
        return response;
    });

    await readAndWrite(data);
}


let getData = (page,limit, organization_id,token, baseurl, sideFilter, worksheet, client) =>{

  return new Promise((resolve, reject) => {

    axios.post(baseurl+`/v2/get-export`, {
      page:page,
      organization_id:organization_id,
      per_page:limit,
      filter: "",
      sorted:"",
      ...sideFilter
    },{ headers: {"Authorization" : `Bearer ${token}`} }).then(function (response) {

      let dataTemp = response.data.data.data.map((t,i)=>{
        var parent = '';
        var child  = '';
        if (t.teams_relation && t.teams_relation.length > 0) {
          //business logic
        }


        return {
          ...t, 
          content     :  t.content ? convert(t.content) : '--',
          parent_team : parent,
          child_team  : child,
          reopened_comments_latest_content : t.reopened_comments_latest?t.reopened_comments_latest.content:'--',
          solved_comments_latest_content : t.solved_comments_latest?t.solved_comments_latest.content:'--',
          closed_comments_latest_content : t.closed_comments_latest?t.closed_comments_latest.content:'--',
          requester_comments_latest_content : t.requester_comments_latest?t.requester_comments_latest.content:'--',
          tags_impolode : t.tags?t.tags.length > 0 ? t.tags.join(", ") : '--':'--',
          organization : t.organization?t.organization.name:'--',
          comments : convert ( t.comments.map(function(c){return c.content;}).join(",") ),
          user_name : t.user ? t.user.name : '',
          user_email : t.user ? t.user.email : '',
          escalated_at : t.escalated_at ? t.escalated_at : '',
          region_Cluster : getDynamicFieldData(t.dynamicFieldsValue, "5f2ff7557a17f166076f2aa2"),
          mawid_Facility_Name : getDynamicFieldData(t.dynamicFieldsValue, "5f3000d1486e94459b6531c2"),
          hospital : getDynamicFieldData(t.dynamicFieldsValue, "609274609d16481196010c6d"),
        }
      });
        resolve(dataTemp);
    }).catch(function (error) {
      reject(error);
    });
  });
}


let getDynamicFieldData = (data, id) => {
    let df = data && data.length>0 ? data.find(d => d._id === id ):null;
    if (df)
        return df.value ;
    else
        return '--';
}


let readAndWrite = async (data) => {
  if (fs.existsSync('./export.xlsx')) {
    const newWorkbook = new excel.Workbook();
    await newWorkbook.xlsx.readFile('export.xlsx').then(() => {
      console.log("read");
    })
    .catch((err) => {
      console.log("error ha yeh while reading", err);
    });
    const newworksheet = newWorkbook.getWorksheet('My Sheet');
    // console.log('columns check ', typeof newworksheet.columns);
    newworksheet.columns = columns;
    await newworksheet.addRows(data);
    await newWorkbook.xlsx.writeFile('export.xlsx').then(() => {
      console.log("updated");
    })
    .catch((err) => {
      console.log("error ha yeh while updating", err);
    });
    delete newworksheet;
    delete newWorkbook;

  } else {
    const workbook1 = new excel.Workbook();
    const worksheet1 = workbook1.addWorksheet("My Sheet");
    worksheet1.columns = columns;
    await worksheet1.addRows(data);
    await workbook1.xlsx.writeFile('export.xlsx').then(() => {
      console.log("saved");
    })
    .catch((err) => {
      console.log("error ha yeh while writing", err);
    });

    delete workbook1;
    delete worksheet1;
  }
  
}

错误 npm ERR! 代码 ELIFECYCLE npm ERR! 错误号 137 npm ERR! wapp-permutas-backend@1.0.0 启动: node -max_old_space_size=20480 server.js npm ERR! 退出状态 137


你解决了这个问题吗? - Gagantous
是的,我已经解决了这个问题。 - hu7sy
请问您如何解决这个问题? - Gagantous
1
@Gagantous 当你从服务器获取数据时,你需要使用循环添加行,然后提交。使用以下代码:worksheet.addRow(data).commit(); 然后使用以下代码进行承诺:await Promise.all(promises); 最后使用以下代码进行提交:await workbook.commit(); - hu7sy
这里的 Promise 是什么? - Gagantous
1
这取决于我是否使用承诺从服务器获取数据,因为通常我有超过100K的数据,所以我会分块获取数据。 - hu7sy
2个回答

0

我用以下代碼解決了此問題。我嘗試使用流而不是緩衝區。我正在使用Typescript編寫此代碼,但問題是,當數據超過250K行時,會出現內存溢出的問題。因此,在處理大量數據時,可以使用非常強大且編譯速度快、寫入數據也很快的Golang,而不是使用Nodejs。

如果您仍然遇到內存溢出的問題,請嘗試運行以下命令。

node --max-old-space-size=<在這裡輸入更多內存的數量> index.js

例如:

(6GB):node --max-old-space-size=6124 index.js

或者

(12GB):node --max-old-space-size=12028 index.js

而不是像通常一樣運行以下命令。

node index.js

但是,不建議設置最大內存,因為它需要更多的RAM資源來處理,這會降低服務器性能。

請注意,我正在使用Node 14。

export async function exportToexcel(res: any, jsonSetting: ObjExcelSetting): Promise<any> {

  // Initiate Excel Workbook
  const workBook = new excel.stream.xlsx.WorkbookWriter({
    // the most important part, dont forget to set this
    stream: res
  });

  // initiate into variable from jsonSetting; column, data, sheetname
  let { column, data, sheetname } = jsonSetting;
  // default name for sheet if null
  let defaultsheetname = sheetname ?? "Sheet"
  // Add the worksheet
  const workSheet = workBook.addWorksheet(defaultsheetname);
  // Set the column
  workSheet.columns = column
  // Looping for adding the data to excel
  console.log("Looping for adding the data to excel")
  for (let i = 0; i < data.length; i++) {
    const r = i + 1;
    
    // dont forget to commit for **every** loop
    workSheet.addRow(data[i]).commit();
  }
  // commit the workbook
  console.log("Commit the excel workboom")
  await workBook.commit();
}   

res: any -> 指的是在expressjs或类似框架nestjs中的响应和请求方法

jsonSetting: ObjExcelSetting -> 是我函数的元数据,包括列、工作表名称和JSON数据等。有关更多信息,请阅读exceljs文档,ObjexcelSetting只是typescript注释,如果您使用JavaScript,请不要使用它。

const workBook = new excel ... -> 指的是初始化模块,例如const excel = require('exceljs')import * as excel from 'exceljs'

数据将以Blob形式返回,因此您需要猜测如何解析它。


0
你使用的是哪个版本的NodeJS?我在你提供的链接中读到有些人通过升级到最新版本来解决这个问题。 另外,你是否使用了--optimize-for-size?有人报告说在指定--max-old-space-size后,这有助于解决问题。

Node.js 版本 = v16.13.0 - hu7sy
npm 版本 = 8.1.0 - hu7sy
我已经使用了 --max-old-space-size。 - hu7sy
这可能是与pm2有关的问题吗? - hu7sy
http://sendanywhe.re/SDUQ2G2Y 控制器 - hu7sy
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接