knaka Tech-Blog

AI, IoT, DIYエレクトロニクス, データサイエンスについて投稿予定です。

Laravel 5.8で、CSVインポート機能

前のLaravel 関係で
CSVアップロードで、DB更新となります。

参考のコード

github.com

実装など

・コントローラ
計測値等の、管理ですが

https://github.com/kuc-arc-f/lara58a_5mdat/blob/master/app/Http/Controllers/MdatsController.php

    public function csv_import(Request $request){
        $user_id = Auth::id();
        // CSVファイルをサーバーに保存
        $temporary_csv_file = $request->file('csv_file')->store('csv');
        $fp = fopen(storage_path('app/') . $temporary_csv_file, 'r');
        // 一行目(ヘッダ)読み込み
        $headers = fgetcsv($fp);

        $column_names = [];
        // CSVヘッダ確認
        foreach ($headers as $header) {
            $result = Mdat::retrieveTestColumnsByValue($header, 'SJIS-win');
            if ($result === null) {
                fclose($fp);
                Storage::delete($temporary_csv_file);
                session()->flash('flash_message', '登録に失敗しました。CSVファイルのフォーマットが正しいことを確認してださい。');
                return redirect()->route('mdats.index');
            }
            $column_names[] = $result;
        }
        $csv_items = [];
        while ($row = fgetcsv($fp)) {
            mb_convert_variables('UTF-8', 'SJIS-win', $row);
            $csv_items[] = $row;
        }
        fclose($fp);
//debug_dump( $csv_items );
        $errors = $this->validator($csv_items );
        if(count($errors) > 0 ){
            return redirect()->back()->withErrors($errors)->withInput();
        }

        foreach ($csv_items as $row) {
            $date  =$row[0];
            if(!empty($date)){
                $mdat = Mdat::where('user_id', $user_id )
                ->where('date', $date )->first();
                if(empty($mdat) ){
                    $mdat = new Mdat();
                    $data["date"] = $row[0];
                    $data["hnum"] = $row[1];
                    $data["lnum"] = $row[2];
                    $data["user_id"] = $user_id;
                    $mdat->fill($data );
                    $mdat->save();
                }else{
                    $mdatArray = $mdat->toArray();
                    $mdat = Mdat::find($mdatArray["id"]);
                    $data["date"] = $row[0];
                    $data["hnum"] = $row[1];
                    $data["lnum"] = $row[2];
                    $mdat->fill($data );
                    $mdat->save();
                }    
            }
        }
        return redirect()->route('mdats.index');
    }

画面

f:id:knaka0209:20200104180311p:plain

csv出力

    public function csv_get(){
        $user_id = Auth::id();
        $dt = new Carbon(self::getYm_firstday());
        $now_month= $dt->format('Y-m');
        $startDt = $dt->format('Y-m-d');
        $endDt = $dt->endOfMonth()->format('Y-m-d');
//dd($startDt);
//exit                
        $mdats = Mdat::orderBy('date', 'asc')
        ->where("user_id", $user_id )
        ->whereBetween("date", [$startDt, $endDt ])
        ->get(['date', 'hnum', 'lnum'] )->toArray();
//dd($mdats );
        $csvHeader = ['date', 'Height' , 'Low'];
        array_unshift($mdats, $csvHeader);   
        $stream = fopen('php://temp', 'r+b');
        foreach ($mdats as $mdat ) {
            fputcsv($stream, $mdat );
        }
        rewind($stream);
        $csv = str_replace(PHP_EOL, "\r\n", stream_get_contents($stream));
        $csv = mb_convert_encoding($csv, 'SJIS-win', 'UTF-8');
        return response($csv )
            ->withHeaders([
                'Content-Type' => 'text/csv',
                'Content-Disposition' => 'attachment; filename="mdat.csv"',
            ]);

    }

Seeder

追加データのseederを追加しました。
https://github.com/kuc-arc-f/lara58a_5mdat/blob/master/database/seeds/MdatTableSeeder.php

php  artisan db:seed --class=MdatTableSeeder

Seederクラスのエラーが出る場合、 composerを再実行すると。エラーが回避できました
php composer.phar dump-autoload