У меня есть задача отчета, в которой все данные должны заполнять файл Excel и отправлять их по почте клиентам со стороны бэкэнда. Я использовал excel.js для написания файла Excel, и он работает нормально с меньшим количеством данных. Если данные больше похожи на 2000 или более, то эти данные не заполняются в файле Excel. Ниже приведен пример, который я попробовал.

Ниже приведен API, в котором.

router.get('/:type/:fromDate/:toDate',userAuth,(req,res)={amp}gt;{ if(!req.query.ids) return res.send({'message':'Please send ID as query',statusCode:2}); let ids = req.query.ids.split(','); var workbook = new Excel.Workbook(); let type = req.params.type workbook.creator = ' 32'; workbook.lastModifiedBy = '321'; workbook.created = new Date(); workbook.modified = new Date(); workbook.views = [{ x: 0, y: 0, width: 10000, height: 20000, firstSheet: 0, activeTab: 1, visibility: 'visible' }] var reportWorkSheet = workbook.addWorksheet( req.params.type  ' Report', { pageSetup: { paperSize: 9, orientation: 'landscape' } }); if(type === 'customers'){ userCustomerReport(req,res ,ids , reportWorkSheet ,workbook ); } else if(type === 'interactions'){ userInteractionReport(req ,res, ids , reportWorkSheet ,workbook , req.params.fromDate , req.params.toDate); } else if(type === 'allocations'){ userAllocationReport(req ,res,ids , reportWorkSheet ,workbook); } else return res.send({'message':'Please check the request type',statusCode:2}); }) commonColomns = () ={amp}gt; ([ { header: 'Customer Name', key: 'cName', width: 25, style: { font: { size: 12 } } }, { header: 'Customer Phone', key: 'cPhone', width: 35, style: { font: { size: 12 } } }, { header: 'Customer Email', key: 'cEmail', width: 35, style: { font: { size: 12 } } }, { header: 'Customer Company Name', key: 'cCompName', width: 18, style: { font: { size: 12 } } }, { header: 'Assigned to name', key: 'assignedTName', width: 18, style: { font: { size: 12 } } }, { header: 'Assigned from name ', key: 'assignedFName', width: 20, style: { font: { size: 12 } } } ]); // here i am generation all JSON data . function userInteractionReport(req ,res , ids ,reportWorkSheet , workbook , fromDate , toDate) { let idString = req.query.ids.split(','); let id =[]; idString.forEach(element ={amp}gt; {id.push(new ObjectID(element));}); Interaction.aggregate([ { $match:{$or: [{"assigned.toId":{$in:id}},{"assigned.fromId":{$in:id}}] ,createdTimeStamp : {$gte:Number(fromDate),$lt:Number(toDate)}} }, { "$project": { "assigned": 1, "type": 1, "priority": 1, "customer": 1, "customFields": 1, "dateTime": 1, "notes":1, "length": { "$size": "$customFields" } }}, { "$sort": { "length": -1 } }, ]) .then((interactions)={amp}gt;{ if(!interactions[0]){ return res.send({'message':'No data found',statusCode:1 , "data":0}) } let columns = commonColomns(); columns.push({ header: 'type', key: 'type', width: 25, style: { font: { size: 12 } } }); columns.push({ header: 'priority', key: 'priority', width: 25, style: { font: { size: 12 } } }); columns.push({ header: 'Company Address', key: 'cAddress', width: 25, style: { font: { size: 12 } } }); columns.push({ header: 'Key Decision Maker Name', key: 'kdm', width: 25, style: { font: { size: 12 } } }); columns.push({ header: 'Key Decision Maker Phone', key: 'kdmPhone', width: 25, style: { font: { size: 12 } } }); columns.push({ header: 'Date', key: 'dateTime', width: 25, style: { font: { size: 12 } } }); columns.push({ header: 'Notes', key: 'notes', width: 25, style: { font: { size: 12 } } }); for (let i = 0; i {amp}lt; interactions[0].customFields.length; i  ) { columns.push({ header: interactions[0].customFields[i].dName , key: interactions[0].customFields[i].dName, width: 25, style: { font: { size: 12 } } }); } reportWorkSheet.columns = columns; interactions.forEach(interaction ={amp}gt; { let assignedTo = interaction.assigned.toName ? interaction.assigned.toName : ''; let assignedFrom = interaction.assigned.fromName ? interaction.assigned.fromName : ''; let companyName = interaction.customer.company ? interaction.customer.company.name : ''; let cAddress ; let kdm,kdmPhone ; if(interaction.customer.company.address){ let companyAddress = interaction.customer.company.address ; cAddress = companyAddress.street ? companyAddress.street ' ,' : '' ; cAddress = cAddress   (companyAddress.city ? companyAddress.city   ' ,' :'' ); cAddress = cAddress   (companyAddress.state ? companyAddress.state  ' ,' :'') ; cAddress = cAddress  (companyAddress.country ? companyAddress.country ' ,':'') ; cAddress = cAddress   (companyAddress.pincode ? companyAddress.pincode  ' ,' :''); } if(interaction.customer.company.kdm){ kdm = interaction.customer.company.kdm.fName; kdmPhone = interaction.customer.company.kdm.phone; } let row = { cName:interaction.customer.fName || ''   ' ' interaction.customer.lName || '', cPhone : interaction.customer.phone.join(','), assignedTName : assignedTo, assignedFName : assignedFrom, cEmail : interaction.email || ' ', source : interaction.source || '', type : interaction.type || '', dateTime : interaction.dateTime ? new Date(interaction.dateTime) : '', notes : interaction.notes || '', priority : interaction.priority === 1 ? "High" : interaction.priority === 2 ? "Medium" : interaction.priority === 3 ? "Low" : " " , status : interaction.status||'', cCompName : companyName, cAddress : cAddress, kdm :kdm, kdmPhone:kdmPhone } for (let i = 0; i {amp}lt; interaction.customFields.length; i  ) { row[interaction.customFields[i].dName] = interaction.customFields[i].type === "dateTime" ? moment(interaction.customFields[i].value).format('l, h:mm:ss a') : interaction.customFields[i].value || " "; } reportWorkSheet.addRow(row); }); return interactions; }).then((interactions)={amp}gt;{ writeWorkbook(workbook , req); res.send({"messgae":"report send sucessfully" , "statusCode":0 ,"data":""}) }).catch((e)={amp}gt;{ console.log(e); }) } function writeWorkbook(workbook , req) { workbook.xlsx.writeFile('templates/excel/Report.xlsx') .then(function () { sendMail(req); console.log("report send successfully "); }); } 

После написания файла excel прикрепите его к почте и отправьте.

Попробуйте потоковую передачу:

  // pipe from stream const workbook = new Excel.Workbook() workbook.useSharedStrings = false stream.pipe(workbook.xlsx.createInputStream()) 

Тем не менее, управление памятью, похоже, является постоянной проблемой для этой библиотеки (на момент написания этого ответа). Смотрите этот вопрос GitHub для справки:

https://github.com/exceljs/exceljs/issues/709 и связанные с этим вопросы

Возможно, вы захотите использовать другую библиотеку для обработки больших файлов Excel (например: Node-libxl . Это расширение является платным, кстати).

Если вы можете использовать Python, вы также можете попробовать OpenPyxl