批量导入数据是一个有用的功能,可以将存储在文件中的记录添加到数据库中。数据可以存储在 - CSV, Excel, XML, ODS等格式。
在本教程中,我将展示如何在Laravel 8项目中使用Laravel Excel包导入CSV和Excel数据到MySQL数据库。

内容
1.安 装软件包
要求 -
- PHP:
^7.2\|^8.0 - Laravel:
^5.8 - PhpSpreadsheet:
^1.21 - psr/simple-cache:
^1.0 - 启用了PHP扩展
php_zip - 启用了PHP扩展
php_xml - 启用了PHP扩展
php_gd2 - 已启用的PHP扩展名
php_iconv - 已启用的PHP扩展名
php_simplexml - 已启用的PHP扩展程序
php_xmlreader - 已启用的PHP扩展
php_zlib
使用composer安装软件包 -
composer require maatwebsite/excel
如果你在执行上述命令时遇到了错误,那么请执行下面的命令------
composer require psr/simple-cache:^1.0 maatwebsite/excel
之后再执行--
composer require maatwebsite/excel
2.更 新app.php
- 打开
config/app.php文件。 - 在
'providers'中添加以下内容:Maatwebsite\Excel\ExcelServiceProvider::class-
'providers' => [
....
....
....
Maatwebsite\Excel\ExcelServiceProvider::class
];
- 添加以下内容
'Excel' => Maatwebsite\Excel\Facades\Excel::class在'aliases'-
'aliases' => [
....
....
....
'Excel' => Maatwebsite\Excel\Facades\Excel::class
];
3.发 布软件包
运行命令 -
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider" --tag=config
这将在config/ 中创建一个新的excel.php 文件。
4.数 据库配置
打开.env 文件。
指定主机、数据库名称、用户名和密码:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tutorial
DB_USERNAME=root
DB_PASSWORD=
5.创 建表
- 使用迁移创建一个新的表
Employees,并添加一些记录:
php artisan make:migration create_employees_table
- 现在,从项目根目录导航到
database/migrations/文件夹。 - 找到一个以
create_employees_table结尾的PHP文件并打开它。 - 在
up()方法中定义表的结构:
public function up()
{
Schema::create('employees', function (Blueprint $table) {
$table->id();
$table->string('username');
$table->string('name');
$table->string('email');
$table->smallInteger('age');
$table->timestamps();
});
}
- 运行迁移 -
php artisan migrate
- 表已经被创建。
6.模 型
- 创建
Employees模型:
php artisan make:model Employees
- 打开
app/Models/Employees.php文件。 - 使用
$fillable属性指定大量可分配的模型属性 - 用户名、姓名、电子邮件和年龄。
完成的代码
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Employees extends Model
{
use HasFactory;
protected $fillable = [
'username','name','email','age'
];
}
7.创 建导入类
我正在创建2个导入类,只是为了举例说明 --
1.EmployeesImport类 -
php artisan make:import EmployeesImport --model=Employees
- 打开
app/Imports/EmployeesImport.php文件。 - 类有1个方法 -
- model()从
$row数组中读取数值,如果email id不存在于employees表中,则插入一条记录,否则返回null。
- model()从
注意这个导入类从第一行开始读取记录。我在下一个导入类中解释了如何跳过包含标题的第一行。
CSV文件中没有标题行 -
| 用户1 | 用户1 u1 | [email protected] | 28 |
| 用户2 | 用户2 u2 | [email protected] | 24 |
已完成的代码
<?php
namespace App\Imports;
use App\Models\Employees;
use Maatwebsite\Excel\Concerns\ToModel;
class EmployeesImport implements ToModel {
/**
* @param array $row
*
* @return \Illuminate\Database\Eloquent\Model|null
*/ public function model(array $row) {
// Check email already exists
$count = Employees::where('email',$row[2])->count();
if($count > 0){
return null;
}
return new Employees([
'username' => $row[0],
'name' => $row[1],
'email' => $row[2],
'age' => $row[3],
]);
}
}
2.Employees2Import类 -
php artisan make:import Employees2Import --model=Employees
- 打开
app/Imports/Employees2Import.php文件。 - 类有2个方法
- collection() 验证
$rows阵列数据。如果验证成功,如果电子邮件ID不存在于employees表中,则插入记录,否则返回错误。
- collection() 验证
注意如果
WithHeadingRow,那么$rows数组包含行标题作为关键名称而不是索引。
-
- headingRow() 返回标题索引位置。
带有标题行的CSV文件 -
| 用户名 | 名称 | 电子邮件 | 年龄 |
|---|---|---|---|
| yssyogesh | Yogesh singh | [email protected] | 28 |
| bsonarika | 索纳里卡-巴多里亚 | [email protected] | 28 |
| 维沙尔 | 韋沙爾-薩胡 | [email protected] | 31 |
已完成的代码
<?php
namespace App\Imports;
use App\Models\Employees;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Illuminate\Support\Facades\Validator;
class Employees2Import implements ToCollection ,WithHeadingRow
{
public function collection(Collection $rows){
// Validate
Validator::make($rows->toArray(), [
'*.username' => 'required|string',
'*.name' => 'required|string',
'*.email' => 'required|email',
'*.age' => 'required|integer',
],[
'*.username.required'=> "The username field is required.",
'*.username.string'=> "The username must be string.",
'*.name.required'=> "The name field is required.",
'*.name.string'=> "The name must be string.",
'*.email.required'=> "The email field is required.",
'*.email.email'=> "The email must be a valid email address.",
'*.age.integer'=> "The age must be an integer."
])->validate();
foreach ($rows as $row) {
// Check email already exists
$count = Employees::where('email',$row['email'])->count();
if($count > 0){
continue;
}
Employees::create([
'username' => $row['username'],
'name' => $row['name'],
'email' => $row['email'],
'age' => $row['age'],
]);
}
}
// Specify header row index position to skip
public function headingRow(): int {
return 1;
}
}
8.路 线
- 打开
routes/web.php文件。 - 定义3条路线 -
- / 加载索引视图。
- employees/importdata 发布导入数据的路由。
- employees/validateandimportdata 发布验证和导入数据的路由。
完成的代码
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\EmployeesController;
Route::get('/', [EmployeesController::class, 'index'])->name('home');
Route::post('employees/importdata/', [EmployeesController::class, 'importData'])->name('employees.importdata');
Route::post('employees/validateandimportdata/', [EmployeesController::class, 'validateAndImportdata'])->name('employees.validateandimportdata');
9.控 制器
- 创建
EmployeesController控制器:
php artisan make:controller EmployeesController
- 打开
app/Http/Controllers/EmployeesController.php文件。 - 导入
EmployeesImport,Employees2Import和Excel。 - 创建3个方法
- index()加载
index视图。 - importdata() 导入调用
Excel::import()。
- index()加载
传递2个参数 -
-
EmployeesImport类的实例。- 传递选定的文件'temp'位置。
-
- validateAndImportdata()再次调用
Excel::import()。
- validateAndImportdata()再次调用
传递2个参数--类实例:
-
Employees2Import类实例。- 传递存储的文件位置(我把文件存储在
public/employees.xlsx文件夹中)。
完成代码
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Imports\EmployeesImport;
use App\Imports\Employees2Import;
use Excel;
class EmployeesController extends Controller
{
public function index(){
return view('index');
}
// Import data
public function importdata(Request $request){
Excel::import(new EmployeesImport, $request->file('file')->store('temp'));
return back()->with('success', 'Import successfully!');
}
// Validate and Import data
public function validateAndImportdata(Request $request){
Excel::import(new Employees2Import, "employees.xlsx");
return back()->with('success', 'Import successfully!');
}
}
10.查 看
在resources/views/ 文件夹中创建index.blade.php 文件。
创建2个<form> -
- 在第1个
<form >,设置动作为{{ route('employees.importdata') }}。创建一个文件元素和一个提交按钮。 - 在第2个
<form>,设置动作为{{ route('employees.validateandimportdata') }}。创建一个提交按钮。
在$errors->all() 循环,以显示错误。
完成的代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>How to Import data into MySQL database in Laravel 8</title>
<!-- CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" >
</head>
<body>
<div class="container mt-5">
<!-- Success message -->
@if(Session::has('success'))
<div class="alert alert-success">
{{ Session::get('success') }}
</div>
@endif
<form method='post' action="{{ route('employees.importdata') }}" enctype="multipart/form-data">
@csrf
<div class="mb-3">
<label for="file" class="form-label">File</label>
<input type="file" class="form-control" id="file" name="file" value="">
</div>
<button type="submit" class="btn btn-success">Import</button>
</form>
<!-- Import data with validation -->
<h2 class='mt-5'>Validate and import data</h2>
{{-- Display errors --}}
@if (count($errors) > 0)
<div class="row">
<div class="col-md-12 ">
<div class="alert alert-danger">
<ul>
@foreach($errors->all() as $error)
<li>{{ $error }} </li>
@endforeach
</ul>
</div>
</div>
</div>
@endif
<form method='post' action="{{ route('employees.validateandimportdata') }}" >
@csrf
<button type="submit" class="btn btn-success">Import</button>
</form>
</div>
</body>
</html>
11.输 出
12.总 结
在导入类中插入或更新记录之前,请确保验证记录。只有在导入文件有标题行的情况下才在导入类中指定WithHeadingRow 。
你可以从这里了解更多关于这个包的信息。
查看本教程,了解如何使用Laravel Excel包导出数据。
如果你觉得这个教程有帮助,那么不要忘记分享。