Сообщество IT-специалистов
Ответы на любые вопросы об IT
Профессиональное развитие в IT
Удаленная работа для IT-специалистов
<?php namespace App\Nova\Actions; use Illuminate\Bus\Queueable; use Illuminate\Support\Facades\Hash; use Laravel\Nova\Actions\Action; use Illuminate\Support\Collection; use Laravel\Nova\Fields\ActionFields; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Laravel\Nova\Fields\Boolean; use Laravel\Nova\Fields\Text; class DownloadExcel extends Action { use InteractsWithQueue, Queueable, SerializesModels; private $columns; private $default_name; private $dates; private $foreign; private $enums; private $borders; public $name = 'Экспорт в Excel'; public function __construct($columns, $default_name = null, $dates = [], $foreign = [], $enums = [], $borders = false) { $this->columns = $columns; $this->default_name = $default_name; $this->dates = $dates; $this->foreign = $foreign; $this->enums = $enums; $this->borders = $borders; } /** * Perform the action on the given models. * * @param \Laravel\Nova\Fields\ActionFields $fields * @param \Illuminate\Support\Collection $models * @return mixed */ public function handle(ActionFields $fields, Collection $models) { $attrs = $fields->getAttributes(); unset($attrs['file_name']); $l = 'A'; $columns = []; foreach ($attrs as $column => $value) { if ($value) { if (in_array($column, $this->dates)) $type = 'date'; elseif (in_array($column, array_keys($this->foreign))) $type = 'foreign'; elseif (in_array($column, array_keys($this->enums))) $type = 'enum'; else $type = 'string'; $columns[$l++] = [ 'name' => $column, 'type' => $type, ]; } } $array = []; foreach ($models as $i => $model) { $t = []; foreach ($columns as $l => $column) { $value = ''; switch ($column['type']) { case 'date': if ($model->{$column['name']}) { $value = \PhpOffice\PhpSpreadsheet\Shared\Date::PHPToExcel($model->{$column['name']}); } break; case 'foreign': if (is_array($this->foreign[$column['name']])) { if (isset($model->{$this->foreign[$column['name']][0]})) $value = $model->{$this->foreign[$column['name']][0]}->{$this->foreign[$column['name']][1]}; } elseif (isset($model->{$column['name']})) $value = $model->{$column['name']}->{$this->foreign[$column['name']]}; break; case 'enum': if (isset($model->{$column['name']})) $value = $this->enums[$column['name']][$model->{$column['name']}]; break; default: $value = $model->{$column['name']} ?? ''; break; } $t[$l] = $value; } $array[] = $t; } return $array; } public function handleResult(ActionFields $fields, $results) { $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet(); try { $spreadsheet->setActiveSheetIndex(0); } catch(\PhpOffice\PhpSpreadsheet\Exception $e) { return Action::danger('Произошла ошибка, обратитесь а администратору.'); } $attrs = $fields->getAttributes(); $file_name = $attrs['file_name']; unset($attrs['file_name']); $l = 'A'; $columns = []; try { $active_sheet = $spreadsheet->getActiveSheet(); } catch(\PhpOffice\PhpSpreadsheet\Exception $e) { return Action::danger('Произошла ошибка, обратитесь а администратору.'); } foreach ($attrs as $column => $value) { if ($value) { $active_sheet->setCellValue($l . '1', $this->columns[$column]); $active_sheet->getColumnDimension($l)->setAutoSize(true); if (in_array($column, $this->dates)) $type = 'date'; elseif (in_array($column, array_keys($this->foreign))) $type = 'foreign'; elseif (in_array($column, array_keys($this->enums))) $type = 'enum'; else $type = 'string'; $columns[$l++] = [ 'name' => $column, 'type' => $type, ]; } } $i = 2; foreach ($results as $result) foreach ($result as $r) { foreach ($columns as $l => $column) { if ($column['type'] === 'date') { $active_sheet->getStyle($l . $i) ->getNumberFormat()->setFormatCode('dd.mm.YYYY'); } $active_sheet->setCellValue($l . $i, $r[$l]); } $i++; } if ($this->borders) { $styleArray = ['borders' => ['allBorders' => ['borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN]]]; $active_sheet->getStyle('A1:' . --$l . ($i - 1))->applyFromArray($styleArray); } $fn = \Auth::user()->id . '-' . $file_name;//Hash::make($file_name); try { $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, "Xlsx"); $writer->save(storage_path("app/public/excel_tmp/$fn.xlsx")); } catch(\PhpOffice\PhpSpreadsheet\Exception $e) { return Action::danger('Произошла ошибка, обратитесь а администратору.'); } return Action::download( url('/download_excel?') . http_build_query([ 'path' => storage_path("app/public/excel_tmp/"), 'filename' => "$fn.xlsx", 'ffn' => "$file_name.xlsx", ]), "$file_name.xlsx" ); } public function fields() { $fields = [Text::make('Имя файла', 'file_name')->withMeta(["value" => $this->default_name])]; foreach ($this->columns as $name => $caption) { $fields[] = Boolean::make($caption, $name)->withMeta(["value" => "true"]); } return $fields; } }