【问题标题】:Import CSV data using Laravel使用 Laravel 导入 CSV 数据
【发布时间】:2021-10-08 12:04:36
【问题描述】:

我正在尝试以 CSV 文件的形式浏览并提取其所有内容。

导入内容后,我需要将它们插入到我的 mysql 数据库表中,但在执行此操作之前,我需要检查这些记录是否存在。如果记录没有,请导入此寄存器。

我有标题和所有内容,我用这些信息创建了一个数组,但我不知道它是否 100% 正确。这是我的实际代码:

function csv_content_parser($content) {
        foreach (explode("\n", $content) as $line) {
          // Generator saves state and can be resumed when the next value is required.
          yield str_getcsv($line);
        }
    }

$archivo = fopen($route, "r");
        
        // Get content from csv file.
        $content = file_get_contents($adjunto);
        // Create arrays from csv file's lines.
        $data = array();
        $headers = array();
        $rows = array();
        //get all content
        foreach ($this->csv_content_parser($content) as $fields) {
            array_push($data, $fields);
        }
        //get headers
        foreach($data[0] as $dat){
            array_push($headers, $dat);
        }
        //get all content of csv without headers
        for($i=1; $i<count($data); $i++){
            array_push($rows, $data[$i]);
        }
        
        //close the file
        fclose($archivo);

csv文件的内容(它是一个示例文件)例如(我需要创建一个通用导入器):

Array
(
    [0] => Array
        (
            [0] => ggggg@gmail.com
            [1] => david
            [2] => 005
            [3] => hola
            [4] => eee
            [5] => eee
        )

    [1] => Array
        (
            [0] => ggggg@gmail.com
            [1] => david
            [2] => 005
            [3] => hola
            [4] => eee
            [5] => eee
        )

)

还有我的标题:

Array
(
    [0] => Email
    [1] => Name
    [2] => Identification
    [3] => Note
    [4] => Field Label 1
    [5] => Field Label 2
)

我的问题是:这是一个好的解决方案还是有更好的解决方案来做到这一点?我需要将此数据插入到我的数据库中。怎么会这样呢?

更新:

