I’m solving a problem such as saving big data to an Excel document. There is a console command that uploads data from the database to an xlsx document.
The code performs the following actions:
- Allocates memory to the process.
- Creates a Spreadsheet object for the header and fills the spreadsheet with headers.
- Next, in the loop, it creates temporary Spreadsheet1 and in batches of 500 records, we pull it from the database and write it to the same document.
- When a new iteration of the while loop begins, we destroy Spreadsheet1.
- At the end and at intermediate stages, we save the document.
As a result, an error occurs:
Worksheet!D301 -> Unable to access External Workbook
at the stage of loading the second data packet. Here is the code:
ini_set('memory_limit', '512M');
...
// Create new object - Spreadsheet
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$count_data = DB::table($table_name)->count();
$data = DB::table($table_name)->get();
//skip($pos)->take(1000)->
$headers = [];
if (count($data) > 0) {
// header
$this->info('Create header');
foreach ($data as $itm) {
$Arr = json_decode($itm->data_json);
if (is_object($Arr))
// Add keys in array of headers
foreach ($Arr as $key => $value) {
if (!in_array($key, $headers)) {
$headers[] = $key;
}
}
}
$rowIndex = 1;
$columnIndex = 1; // Start with first column
foreach ($headers as $colIndex => $header) {
//$sheet->setCellValueByColumnAndRow($columnIndex++, 1, $header);
$colLetter = Coordinate::stringFromColumnIndex($colIndex + 1);
// create Alfabet string
$cell = $colLetter . $rowIndex;
$sheet->setCellValue($cell, $header);
}
$this->info('Header created...');
$this->info('Rec data...');
try {
$writer = new Xlsx($spreadsheet);
$writer->save(base_path('public') . '/' . $document);
} catch (PhpOfficePhpSpreadsheetWriterException $e) {
$this->error('Error of save document: ' . $e->getMessage());
}
$rowIndex = 2; // Begin with second record
$pos = 0;
while ($rowIndex < $count_data) {
$dump = DB::table($table_name)->skip($pos)->take(500)->get();
if ($dump->count()) {
$spreadsheet1 = PhpOfficePhpSpreadsheetIOFactory::load(base_path('public').'/'.$document);
//$spreadsheet1 = new Spreadsheet();
$sheet1 = $spreadsheet1->getActiveSheet();
foreach ($dump as $item) {
$Arr = json_decode($item->data_json);
foreach ($headers as $colIndex => $header) {
$colLetter = Coordinate::stringFromColumnIndex($colIndex + 1);
$cell = $colLetter . $rowIndex;
$sheet1->setCellValue($cell, $Arr->$header ?? '');
}
$rowIndex++;
}
$this->info('Save document ' . base_path('public') . '/' .$document);
$this->info('Memory Size: ' . memory_get_usage() . ' bite');
try {
$writer = new Xlsx($spreadsheet1);
$writer->save(base_path('public') . '/'.$document);
sleep(5);
unset($spreadsheet1);
unset($sheet1);
} catch (PhpOfficePhpSpreadsheetWriterException $e) {
$this->error('Error of save document: ' . $e->getMessage());
}
}
How to solve the problem?