写入包含MemoryDrawing图像的大文件时内存不足(PhpSpreasheet)

brc7rcf0  于 2022-12-26  发布在  PHP
关注(0)|答案(1)|浏览(211)

我目前正在尝试将产品列表(来自API,大约6000个产品)导出到. xlsx文件,在该文件中列出产品名称及其缩略图。
对于文本值,一切都很好,但我尝试使用PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing直接在电子表格中呈现图像。
我的问题是在生成一定数量的图像后,我的进程内存不足。
下面是我的代码:

$spreadsheet = new Spreadsheet();
        $sheet       = $spreadsheet->getActiveSheet();

        $sheet->getColumnDimension('B')->setAutoSize(true);
        $sheet->getColumnDimension('C')->setAutoSize(true);

        foreach ($products as $k => $product) {
            $sheet->setCellValueByColumnAndRow(1, $k+1, $product['ref']);
            $sheet->getCellByColumnAndRow(1, $k+1)->setDataType(DataType::TYPE_STRING);
            $sheet->setCellValueByColumnAndRow(2, $k+1, $product['title']);

            if (empty($product['image'])) {
                continue;
            }

            $drawing = new MemoryDrawing();
            $sheet->getRowDimension($k+1)->setRowHeight(80);

            $gdImage = substr_count($imagePath, '.png') ? imagecreatefrompng($imagePath) : imagecreatefromjpeg($imagePath);
            $drawing->setName('Thumbnail');
            $drawing->setDescription('Thumbnail');
            $drawing->setResizeProportional(true);
            $drawing->setImageResource($gdImage);
            $drawing->setRenderingFunction(substr_count($imagePath, '.png') ? MemoryDrawing::RENDERING_PNG : MemoryDrawing::RENDERING_JPEG);
            $drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT);
            $drawing->setHeight(80);
            $drawing->setOffsetX(0);
            $drawing->setOffsetY(0);
            $drawing->setCoordinates('C'.($k+1));
            $drawing->setWorksheet($sheet);

            unset($drawing);
        }

        $writer = new Xlsx($spreadsheet);
        $writer->save($filePath);

我也试着写我的文件,取消设置电子表格,每100或200行重新加载一次,但我失去了之前写的所有内存图像。

if ($k % 100 === 0) {
            $writer = new Xlsx($spreadsheet);
            $writer->save($filePath);
            $spreadsheet->disconnectWorksheets();
            $spreadsheet->garbageCollect();
            unset($spreadsheet);
            unset($sheet);

            $reader      = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
            $spreadsheet = $reader->load($filePath);
            $sheet       = $spreadsheet->getActiveSheet();
        }

有什么办法让它工作吗?

eqoofvh9

eqoofvh91#

尝试这(persistent结果在这文件系统并且不在这记忆体)

$drawing->setWorksheet($spreadsheet->getActiveSheet());
$writer = new Xlsx($spreadsheet);
$writer->save('my_file.xlsx');

相关问题