У меня есть код для MySQL для записи данных в Excel и загрузки файла Excel с помощью nodejs, который занимает некоторое время, и после этого выдает ошибку nodejs-heap из памяти.
exports.exportdatatocsv = async (req, res) => {
con.query(
"SELECT sender_name, table_name FROM sender_tbl",
function (error, data) {
if (error) {
console.error(error);
res.status(500).send("Internal Server Error");
return;
}
var mysqlData = JSON.parse(JSON.stringify(data));
var workbook = new ExcelJS.stream.xlsx.WorkbookWriter({ stream: res });
mysqlData.forEach((sender, index) => {
var worksheet = workbook.addWorksheet(
sender.sender_name.substring(0, 31)
);
con.query(
`SELECT * FROM ${sender.table_name} ORDER BY id DESC`,
function (error, tableData) {
if (error) {
console.error(error);
res.status(500).send("Internal Server Error");
return;
}
var fileHeader = [
"message",
"info",
"credit/debit",
"amount",
"netbal",
];
worksheet.addRow(fileHeader);
tableData.forEach((row) => {
worksheet.addRow([
row.message,
row.info,
row.isdebit ? "debit" : "credit",
row.amount,
row.netbal,
]);
});
if (index === mysqlData.length - 1) {
workbook
.commit()
.then(function () {
res.status(200).end();
})
.catch(function (err) {
console.error(err);
res
.status(500)
.send("Error occurred while generating Excel file");
});
}
}
);
});
}
);
};
🤔 А знаете ли вы, что...
JavaScript позволяет создавать динамические и интерактивные веб-приложения.
Вероятно, во время операций вы достигли максимального доступного пространства кучи, у вас есть два возможных варианта:
node --max-old-space-size=2048 yourApp.js
NOTE:
значение 2048 приведено только в качестве примера, попробуйте упорядочить его с помощью некоторых тестов, увеличивая или уменьшая его.
async function main() {
let index = 0;
let batchSize = 100;
for await (const elem of processSenderTbl(batchSize)) {
// elem is a list of batch
const mysqlData = JSON.parse(JSON.stringify(elem));
const workbook = new ExcelJS.stream.xlsx.WorkbookWriter({ stream: res });
for (const sender of mysqlData) {
const worksheet = workbook.addWorksheet(
sender.sender_name.substring(0, 31)
);
for await (const tableData of processSenderTbl_(sender.table_name,batchSize)){
var fileHeader = [
"message",
"info",
"credit/debit",
"amount",
"netbal",
];
worksheet.addRow(fileHeader);
tableData.forEach((row) => {
worksheet.addRow([
row.message,
row.info,
row.isdebit ? "debit" : "credit",
row.amount,
row.netbal,
]);
});
}
if (index === mysqlData.length - 1) {
workbook
.commit()
.then(function () {
res.status(200).end();
})
.catch(function (err) {
console.error(err);
res
.status(500)
.send("Error occurred while generating Excel file");
});
}
index++
}
}
}
async function* processSenderTbl(batchSize: number) {
let offset = 0;
try {
while (true) {
// Fetch data with the current offset
const query = `SELECT sender_name, table_name FROM sender_tbl LIMIT ? OFFSET ?`;
const payload = [batchSize, offset];
const [row, _] = await conn.query(query, payload);
const results = row as any[];
if (results.length === 0) {
// No more data to fetch
break;
}
yield results;
offset += batchSize;
}
} catch (err) {
console.info(err);
return;
}
}
async function* processSenderTbl_(tableName: string, batchSize: number) {
let offset = 0;
try {
while (true) {
// Fetch data with the current offset
const query = `SELECT * FROM ?? LIMIT ? OFFSET ?`;
const payload = [tableName, batchSize, offset];
const [row, _] = await conn.query(query, payload);
const results = row as any[];
if (results.length === 0) {
// No more data to fetch
break;
}
yield results;
offset += batchSize;
}
} catch (err) {
console.info(err);
return;
}
}
Это всего лишь доказательство концепции, основанной на вашем коде, поскольку у меня нет всей вашей кодовой базы;
NOTE:
Я использовал обещание в качестве стратегии подключения к базе данных, поэтому вы можете обновить информацию о соединении, добавив дополнительные promise()
, я предполагаю, что вы используете mysql2
в качестве драйвера базы данных.
const conn = mysql2
.createConnection({
...
})
.promise();
Дайте мне знать, если это поможет
Некоторые ресурсы:
Учебное пособие по генераторам Javascript