반응형

* 데이터 베이스는 연결과 Model, Migration 설정은 마친상태

 

Laravel Excel Install(laravel8 이전까지)

composer require maatwebsite/excel

 

ajax로 url을 호출하기 위해 form에 넣지 않았다

<div class="container">
    <div class="input-group mb-3">
        <div class="input-group-prepend">
            <input type="file" class="custom-file-input" id="upFile" name="upFile" required>
            <button type="button" class="btn btn-secondary btn-lg" id="upCsv">UPLOAD</button>
        </div>
    </div>
</div>

 

버튼 클릭시 ajax 호출

로딩 모달은 아래 사이트를 이용했다

https://www.jqueryscript.net/loading/Fullscreen-Loading-Modal-Indicator-Plugin-For-jQuery-loadingModal.html

 

Fullscreen Loading Modal / Indicator Plugin For jQuery - loadingModal

loadingModal is a simple yet customizable jQuery loading indicator plugin which displays a fullscreen loading modal / overlay with more than 10 CSS3 powered loading spinners.

www.jqueryscript.net

로딩모달 라이브러리 추가

<link rel="stylesheet" href="library/jquery.loadingModal.css">
<script src="library/jquery.loadingModal.js"></script>
$(document).ready(function(){
    $('#upCsv').click(function(e){
    	//php에 가져갈 값 세팅
        let fileInput = ($("#upFile")[0]).files[0];
        let mallTypeInput = $('input[name=mallType]:checked').val();
        let formData = new FormData();
        formData.append('upFile', fileInput);
        formData.append('mallType', mallTypeInput);

        $.ajax({
            headers: {
                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
            },
            url: '/orderList/upload',
            type: 'POST',
            dataType: 'html',
            enctype: 'multipart/form-data',
            processData: false,
            contentType: false,
            data: formData,
            beforeSend: function(){
                $('body').loadingModal({
                    text: '데이터를 불러오는 중'
                  });
            },
            success: function(result) {
                $('body').loadingModal('hide');
                alert(result);
                location.href = '/orderList';
            },
            error: function(e) {
                $('body').loadingModal('hide');
                alert('ERROR CHECK');
                location.href = '/orderList';
            }
        });
    });
});

 

순서로 보자면

1. 버튼 클릭시 OrderController의 parseImport 함수 호출

2. parseImport에서 엑셀을 1000개 단위로 나눈 후 return redirect("import") 반환

3. import 함수 호출 후 나눈 엑셀을 DB에 저장하고 파일 삭제

 

web.php 

Route::post('/orderList/upload', [OrderController::class, 'parseImport']);
Route::get('import',  [OrderController::class, 'import']);

Controller

<?php

namespace App\Http\Controllers;

use App\Imports\OrdersImport;
use App\Jobs\ProcessImportJob;
use App\Models\Order;
use Database\Seeders\OrderSeeder;
use Exception;
use GuzzleHttp\Psr7\Message;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Facades\Excel;
use SplFileObject;

class OrderController extends Controller
{
    public function parseImport(Request $req)
    {        
        $path = $req->file('upFile')->getRealPath();
        $file = file($path);
        $data = array_slice($file, 1);

        $parts = array_chunk($data, 1000);
        $i = 1;

        foreach($parts as $line) {
        	//임시로 저장할 파일의 파일명 중복 방지 
            $filename = base_path('database/csv/'.date('y-m-d-H-i-s').$i.'.csv');
            file_put_contents($filename, $line);
            $i++;
        }
        return redirect("import");
    }

    public function import()
    {    	
        $path = base_path('database/csv');   
        $fileNameArr = glob($path.'/*.csv');
        
        foreach ($fileNameArr as $file) {
            $csv_content = new SplFileObject($file);
            
            $csv_content->setFlags(
                \SplFileObject::READ_CSV |
                \SplFileObject::READ_AHEAD |
                \SplFileObject::SKIP_EMPTY |
                \SplFileObject::DROP_NEW_LINE
            );
            $lists = [];

            foreach ($csv_content as $i => $line) {
                if ($i >= 0) {
                    $lists[] = [
                        'ord_no'            => $line[0],                    //注文番号
                        'mall_id'           => '1',                         //==>後で削除
                        'ord_date'          => $line[1],                    //注文日
                        'pay_price'         => $line[2] ? $line[2] : 0,     //請求金額
                        'ord_total_price'   => $line[3],                    //合計金額
                        'point_price'       => $line[4] ? $line[4] : 0,     //ポイント利用額
                        'coupon_price'      => $line[5] ? $line[5] : 0,     //クーポン利用総額
                        'ord_email'         => $line[6],                    //注文者メールアドレス
                        'product_id'        => $line[7],                    //商品明細ID
                    ];
                }
            }

            DB::transaction(function () use ($lists) {
                $pack = [];
                $inserts = 0;
                foreach($lists as $list){
                    $pack[] = $list;
                    if(count($pack) >= 1000){
                        $inserts += count($pack);
                        Order::upsert(
                            //데이터
                            $pack,
                            //update조건
                            ['ord_no', 'product_id'],
                            //update 또는 insert 할 columns 
                            ['mall_id', 'ord_date', 'pay_price', 'ord_total_price', 'point_price', 'coupon_price', 'ord_email']);
                        $pack = [];
                    }
                }
                $inserts += count($pack);
    
                Order::upsert(
                    //데이터
                    $pack,
                    //update조건
                    ['ord_no', 'product_id'],
                    //update 또는 insert 할 columns
                    ['mall_id', 'ord_date', 'pay_price', 'ord_total_price', 'point_price', 'coupon_price', 'ord_email']);
                $pack = [];
            });

            //DB upsert 후 해당 파일 삭제
            unlink($file);
        }

        return '임포트 성공!';
    }
}

 

 

참고자료

https://reffect.co.jp/laravel/laravel_excel_master/

 

Laravel Excelをマスターしよう | アールエフェクト

Laravel環境では、Laravel ExcelをインストールすることでEXCELファイルかへのテーブルデータのエクスポート、作成したEXCELファイルからLaravelテーブルへインポートを行うことができます。日本語

reffect.co.jp

https://mtoo.tistory.com/69

 

PHP + AJAX를 사용하여 파일 업로드 하기

PHP + AJAX를 사용하여 파일 업로드 하기 enctype: 'multipart/form-data', // 필수 processData: false, // 필수 contentType: false, // 필수 data: formData, // 필수 ajax_file_upload_test.html : 파일 업로드 ajax 업로드 ajax_file_upload

mtoo.tistory.com

이것 저것 짬뽕한거라 참조자료 누락되었으면 미안합니다요

반응형

+ Recent posts