型号

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Listado extends Model
{
    protected $table = 'listado';

    protected $fillable = [
        'nomape', 'direccion', 'provincia', 'ciudad', 'cp', 'telefono', 'movil', 'id_teleoperadora'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [];

    public function scopeTodos( $query )
    {
        return $query->orderBy('nomape',   'ASC')->orderBy('telefono', 'ASC');
    }

    public function scopeSinAsignar( $query, $id_llamadas )
    {
        $query->whereIn('id', $id_llamadas)->whereNull('id_teleoperadora');
    }

    public static function Filtrado($request)
    {
        $query = self::query();

        if($request['direccion']) {
            $query->where('direccion', 'like', '%' .$request['direccion']. '%');
        }

        if($request['ciudad']) {
            $query->where('ciudad', $request['ciudad']);
        }

        if($request['cp']) {
            $query->where('cp', $request['cp']);
        }

        /*if($request['teleoperadora']) {
            $query->where('id_teleoperadora', $request['teleoperadora']);
        }*/

        return $query;
    }

    public function scopeConEstado( $query, $nombreEstado )
    {
        return $query->whereHas('llamada.estado', function ($query) use ($nombreEstado) {
            $query->whereNombre($nombreEstado);
        })->orWhereDoesntHave('llamada');
    }

    public function scopeConEstados( $query, $nombresEstado )
    {
        return $query->whereHas('llamada.estado', function ($query) use ($nombresEstado) {
            $query->whereIn('nombre', $nombresEstado);
        })->orWhereDoesntHave('llamada');
    }

    public function llamada()
    {
        return $this->hasOne('App\Llamada', 'id_listado', 'id')->latest();
    }

    public function llamada_test()
    {
        return $this->hasOne('App\Llamada', 'id', 'id_listado');
    }


    /**
     * RETURN OPERATOR
     */
    public function teleoperadora()
    {
        return $this->hasOne('App\User', 'id', 'id_teleoperadora')->withDefault(['nombre' => 'NINGUNA']);
    }

    /**
     * RETURN CALL DATA
     */
    public function callStatusName()
    {
        return $this->hasOne('App\llamada', 'id_listado', 'id');
    }


}

更新 2

我所有的功能代码

function csv_content_parser($content) {
        foreach (explode("\n", $content) as $line) {
          // Generator saves state and can be resumed when the next value is required.
          yield str_getcsv($line);
        }
    }

    public function uploadListing(Request $request)
    {
        $adjunto = $request->file('attached');
        $route = "";

        if(isset($adjunto)){
            $name = $adjunto->getClientOriginalName();
            $result = $adjunto->storeAs('importaciones', $name, 's4');

            $route =  public_path('storage/importaciones/'.$name);
        }else{
            return "Error al adjuntar recibo de envío, consulte al administrador del sistema";
        }


        //Abrimos nuestro archivo
        $archivo = fopen($route, "r");
        
        // Get content from csv file.
        $content = file_get_contents($adjunto);
        // Create arrays from csv file's lines.
        $data = array();
        $headers = array();
        $rows = array();
        //get all content
        foreach ($this->csv_content_parser($content) as $fields) {
            array_push($data, $fields);
        }
        //get headers
        foreach($data[0] as $dat){
            array_push($headers, $dat);
        }
        //get all content of csv without headers
        for($i=1; $i<count($data); $i++){
            array_push($rows, $data[$i]);
        }

        Listado::insertOrIgnore(array_map(function($row) {
            return array_combine($headers, $row);
        }, $rows));

        
        //Cerramos el archivo
        fclose($archivo);        
    }

更新 3

function csv_content_parser($content) {
        foreach (explode("\n", $content) as $line) {
          // Generator saves state and can be resumed when the next value is required.
          yield str_getcsv($line);
        }
    }

    public function uploadListing(Request $request)
    {
        $adjunto = $request->file('attached');
        $route = "";

        if(isset($adjunto)){
            $name = $adjunto->getClientOriginalName();
            $result = $adjunto->storeAs('importaciones', $name, 's4');

            $route =  public_path('storage/importaciones/'.$name);
        }else{
            return "Error al adjuntar recibo de envío, consulte al administrador del sistema";
        }


        //Abrimos nuestro archivo
        $archivo = fopen($route, "r");
        
        // Get content from csv file.
        $content = file_get_contents($adjunto);
        // Create arrays from csv file's lines.
        $data = array();
        $headers = array();
        $rows = array();
        //get all content
        foreach ($this->csv_content_parser($content) as $fields) {
            array_push($data, $fields);
        }
        //get headers
        foreach($data[0] as $dat){
            array_push($headers, $dat);
        }
        //get all content of csv without headers
        for($i=1; $i<count($data); $i++){
            array_push($rows, $data[$i]);
        }

        Listado::insertOrIgnore(array_map(function($row) use($headers) {
            return array_combine($headers, $row);
        }, $rows));

        
        //Cerramos el archivo
        fclose($archivo);        
    }

【问题讨论】:

  • 您说,您想将记录插入数据库,但我在您的代码中找不到任何尝试。为了做到这一点,您已经尝试过什么?如果没有,您在完成这项任务时遇到了什么困难?
  • $this-&gt;csv_content_parser() 是您编写的解析器还是它有什么作用?您是否需要任何特殊的逻辑或者您不使用fgetcsv() 的其他原因?
  • @shaedrich 感谢您的回复,我用我的函数 csv_content_parser() 编辑了我的问题,我正在使用这个函数从我的 csv 中获取所有行。我之前怎么说,我不知道这是否是更好的解决方案,但有了这个,我得到了我的标题和所有内容。我没有在我的数据库中导入托盘,因为我不知道如何将关联数组插入到我的数据库中。感谢您的帮助
  • 啊,好的。使用内置函数 str_getcsv() 作为生成器的有趣解决方案。酷!
  • 既然你不知道如何在 Laravel 中使用查询(核心功能),我不认为你有 Eloquent 模型,对吧?

标签: php laravel csv laravel-5 csv-import


【解决方案1】:

作为per docs:

DB::table('listado')->insertOrIgnore(array_map(fn($row) => array_combine($headers, $row), $rows));

由于你有 Eloquent 模型,你可以使用 Eloquent 的insert() method

Listado::insertOrIgnore(array_map(fn($row) => array_combine($headers, $row), $rows));

既然你说了以下

我需要检查这些记录是否存在。如果记录没有,请导入此寄存器。

我选择了insertOrIgnore() 方法,但也许你想要别的东西。幸运的是,Laravel 为略有不同的用例提供了许多类似的方法。

在 PHP 7.4 之前,array_map(fn($row) =&gt; array_combine($headers, $row), $rows) 必须是:

array_map(function($row) use($headers) {
    return array_combine($headers, $row);
}, $rows)

【讨论】:

  • 感谢您的回复。我用我所有的模型编辑了我的问题
  • 我正在准备将您的代码插入我的代码中,但未加急返回错误 =>
  • 语法错误,意外的 '=>' (T_DOUBLE_ARROW),需要 ',' 或 ')'
  • 啊,你有一个旧的 PHP 版本。我会更新我的答案
  • 感谢您的帮助。我用更新 2 部分中的所有代码更新了我的问题
猜你喜欢
  • 2018-07-06
  • 2018-03-20
  • 2017-07-27
  • 1970-01-01
  • 1970-01-01
  • 2012-07-11
  • 2018-01-29
  • 2010-10-17
  • 2020-12-20
相关资源
最近更新 更多