ExportCommonCatalogService.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Services\Export;
  4. use App\Models\CommonCatalogItem;
  5. use App\Models\File;
  6. use Illuminate\Support\Facades\Storage;
  7. use PhpOffice\PhpSpreadsheet\Cell\DataType;
  8. use PhpOffice\PhpSpreadsheet\Spreadsheet;
  9. use PhpOffice\PhpSpreadsheet\Style\Alignment;
  10. use PhpOffice\PhpSpreadsheet\Style\Border;
  11. use PhpOffice\PhpSpreadsheet\Style\Fill;
  12. use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
  13. use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
  14. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  15. class ExportCommonCatalogService
  16. {
  17. public const HEADERS = [
  18. 'ID',
  19. 'Внешний вид',
  20. 'Артикул',
  21. 'Наименование по калькулятору',
  22. 'Вид',
  23. 'Габаритные размеры',
  24. 'Высота падения',
  25. 'Дополнительные сведения',
  26. "Единица измерения\nгабаритов",
  27. 'Вес, кг.',
  28. 'Объем, м3',
  29. 'Места',
  30. 'Состав',
  31. 'Возрастная группа',
  32. 'Макс.кол-во пользователей',
  33. 'Ед.',
  34. 'Серия',
  35. 'ТМ',
  36. 'Примечание',
  37. ];
  38. public function handle(int $userId): string
  39. {
  40. $spreadsheet = new Spreadsheet;
  41. $sheet = $spreadsheet->getActiveSheet();
  42. $sheet->setTitle('Каталог общий');
  43. $sheet->fromArray(self::HEADERS, null, 'A1');
  44. $sheet->getStyle('A1:S1')->applyFromArray([
  45. 'font' => ['bold' => true],
  46. 'fill' => [
  47. 'fillType' => Fill::FILL_SOLID,
  48. 'startColor' => ['rgb' => 'D9EAF7'],
  49. ],
  50. 'alignment' => [
  51. 'horizontal' => Alignment::HORIZONTAL_CENTER,
  52. 'vertical' => Alignment::VERTICAL_CENTER,
  53. 'wrapText' => true,
  54. ],
  55. ]);
  56. $sheet->getRowDimension(1)->setRowHeight(42);
  57. $sheet->freezePane('A2');
  58. $sheet->setAutoFilter('A1:S1');
  59. $row = 2;
  60. CommonCatalogItem::query()
  61. ->with('imageFile')
  62. ->orderBy('article')
  63. ->chunk(200, function ($items) use ($sheet, &$row): void {
  64. foreach ($items as $item) {
  65. $sheet->setCellValue("A{$row}", $item->id);
  66. $sheet->setCellValueExplicit("C{$row}", $item->article, DataType::TYPE_STRING);
  67. $sheet->setCellValue("D{$row}", $item->calculator_name);
  68. $sheet->setCellValue("E{$row}", $item->kind);
  69. $sheet->setCellValue("F{$row}", $item->dimensions);
  70. $sheet->setCellValue("G{$row}", $item->fall_height);
  71. $sheet->setCellValue("H{$row}", $item->additional_info);
  72. $sheet->setCellValue("I{$row}", $item->dimension_unit);
  73. $sheet->setCellValue("J{$row}", $item->weight);
  74. $sheet->setCellValue("K{$row}", $item->volume);
  75. $sheet->setCellValue("L{$row}", $item->places);
  76. $sheet->setCellValue("M{$row}", $item->composition);
  77. $sheet->setCellValue("N{$row}", $item->age_group);
  78. $sheet->setCellValue("O{$row}", $item->max_users);
  79. $sheet->setCellValue("P{$row}", $item->unit);
  80. $sheet->setCellValue("Q{$row}", $item->series);
  81. $sheet->setCellValue("R{$row}", $item->trademark);
  82. $sheet->setCellValue("S{$row}", $item->note);
  83. $this->addImage($sheet, $item, $row);
  84. $row++;
  85. }
  86. });
  87. if ($row > 2) {
  88. $sheet->getStyle('A1:S'.($row - 1))
  89. ->getBorders()
  90. ->getAllBorders()
  91. ->setBorderStyle(Border::BORDER_THIN);
  92. $sheet->getStyle('A2:S'.($row - 1))->getAlignment()
  93. ->setVertical(Alignment::VERTICAL_TOP)
  94. ->setWrapText(true);
  95. }
  96. foreach (['A' => 8, 'B' => 18, 'C' => 16, 'D' => 38, 'E' => 24, 'F' => 28] as $column => $width) {
  97. $sheet->getColumnDimension($column)->setWidth($width);
  98. }
  99. foreach (range('G', 'S') as $column) {
  100. $sheet->getColumnDimension($column)->setWidth(18);
  101. }
  102. $directory = 'export/common_catalog';
  103. $filename = 'common_catalog_'.now()->format('Y-m-d_H-i-s').'.xlsx';
  104. $relativePath = "{$directory}/{$filename}";
  105. Storage::disk('public')->makeDirectory($directory);
  106. (new Xlsx($spreadsheet))->save(Storage::disk('public')->path($relativePath));
  107. $spreadsheet->disconnectWorksheets();
  108. $link = url('/storage/'.$relativePath);
  109. File::query()->create([
  110. 'link' => $link,
  111. 'path' => $relativePath,
  112. 'user_id' => $userId,
  113. 'original_name' => $filename,
  114. 'mime_type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  115. 'is_generated' => true,
  116. ]);
  117. return $link;
  118. }
  119. private function addImage(Worksheet $sheet, CommonCatalogItem $item, int $row): void
  120. {
  121. $path = $item->imageFile?->path;
  122. if (! $path || ! Storage::disk('public')->exists($path)) {
  123. return;
  124. }
  125. $drawing = new Drawing;
  126. $drawing->setName($item->article);
  127. $drawing->setPath(Storage::disk('public')->path($path));
  128. $drawing->setCoordinates("B{$row}");
  129. $drawing->setHeight(68);
  130. $drawing->setOffsetX(4);
  131. $drawing->setOffsetY(4);
  132. $drawing->setWorksheet($sheet);
  133. $sheet->getRowDimension($row)->setRowHeight(56);
  134. }
  135. }