題名の通り
Excelにあるデータをweb上でも管理するアプリを作成しました。
こちらにあるExcelファイルのデータをWeb上で管理します
Excelファイル
※Macだと登録シートでデータの登録、一覧表示、変更、削除機能が使えないです。
#要件
・Web上でも顧客管理がしたい。(バックアップも兼ねて)
・検索したい
・検索した結果をExcelに出力したい
#機能
・ログイン
・Excelデータ取り込み & 出力
・検索
#実装
今回はExcelデータ取り込み & 出力のみ書いていこうと思います。
参考:検索機能
Web.php
Route::middleware('auth')->group(function () {
Route::get('/', 'ClientsController@index')->name('client.index');
Route::get('/export', 'ClientsController@export')->name('export');
Route::post('/import', 'ClientsController@import')->name('import');
});
ClientsController.php
<?php
namespace App\Http\Controllers;
use App\Client;
use Illuminate\Http\Request;
use App\Exports\ClientExport;
use App\Imports\ClientImport;
use Maatwebsite\Excel\Facades\Excel;
class ClientsController extends Controller
{
/**
* 顧客一覧
*/
public function index(Request $request)
{
$query = Client::query();
$client_name = $request->client_name;
//顧客名の値が存在&商品名の値が空ではなかった場合
if ($request->has('client_name') && $client_name !== '') {
$query->where('client_name', 'like', '%' . $client_name . '%')->get();
}
$datas = $query->paginate(15);
return view('client.index', ['datas' => $datas, 'client_name' => $client_name]);
}
/**
* Excelファイル出力
*/
public function export(Request $request)
{
$client_name = $request->client_name;
$export_name = $request->export_name;
if (!isset($export_name)) {
return back()->withErrors('ファイル名を入力して下さい');
}
if (!isset($client_name)) {
$client_name = "";
}
return Excel::download(new ClientExport($client_name), $export_name . '.xlsx');
}
/**
* Excelファイル取り込み
*/
public function import(Request $request)
{
$file = $request->file('file');
if (!isset($file)) {
return back()->withErrors('ファイルを選択して下さい');
}
if ($file->getClientOriginalName() <> "顧客データ.xlsm") {
return back()->withErrors('顧客データ.xlsmを選択して下さい');
}
$import = new ClientImport();
$import->onlySheets('データ'); //シート指定
Excel::import($import, $file);
return back()->withStatus('保存しました'); //withStatus()は戻った時にメッセージを表示
}
}
views\client\index.blade.php
@extends('layouts.app')
@section('content')
<!-- エラーメッセージ表示 -->
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<!-- 成功メッセージ表示 -->
@if (session('status'))
<div class="alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif
<div class="client">
<div class="container mt-4 offset-2 flex">
<div class="a a1" style="width:400px;">
<form class="search" enctype="multipart/form-data" action="{{route('client.index')}}" accept-charset="UTF-8" method="get">
@csrf
<div class="searchBox">
<div class="a2">
<h2 class="mr-2">顧客名</h2>
<input type="text" name="client_name" class="form-control" value="{{isset($client_name) ? $client_name : "" }}">
</div>
<div class="a2">
<h2 class="mr-2"> </h2>
<span class="input-group-btn">
<input type="submit" class="btn btn-success ml-4" value="検索">
</span>
</div>
</div>
</form>
</div>
<div class="a a2">
<form action="{{ route('import') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="form-group">
<input type="file" name="file">
<button class="btn btn-success"> 取込 </button>
</div>
</form>
<form action="{{ route('export') }}" method="GET" enctype="multipart/form-data">
@csrf
<div class="form-group" >
<input type="hidden" name="client_name" class="form-control" value="{{$client_name ? $client_name : "" }}">
<input type="text" name="export_name" placeholder="ファイル名を入力">
<button class="btn btn-secondary" style="width: 90px; margin-left: 121px;">出力</button>
</div>
</form>
<!-- <input type="submit" class="b btn btn-danger" value="登録"> -->
</div>
</div>
</div>
<div class="container mt-4">
<div class="panel panel-default">
<div class="panel-heading">全件{{$datas->total()}}件</div>
<div class="panel-body">
</div>
<table border="1" class="table" style="border-collapse: collapse">
@foreach($datas as $data)
<thead class="bg-success">
<tr>
<th>名前</th>
<th>連絡先</th>
<th>メールアドレス</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{$data->client_name}}</td>
<td>{{$data->client_PhoneNumber}}</td>
<td>{{$data->client_email}}</td>
</tr>
</tbody>
@endforeach
</table>
<!-- 検索結果を保持したままページネーションできる-->
{{ $datas->appends(request()->input())->links() }}
</div>
</div>
</div>
@endsection
app\Imports\ClientImport.php
<?php
namespace App\Imports;
use App\Client;
use Maatwebsite\Excel\Row;
use Maatwebsite\Excel\Concerns\OnEachRow;
use Maatwebsite\Excel\Concerns\WithHeadingRow;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
use Maatwebsite\Excel\Concerns\WithConditionalSheets;
class ClientImport implements OnEachRow, WithHeadingRow, WithMultipleSheets
{
/**
* トレイト
*/
use WithConditionalSheets;
/**
* どのシートをインポートするか指定
*/
public function conditionalSheets(): array
{
return [
'データ' => new ClientImport()
];
}
/**
* データ保存
*/
public function OnRow(Row $row)
{
$row = $row->toArray();
$client = Client::FirstOrNew(
// 重複除外カラムを指定
['client_email' => $row['メールアドレス']],
// データベースのカラムとエクセルのカラムを紐づけ
[
'client_PhoneNumber' => $row['連絡先'],
'client_name' => $row['顧客名'],
'type_id' => 1,
]
);
$client->save();
}
}
app\Exports\ClientExport.php
<?php
namespace App\Exports;
use App\Client;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\FromCollection;
class ClientExport implements WithHeadings, FromCollection
{
/**
* コンストラクト
*/
public function __construct(string $client_name)
{
$this->client_name = $client_name; // Where句のデータ
}
/**
* 条件データ取得
*/
public function collection()
{
return Client::where('client_name', 'like', '%' . $this->client_name . '%')->get(['client_name','client_PhoneNumber','client_email']);
}
/**
* Excel1フィールド指定
*/
public function headings(): array
{
return [
'顧客名',
'電話番号',
'メールアドレス'
];
}
}
#感想
・もっと工夫すればいいものが作れそうな気がする。
・出力したシートの名前もちゃんと設定できるようにしたらよかった。
今回はExcelファイルのデータをWeb上で管理するというのが目的だったので、いい感じにできたのではないのでしょうか。※実務で使うとなればまだまだですが・・・