将数据导入Laravel 8的MySQL数据库中的详细教程

396 阅读3分钟

批量导入数据是一个有用的功能,可以将存储在文件中的记录添加到数据库中。数据可以存储在 - CSV, Excel, XML, ODS等格式。

在本教程中,我将展示如何在Laravel 8项目中使用Laravel Excel包导入CSV和Excel数据到MySQL数据库。

How to Import data into MySQL database in Laravel 8


内容

  1. 安装软件包
  2. 更新app.php
  3. 发布软件包
  4. 数据库配置
  5. 创建表
  6. 模型
  7. 创建导入类
  8. 路线
  9. 控制器
  10. 查看
  11. 输出
  12. 结论

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。

注意这个导入类从第一行开始读取记录。我在下一个导入类中解释了如何跳过包含标题的第一行。

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 表中,则插入记录,否则返回错误。

注意如果WithHeadingRow ,那么$rows 数组包含行标题作为关键名称而不是索引。

    • headingRow() 返回标题索引位置。

带有标题行的CSV文件 -

用户名名称电子邮件年龄
yssyogeshYogesh 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,Employees2ImportExcel
  • 创建3个方法
    • index()加载index 视图。
    • importdata() 导入调用Excel::import()

传递2个参数 -

    1. EmployeesImport 类的实例。
    2. 传递选定的文件'temp'位置。
    • validateAndImportdata()再次调用Excel::import()

传递2个参数--类实例:

    1. Employees2Import 类实例。
    2. 传递存储的文件位置(我把文件存储在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包导出数据。

如果你觉得这个教程有帮助,那么不要忘记分享。