ExportCommonCatalogService.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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\Style\NumberFormat;
  13. use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
  14. use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
  15. use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
  16. class ExportCommonCatalogService
  17. {
  18. public const HEADERS = [
  19. 'Артикул',
  20. 'Наименование',
  21. 'Вид',
  22. 'Габариты',
  23. null,
  24. null,
  25. 'Размер участка',
  26. null,
  27. 'Высота падения',
  28. 'Дополнительные сведения',
  29. "Единица измерения\nгабаритов",
  30. 'Вес, кг.',
  31. 'Объем, м3',
  32. 'Места',
  33. 'Состав',
  34. 'Возрастная группа',
  35. 'Макс.кол-во пользователей',
  36. 'Ед.',
  37. 'Внешний вид',
  38. 'Серия',
  39. 'ТМ',
  40. 'Калькулятор',
  41. 'строители',
  42. 'опт',
  43. 'рек',
  44. 'розница',
  45. 'проект',
  46. 'проект+м',
  47. 'пик',
  48. 'рек+10',
  49. ];
  50. public const SUBHEADERS = [
  51. null,
  52. null,
  53. null,
  54. 'Длина',
  55. 'Ширина',
  56. 'Высота',
  57. 'Длина',
  58. 'Ширина',
  59. null,
  60. null,
  61. null,
  62. null,
  63. null,
  64. null,
  65. null,
  66. null,
  67. null,
  68. null,
  69. null,
  70. null,
  71. null,
  72. null,
  73. null,
  74. 1.05,
  75. 1.1,
  76. 1.5,
  77. 2,
  78. 1.2,
  79. 'инд.',
  80. 1.21,
  81. ];
  82. public function handle(int $userId): string
  83. {
  84. $spreadsheet = new Spreadsheet;
  85. $sheet = $spreadsheet->getActiveSheet();
  86. $sheet->setTitle('Общие сведения');
  87. $sheet->fromArray(self::HEADERS, null, 'A1');
  88. $sheet->fromArray(self::SUBHEADERS, null, 'A2');
  89. $this->mergeHeaders($sheet);
  90. $this->styleHeaders($sheet);
  91. $row = 3;
  92. CommonCatalogItem::query()
  93. ->with('imageFile')
  94. ->orderBy('article')
  95. ->orderBy('calculator_name')
  96. ->chunk(200, function ($items) use ($sheet, &$row): void {
  97. foreach ($items as $item) {
  98. $sheet->setCellValueExplicit("A{$row}", $item->article, DataType::TYPE_STRING);
  99. $sheet->setCellValue("B{$row}", $item->calculator_name);
  100. $sheet->setCellValue("C{$row}", $item->kind);
  101. $sheet->setCellValue("D{$row}", $item->dimension_length);
  102. $sheet->setCellValue("E{$row}", $item->dimension_width);
  103. $sheet->setCellValue("F{$row}", $item->dimension_height);
  104. $sheet->setCellValue("G{$row}", $item->site_length);
  105. $sheet->setCellValue("H{$row}", $item->site_width);
  106. $sheet->setCellValue("I{$row}", $item->fall_height);
  107. $sheet->setCellValue("J{$row}", $item->additional_info);
  108. $sheet->setCellValue("K{$row}", $item->dimension_unit);
  109. $sheet->setCellValue("L{$row}", $item->weight);
  110. $sheet->setCellValue("M{$row}", $item->volume);
  111. $sheet->setCellValue("N{$row}", $item->places);
  112. $sheet->setCellValue("O{$row}", $item->composition);
  113. $sheet->setCellValue("P{$row}", $item->age_group);
  114. $sheet->setCellValue("Q{$row}", $item->max_users);
  115. $sheet->setCellValue("R{$row}", $item->unit);
  116. $sheet->setCellValue("T{$row}", $item->series);
  117. $sheet->setCellValue("U{$row}", $item->trademark);
  118. $sheet->setCellValue("V{$row}", match ($item->calculator_enabled) {
  119. true => 'да',
  120. false => 'нет',
  121. null => null,
  122. });
  123. $sheet->setCellValue("W{$row}", $item->builders_price);
  124. $sheet->setCellValue("X{$row}", $item->wholesale_price);
  125. $sheet->setCellValue("Y{$row}", $item->recommended_price);
  126. $sheet->setCellValue("Z{$row}", $item->retail_price);
  127. $sheet->setCellValue("AA{$row}", $item->project_price);
  128. $sheet->setCellValue("AB{$row}", $item->project_with_installation_price);
  129. $sheet->setCellValue("AC{$row}", $item->pik_price);
  130. $sheet->setCellValue("AD{$row}", $item->recommended_plus_10_price);
  131. $this->addImage($sheet, $item, $row);
  132. $row++;
  133. }
  134. });
  135. if ($row > 3) {
  136. $lastRow = $row - 1;
  137. $sheet->getStyle("A1:AD{$lastRow}")
  138. ->getBorders()
  139. ->getAllBorders()
  140. ->setBorderStyle(Border::BORDER_THIN);
  141. $sheet->getStyle("A3:AD{$lastRow}")->getAlignment()
  142. ->setVertical(Alignment::VERTICAL_TOP)
  143. ->setWrapText(true);
  144. $sheet->getStyle("W3:AD{$lastRow}")
  145. ->getNumberFormat()
  146. ->setFormatCode(NumberFormat::FORMAT_NUMBER_COMMA_SEPARATED1);
  147. }
  148. $this->setColumnWidths($sheet);
  149. $directory = 'export/common_catalog';
  150. $filename = 'common_catalog_'.now()->format('Y-m-d_H-i-s').'.xlsx';
  151. $relativePath = "{$directory}/{$filename}";
  152. Storage::disk('public')->makeDirectory($directory);
  153. (new Xlsx($spreadsheet))->save(Storage::disk('public')->path($relativePath));
  154. $spreadsheet->disconnectWorksheets();
  155. $link = url('/storage/'.$relativePath);
  156. File::query()->create([
  157. 'link' => $link,
  158. 'path' => $relativePath,
  159. 'user_id' => $userId,
  160. 'original_name' => $filename,
  161. 'mime_type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  162. 'is_generated' => true,
  163. ]);
  164. return $link;
  165. }
  166. private function mergeHeaders(Worksheet $sheet): void
  167. {
  168. foreach (['A', 'B', 'C', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W'] as $column) {
  169. $sheet->mergeCells("{$column}1:{$column}2");
  170. }
  171. $sheet->mergeCells('D1:F1');
  172. $sheet->mergeCells('G1:H1');
  173. }
  174. private function styleHeaders(Worksheet $sheet): void
  175. {
  176. $sheet->getStyle('A1:AD2')->applyFromArray([
  177. 'font' => ['bold' => true],
  178. 'fill' => [
  179. 'fillType' => Fill::FILL_SOLID,
  180. 'startColor' => ['rgb' => 'D9EAF7'],
  181. ],
  182. 'alignment' => [
  183. 'horizontal' => Alignment::HORIZONTAL_CENTER,
  184. 'vertical' => Alignment::VERTICAL_CENTER,
  185. 'wrapText' => true,
  186. ],
  187. ]);
  188. $sheet->getRowDimension(1)->setRowHeight(36);
  189. $sheet->getRowDimension(2)->setRowHeight(24);
  190. $sheet->freezePane('A3');
  191. }
  192. private function setColumnWidths(Worksheet $sheet): void
  193. {
  194. foreach ([
  195. 'A' => 14,
  196. 'B' => 38,
  197. 'C' => 24,
  198. 'D' => 13,
  199. 'E' => 13,
  200. 'F' => 13,
  201. 'G' => 13,
  202. 'H' => 13,
  203. 'I' => 15,
  204. 'J' => 28,
  205. 'K' => 18,
  206. 'L' => 14,
  207. 'M' => 14,
  208. 'N' => 11,
  209. 'O' => 28,
  210. 'P' => 18,
  211. 'Q' => 18,
  212. 'R' => 10,
  213. 'S' => 18,
  214. 'T' => 20,
  215. 'U' => 18,
  216. 'V' => 14,
  217. ] as $column => $width) {
  218. $sheet->getColumnDimension($column)->setWidth($width);
  219. }
  220. foreach (['W', 'X', 'Y', 'Z', 'AA', 'AB', 'AC', 'AD'] as $column) {
  221. $sheet->getColumnDimension($column)->setWidth(16);
  222. }
  223. }
  224. private function addImage(Worksheet $sheet, CommonCatalogItem $item, int $row): void
  225. {
  226. $path = $item->imageFile?->path;
  227. if (! $path || ! Storage::disk('public')->exists($path)) {
  228. return;
  229. }
  230. $drawing = new Drawing;
  231. $drawing->setName($item->article);
  232. $drawing->setPath(Storage::disk('public')->path($path));
  233. $drawing->setCoordinates("S{$row}");
  234. $drawing->setHeight(68);
  235. $drawing->setOffsetX(4);
  236. $drawing->setOffsetY(4);
  237. $drawing->setWorksheet($sheet);
  238. $sheet->getRowDimension($row)->setRowHeight(56);
  239. }
  240. }