#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 управляет процессом вставки с помощью собственного менеджера. Проверьте исходный код.
- https://github.com/Maatwebsite/Laravel-Excel/blob/3.1/src/Imports/ModelImporter.php#L74
- https://github.com/Maatwebsite/Laravel-Excel/blob/3.1/src/Imports/ModelImporter.php#L92
- https://github.com/Maatwebsite/Laravel-Excel/blob/3.1/src/Imports/ModelManager.php#L45
- https://github.com/Maatwebsite/Laravel-Excel/blob/3.1/src/Imports/ModelManager.php#L64
Комментарии:
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 = Пользователь::создание([ …. вместо нового