Laravel — Импорт Excel с веб-сайта, хранящийся только в хранилище, но не в БД

#laravel #import #maatwebsite-excel

Вопрос:

Я импортирую файл Excel с использованием конечных точек Laravel-8 и пакета Maatwebsite-3.1.

Я сделал это так, что загруженный файл Excel сначала попадет в хранилище (хранилище/file_imports/student_imports). Затем Laravel забирает его оттуда, сохраняет в таблице БД через StudentImport с помощью веб-сайтов.

СтудентИмпорт:

 <?php

  namespace AppImports;

  use AppModelsUser;
  use AppModelsStudent;
  use IlluminateSupportFacadesHash;
  use IlluminateSupportFacadesDB;
  use IlluminateSupportStr;
  use IlluminateSupportFacadesAuth;
  use IlluminateSupportFacadesPassword;
  use IlluminateValidationRule;
  use MaatwebsiteExcelConcernsToModel;
  use MaatwebsiteExcelConcernsImportable;
  use MaatwebsiteExcelConcernsWithBatchInserts;
  use MaatwebsiteExcelConcernsWithValidation;
  use MaatwebsiteExcelConcernsWithHeadingRow;
  use MaatwebsiteExcelConcernsSkipsErrors;
  use MaatwebsiteExcelConcernsSkipsOnError;
  use MaatwebsiteExcelConcernsSkipsFailures;
  use MaatwebsiteExcelConcernsSkipsOnFailure;
  use IlluminateSupportFacadesValidator;
  use MaatwebsiteExcelConcernsSkipsEmptyRows;
  use MaatwebsiteExcelValidatorsFailure;
  use Throwable;

class StudentImport implements
  ToModel,
  WithValidation,
  WithHeadingRow,
  SkipsOnError,
  SkipsOnFailure,
  WithBatchInserts
{
protected $companyId;

public function __construct()
{
    $this->companyId = Auth::user()->company_id;
}

use Importable, SkipsErrors, SkipsFailures;

public function model(array $row)
{
    $student_data = [
        'first_name'                        => $row[0],
        'other_name'                        => $row[1] ?? '',
        'last_name'                         => $row[2],
        'email'                             => preg_replace('/s /', '', strtolower($row[3])),
        'gender'                            => $row[4],
        'nationality_id'                    => $this->getNationality() ?? '',
        'school_id'                        => Auth::user()->school_id,
    ];
    $student = Student::create($student_data);

    if (User::where('email', '=', $student->email)->exists()) {
        $user = User::update([
            'first_name'                        => $student->first_name,
            'other_name'                        => $student->other_name,
            'last_name'                         => $student->last_name,
            'complete_profile'                  => 1,
            'active'                            => 1,
            'user_type'                         => 'Driver',
            'company_id'                        => Auth::user()->company_id,
            'updated_at'                        => date("Y-m-d H:i:s"),
            'updated_by'                        => Auth::user()->id,
        ]);
     }else{
        $user = User::create([
            'email'                             => $student->email,
            'username'                          => strtok($row[3], '@'),
            'password'                          => bcrypt("123456"),
            'first_name'                        => $student->first_name,
            'other_name'                        => $student->other_name,
            'last_name'                         => $student->last_name,
            'activation_token'                  => str_random(10),
        ]);
     }
}

public function headingRow(): int
{
    return 1;
}

public function getRowCount(): int
{
    return $this->rows;
}

public function customValidationAttributes()
{
    return [
        '0'     => 'First Name',
        '1'     => 'Other Name',
        '2'     => 'Last Name',
        '3'     => 'Email',
        '4'     => 'Gender',
    ];
}

public function rules(): array
{
    return [
        '*.0' => [
            'required',
            'string',
            'max:50'
        ],
        '*.1' => [
            'nullable',
            'string',
            'max:50'
        ],
        '*.2' => [
            'required',
            'string',
            'max:50'
        ],
        '*.3' => [
            'required',
            'email',
            'max:100',
            Rule::unique('studentss')->where(function ($query) {
                return $query->where('school_id', Auth::user()->school_id);
            })
        ],
        '*.4' => [
            'required',
            'string',
            'max:20'
        ],
    ];
}

public function batchSize(): int
{
    return 1000;
}

public function chunkSize(): int
{
    return 1000;
}

public function onFailure(Failure ...$failures)
{
    // Handle the failures how you'd like.
}

public function customValidationMessages()
{
    return [
        '1.in' => 'Custom message for :attribute.',
        'nim.unique' => 'Custom message',
    ];
}
}
 

Контроллер:

 public function importStudent(Request $request)
{
try {
    $user = Auth::user()->id;
    $validator = Validator::make($request->all(), [
        'document' => 'file|mimes:xlsx|max:10000',
    ]);
    if($validator->fails()) {
        return $this->error($validator->errors(), 401);
    } else {
        $check = User::where('id', $user)->pluck('id');
        if($check[0] !== null || $check[0] !== undefined) {

            $file = $request->file('document');
            $file->move(public_path('storage/file_imports/student_imports'), $file->getClientOriginalName());
            Excel::import(new StudentImport, public_path('storage/file_imports/student_imports/' . $file->getClientOriginalName() ));
            return $this->success('Students Successfully Imported.', [
                'file'         => $file
            ]);
        } else {
            return $this->error('Not allowed', 401);
        }
    }
    } catch(Exception $e) {
        return $this->error($e->getMessage());
    }
}
 

Как я уже говорил ранее, сначала он сохранит файл Excel в:

storage/file_imports/student_imports

Затем выберите его оттуда и сохраните в базе данных.

Этот код находится в контроллере выше.

Файл хранится в

public/storage/file_imports/student_imports

как и ожидалось, но в базе данных ничего не найдено. Да, он отображает успех без ошибок.

В чем может быть проблема и как ее решить?

Спасибо

Ответ №1:

model метод в вашем StudentImport классе должен возвращать новый экземпляр модели Eloquent.

Вы не должны вызывать метод создания или обновления через свою модель здесь.

Maatwebsite-Excel управляет процессом вставки с помощью собственного менеджера. Проверьте исходный код.

Комментарии:

1. Как теперь выполнить инструкцию update и if?

2. Используйте расстраивание. docs.laravel-excel.com/3.1/imports/model.html#upserting-models

3. Можете ли вы привести мне пример WithUpserts и где он используется? Я немного сбит с толку

4. Я добавляю пример. вставить. laravel.io/4f9c7c4c-b855-48eb-b101-7b1695804382

5. @EverArsian — Любезно позвольте мне задать еще один вопрос. Я замечаю, что вы все еще используете: $user = Пользователь::обновление([ … и $user = Пользователь::создание([ …. вместо нового