load($inputFileName); $sheet = $spreadsheet->getActiveSheet(); // Получаем данные из модели (НЕ view!) // ВАЖНО: Вычисляемые поля учитывают текущий год из сессии $spareParts = SparePart::with('pricingCodes')->orderBy('article')->get(); $i = 2; foreach ($spareParts as $sp) { $sheet->setCellValue('A' . $i, $sp->id); $sheet->setCellValue('B' . $i, $sp->article); $sheet->setCellValue('C' . $i, $sp->used_in_maf); $sheet->setCellValue('D' . $i, $sp->quantity_without_docs); $sheet->setCellValue('E' . $i, $sp->quantity_with_docs); $sheet->setCellValue('F' . $i, $sp->total_quantity); $sheet->setCellValue('G' . $i, $sp->note); $sheet->setCellValue('H' . $i, $sp->purchase_price); $sheet->setCellValue('I' . $i, $sp->customer_price); $sheet->setCellValue('J' . $i, $sp->expertise_price); $sheet->setCellValue('K' . $i, $sp->tsn_number); // Экспортируем множественные шифры расценки через запятую $sheet->setCellValue('L' . $i, $sp->pricingCodes->pluck('code')->implode(', ')); $sheet->setCellValue('M' . $i, $sp->min_stock); $i++; } $sheet->getStyle('A1:M' . ($i - 1)) ->getBorders() ->getAllBorders() ->setBorderStyle(Border::BORDER_THIN) ->setColor(new Color('777777')); // Создаём вторую вкладку для справочника расшифровок $pricingCodesSheet = $spreadsheet->createSheet(1); $pricingCodesSheet->setTitle('Справочник расшифровок'); // Заголовки $pricingCodesSheet->setCellValue('A1', 'ID'); $pricingCodesSheet->setCellValue('B1', 'Тип'); $pricingCodesSheet->setCellValue('C1', 'Код'); $pricingCodesSheet->setCellValue('D1', 'Расшифровка'); // Стиль заголовков $pricingCodesSheet->getStyle('A1:D1')->getFont()->setBold(true); $pricingCodesSheet->getStyle('A1:D1')->getFill() ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID) ->getStartColor()->setARGB('DDDDDD'); // Данные справочника $pricingCodes = PricingCode::orderBy('type')->orderBy('code')->get(); $j = 2; foreach ($pricingCodes as $pc) { $pricingCodesSheet->setCellValue('A' . $j, $pc->id); $pricingCodesSheet->setCellValue('B' . $j, $pc->type === PricingCode::TYPE_TSN_NUMBER ? '№ по ТСН' : 'Шифр расценки'); $pricingCodesSheet->setCellValue('C' . $j, $pc->code); $pricingCodesSheet->setCellValue('D' . $j, $pc->description); $j++; } // Границы для справочника if ($j > 2) { $pricingCodesSheet->getStyle('A1:D' . ($j - 1)) ->getBorders() ->getAllBorders() ->setBorderStyle(Border::BORDER_THIN) ->setColor(new Color('777777')); } // Автоширина колонок foreach (range('A', 'D') as $col) { $pricingCodesSheet->getColumnDimension($col)->setAutoSize(true); } // Возвращаемся на первую вкладку $spreadsheet->setActiveSheetIndex(0); $fileName = 'export_spare_parts_' . date('Y-m-d_H-i-s') . '.xlsx'; $writer = new Xlsx($spreadsheet); $fd = 'export/spare_parts'; Storage::disk('public')->makeDirectory($fd); $fp = storage_path('app/public/' . $fd . '/') . $fileName; Storage::disk('public')->delete($fd . '/' . $fileName); $writer->save($fp); $link = url('/storage/' . $fd . '/' . $fileName); // Создаём запись в таблице files File::query()->create([ 'link' => $link, 'path' => $fp, 'user_id' => $userId, 'original_name' => $fileName, 'mime_type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', ]); return $link; } }