Этот код предназначен для хранения сгенерированного файла Excels с PHP библиотекой Excel
"maatwebsite / excel": "~ 2.1.0"
Есть 30 КБ строки данных транзакции, и каждая транзакция имеет под-данные. Цель состоит в том, чтобы создать документ отчета о транзакциях, который группируется по месяцам (1 месяц = 1 файл Excel). 15k транзакций было установлено как ограничение на лист (оно автоматически генерирует новый лист, если лимит был превышен).
Поскольку я пытался регистрировать использование памяти, процесс занял загрузку памяти , Вот следующие сведения об использовании памяти.
Первое состояние памяти: 10 МБ
Первый файл Excel (первый месяц) Сгенерированное состояние памяти: 88 МБ
Ожидаемое состояние памяти после сохранения первого файла Excel: аналогично первому состоянию 10 МБ
Фактическое состояние памяти после сохранения первого файла Excel: 60 МБ
Это означает, что phpexcel не полностью освободил память даже после того, как первый файл имеет
Предположительно PHP excel должен освободить память после того, как был создан первый файл. Цель состоит в том, чтобы сгенерировать как минимум 150 тыс. Строк транзакций в отдельных файлах Excel, но в этой ситуации я считаю, что это невозможно, поскольку потребуется много памяти.
Любое решение, которое можно сделать, чтобы избежать проблем с памятью при генерации PHP файлов Excel?
Код, который используется для генерации файлов Excel, показан ниже. Заранее спасибо.
$counter = 0;
// Loop through months
foreach ($period as $month) {
$numberOfPages = 1;
$startOfMonth = $monthLoops === 0 ? Carbon::parse($export->startDate) : $month->copy()->startOfMonth();
$endOfMonth = $monthLoops === $numberOfMonths ? Carbon::parse($export->endDate) : $month->copy()->endOfmonth();
$monthName = $month->format('F');
// do the first call and get number of records and calculate pages
list($transactions, $aggregations, $numberOfTransactions) = $this->getTransactionsCall($datalakeSalesTransactionRepository, $companyUuid, $export, $startOfMonth, $endOfMonth, 1, 1, null, 1);
if ($transactions) {
// generate first datalake excel call
$objPHPExcel = Excel::create("Laporan Transaksi Penjualan $monthName ".$startOfMonth->year, function ($excel) use ($export, &$counter, $totalTransactionsPerSheet, $numberOfPages, $datalakeSalesTransactionRepository, $companyUuid, $startOfMonth, $endOfMonth, $perPage, $transactions, $aggregations, $numberOfTransactions) {
$page = 1;
// calculate pages and sheets
$sheetLoop = 1;
$numberOfPages = $numberOfTransactions !== 0 ? (int) ceil($numberOfTransactions/$perPage) : 1;
$numberOfSheets =$numberOfTransactions !== 0 ? (int) ceil($numberOfTransactions/$totalTransactionsPerSheet) : 1;
// generate all sheets in one excel
for ($sheetLoop; $sheetLoop <= $numberOfSheets; $sheetLoop++) {
// generate sheets if total of transactions in one excel exceed limit of totalRows per sheet chunk by perPage
$this->currentRow = 1;
$numberOfTransactionsInOneSheet = 0;
$excel->sheet("$export->myTitle-$sheetLoop", function ($sheet) use ($export, $aggregations, $numberOfTransactionsInOneSheet, &$counter, $totalTransactionsPerSheet, &$page, $numberOfPages, $datalakeSalesTransactionRepository, $companyUuid, $startOfMonth, $endOfMonth, $perPage) {
// loop through calls per 200 items to avoid memory usage issue
$header = $this->getHeader($export, $startOfMonth, $endOfMonth);
foreach ($header as $row) {
$sheet->row($this->currentRow++, $row);
}
while ($page <= $numberOfPages) {
$transactions = $this->getTransactionsCall($datalakeSalesTransactionRepository, $companyUuid, $export, $startOfMonth, $endOfMonth, $page, $perPage, 1);
foreach ($transactions as $keyTrx => $transaction) {
$counter++;
$this->generateRow($transaction, $keyTrx, $sheet);
\Log::info(array('transactions' => $counter, $startOfMonth->month));
\Log::info(memory_get_usage()/1000000);
}
$numberOfTransactionsInOneSheet += $perPage;
$page++;
if ($numberOfTransactionsInOneSheet >= $totalTransactionsPerSheet) {
break;
}
}
$this->setTotal($aggregations);
$this->setUpSheet($sheet);
});
}
$this->getDatalakeDownpaymentSheet($excel, $export, $companyUuid, $numberOfPages, $perPage, $startOfMonth, $endOfMonth, $datalakeSalesTransactionRepository);
$excel->setActiveSheetIndex(0);
});
$objPHPExcel->store($export->extension, $folderPath);
$objPHPExcel->disconnectWorksheets();
$objPHPExcel->garbageCollect();
unset($objPHPExcel);
}
$monthLoops++;
}
Я пытался освободить память после того, как файл был сохранен с этими частями кода, но, похоже, он не работает.
$objPHPExcel->store($export->extension, $folderPath);
$objPHPExcel->disconnectWorksheets();
$objPHPExcel->garbageCollect();
unset($objPHPExcel);