导入CSV文件到Laravel控制器并向两个表插入数据

问题描述 投票:0回答:4

所以我对 Laravel 完全是菜鸟,并且正在这里尝试一些东西。我想将 CSV 文件导入到两个表中,我有一个名为“列表”的表,它将获取列表名称和

client_id

然后我有一个名为“客户”的表,它将获得姓名、联系电话以及

client_id
list_id

我想要实现的是导入一个 CSV 文件,该文件将获取文件名并将其存储在列表中,然后通过 CSV 文件创建一个数组,并将数据与列表和客户端 ID 一起导入到客户表中。

我已经完成了第一部分,它正确插入到列表表中,现在如何从位于存储/文档中的 CSV 创建一个数组,然后将其插入到客户表中?

namespace App\Http\Controllers;

use Input;
use DB;
use Illuminate\Http\Request;
use App\Http\Requests\ListsRequest;
use App\Lists;
use App\Clients;
use App\Http\Requests;
use App\Http\Controllers\Controller;

class ListsController extends Controller {

    public function index()
    {
        // $list_items = Lists::all();
        $clients = Clients::all();

        return view('lists.show', compact('clients'));
    }

    public function store(Requests\ListsRequest $request)
    {
        $input = $request->input();
        Lists::create($input);

        if (Input::hasFile('name'))
        {

            $file = Input::file('name');
            $name = time() . '-' . $file->getClientOriginalName();

            $path = storage_path('documents');

            $file->move($path, $name);

            // All works up to here
            // All I need now is to create an array
            // from the CSV and insert into the customers database
        }
    }
}

我选择使用我已接受的答案,但我也尝试了其他答案并让它像这样工作。

public function store(Requests\ListsRequest $request)
{
    $input = $request->input();
    $client_id = $request->input('client_id');

    if (Input::hasFile('name'))
    {
        $file = Input::file('name');
        $name = time() . '-' . $file->getClientOriginalName();
        $path = storage_path('documents');

        Lists::create(['client_id' => $client_id, 'name' => $name]);

        $reader = Reader::createFromPath($file->getRealPath());
        // Create a customer from each row in the CSV file
        $headers = array();

        foreach ($reader as $index => $row)
        {
            if ($index === 0)
            {
                $headers = $row;
            } else
            {
                $data = array_combine($headers, $row);
                Customers::create($data);
            }
        }

        $file->move($path, $name);

        return view('clients');
    }
}
php laravel csv laravel-5
4个回答
57
投票

在 Laravel 中读取 CSV 文件并将其导入数据库需要 3 个步骤。

  1. 读取 CSV 文件
  2. 将其转换为数组
  3. 最后在我们的数据库中创建记录。

在开始之前,我创建了一个示例

test.csv
文件并将其放在文件夹下的公共文件夹中:

name,email,password
user1,[email protected],pasxxxxxxxxxword
user2,[email protected],pasxxxxxxxxxword
user3,[email protected],pasxxxxxxxxxword

步骤1和2;我创建了一个名为

csvToArray
的辅助函数,我现在只是将其放入我的控制器中(该函数受到此 link 的启发),它只是读取 CSV 文件并将其转换为数组:

function csvToArray($filename = '', $delimiter = ',')
{
    if (!file_exists($filename) || !is_readable($filename))
        return false;

    $header = null;
    $data = array();
    if (($handle = fopen($filename, 'r')) !== false)
    {
        while (($row = fgetcsv($handle, 1000, $delimiter)) !== false)
        {
            if (!$header)
                $header = $row;
            else
                $data[] = array_combine($header, $row);
        }
        fclose($handle);
    }

    return $data;
}

步骤3;这是我的最后一步,读取数组并将其插入到我们的数据库中:

public function importCsv()
{
    $file = public_path('file/test.csv');

    $customerArr = $this->csvToArray($file);

    for ($i = 0; $i < count($customerArr); $i ++)
    {
        User::firstOrCreate($customerArr[$i]);
    }

    return 'Jobi done or what ever';    
}

注意:此解决方案假设您的 Laravel 项目中有一个模型,并且数据库中有正确的表。

如果你使用

dd($customerArr)
你会得到这个


10
投票

在您的

store()
方法中,在
lists
表中创建记录,然后迭代 CSV 文件的内容并将数据插入到
customers
表中。为此,您应该在客户和列表之间创建“关系”。您最好使用类似 PHP League 的 CSV 包 的东西来读取此类文件: public function store(AddCustomersRequest $request) { // Get uploaded CSV file $file = $request->file('csv'); // Create list name $name = time().'-'.$file->getClientOriginalName(); // Create a list record in the database $list = List::create(['name' => $name]); // Create a CSV reader instance $reader = Reader::createFromFileObject($file->openFile()); // Create a customer from each row in the CSV file foreach ($reader as $index => $row) { $list->customers()->create($row); } // Redirect back to where you need with a success message }



4
投票

public function importCsv() { $file = public_path('file/test.csv'); $customerArr = $this->csvToArray($file); $data = []; for ($i = 0; $i < count($customerArr); $i ++) { $data[] = [ 'column_name1' => 'value', 'column_name2' => 'value2', .. so..on..and..on ]; //User::firstOrCreate($customerArr[$i]); } DB::table('table_name')->insert($data); return 'Jobi done or what ever'; }

这将调用数据库一次以插入任意数量的行。无论是 1000、100000 还是其他。
但是,如果您有一个巨大的 csv,这也会是一个问题,因为您需要分块插入。就像在 PostgreSQL 中一样,我注意到您可以在一条语句中插入最多 65000 行。也许我对这个数字是错误的,但每个数据库都有一个限制,你需要寻找它。


0
投票
[电子邮件受保护]

”“手机号码”=>“923070770597”“电话号码”=>“92090078601”“网站”= > "goole.com" "job_title" => "Web 开发人员" "business_address" => "巴基斯坦旁遮普省拉合尔" "口号" => "终身代码" "why_choose_us" => "loremipsum loremipsum loremipsum loremipsum loremipsum loremipsum loremipsum" " about_us”=>“loremipsum loremipsumloremipsum loremipsumloremipsum loremipsumloremipsum”“linkedin”=>“dummy.com”“facebook”=>“dummy.com”“twitter”=>“dummy.com”“instagram”=>“dummy.com” “youtube”=>“https://www.youtube.com/embed/arW24Ua0JJc”“reddit”=>“dummy.com”“telegram”=>“dummy.com”“whatsapp”=>“923070770597”] // Ensure the company and csv_file are found if (!$company || !$company->csv_file) { return abort(404); // Or handle the situation appropriately } $fileContents = public_path($company->csv_file); $lines = file($fileContents); enter code here // Check if there is at least one line in the CSV file if (count($lines) < 2) { return; // Or handle the situation where the CSV file is empty or has only headers } // Get headers from the first line $headers = str_getcsv(array_shift($lines)); foreach ($lines as $line) { $data = str_getcsv($line); // Combine headers with data to create an associative array $productAttributes = array_combine($headers, $data) ?: []; // Create a new Product with the attributes Product::create($productAttributes); }

© www.soinside.com 2019 - 2024. All rights reserved.