前提・実現したいこと
- PHP7.2
- Laravel5.6
- MySQL5.6
イベント出欠確認システムを作成しております。
ユーザーごとのイベント毎の出欠を確認するCSV出力する機能の作成途中に行き詰っています。
どうぞよろしくお願いいたします。
usersテーブル
id | name | age |
---|---|---|
1 | 一郎 | 30 |
2 | 次郎 | 29 |
3 | 三郎 | 28 |
4 | 四子 | 27 |
5 | 五子 | 26 |
6 | 六子 | 25 |
eventsテーブル
id | name | date |
---|---|---|
1 | 第1回イベント | 2018-01-01 |
2 | 第2回イベント | 2018-02-01 |
3 | 第3回イベント | 2018-03-01 |
event_userテーブル
id | user_id | event_id | attendance |
---|---|---|---|
1 | 1 | 1 | 出席 |
2 | 3 | 1 | 出席 |
3 | 5 | 1 | 欠席 |
4 | 1 | 2 | 出席 |
5 | 5 | 2 | 出席 |
6 | 6 | 2 | 欠席 |
7 | 5 | 6 | 出席 |
8 | 1 | 6 | 出席 |
9 | 4 | 3 | 出席 |
10 | 6 | 5 | 欠席 |
※event_userテーブルのuser_id,event_id はそれぞれテーブルIDと外部キー接続しています。
CSV出力イメージ
|||第1回イベント|第2回イベント|第3回イベント|第4回イベント|第5回イベント|第6回イベント|
|:--:|:--:|:--:|:--:|
|ユーザー名|年齢|出欠状態|出欠状態|出欠状態|出欠状態|出欠状態|出欠状態|
|一郎|30|出席|出席||||出席
|次郎|29||||||
|三郎|28|出席|||||
|四子|27|||出席|||
|五子|26|欠席|出席||||出席
|六子|25||欠席|||欠席|
データ取得の方法が思いつかず、詰まっています。
・データがない座標(例えば次郎はどのイベントにも参加していない)も含めて、NULLで出力したい
・各ユーザー、各イベントの出欠状態が一覧で見れる形であれば現在のイメージ図にはこだわらない
該当のソースコード
app/UserController.php
/* ユーザーごとの出欠・領収履歴 CSVダウンロード機能*/ public function csvAttendanceListDownload(Event $event, User $user, EventUser $eventuser) { $current = Carbon::now(); $formats = array(); #ファイル名の指定 $file_name = 'event_user_' . date('YmdHis') . '.csv'; $file_path = 'temp/' . $file_name; #ファイルの生成 $file = new \SplFileObject($file_path, 'w'); if ($file === false) { throw new Exception('ファイルの書き込みに失敗しました。'); } #出力する項目 //ユーザーデータ $query_select_users = ['users.*', 'event_user.id as event_user_id', 'event_user.user_id as event_user_user_id', 'event_user.event_id as event_user_event_id', 'event_user.attendance_status']; //イベントに対応したユーザーの出欠・領収情報の表示 $query_select_event_user = ['event_user.*', 'users.id as userId', 'events.id as eventId']; #取得データの生成 //イベント情報 $events = Event::get(); $count = count($events); //ユーザー情報 $download_users = User::select($query_select_users) ->leftJoin('event_user', function ($join_user) { $join_user->on('users.id', '=', 'event_user.user_id'); }) ->get(); //ユーザー毎とイベント毎の出欠状態 $download_event_users = Event::select($query_select_event_user) ->leftJoin('event_user', function ($join_event_user) { $join_event_user->on('events.id', '=', 'event_user.event_id'); }) ->rightJoin('users', function ($join_event_user) { $join_event_user->on('users.id', '=', 'event_user.user_id'); }) ->get(); #各行列の配置 //1行目は必要なイベント名を出力 $column_name_1 = array('', ''); //2行目は各データとイベントのカウント数「出欠状態」項目の表示 $column_name_2 = array('ユーザー名', '年齢'); // foreach($download_events as $download_event=> $val) { $column_name_1[] = $add_event_name; } mb_convert_variables('SJIS-win', 'UTF-8', $column_name_1); $file->fputcsv($column_name_1); $i = 0; while ($i < $count) { $add = '出欠'; $column_name_2[] = $add; $i++; } mb_convert_variables('SJIS-win', 'UTF-8', $column_name_2); $file->fputcsv($column_name_2); #データの出力 foreach ($download_users as $download_user => $user) { #文字コード変換と整形 $formats = array( array( mb_convert_encoding($user->name, 'SJIS-win', 'UTF-8'),//ユーザー名 mb_convert_encoding($user->age, 'SJIS-win', 'UTF-8'),//年齢 ) ); foreach ($formats as $format => $value) { $file->fputcsv($value); }; } #出欠状態 foreach ($download_event_users as $download_event_user => $event_user) { $add_attendance_status = mb_convert_encoding($event_user->attendance, 'SJIS-win', 'UTF-8');//出欠状態 //出欠状態 CSVへ追記 foreach ($formats as $format => $value) { $value[] = $add_attendance_status; $file->fputcsv($value); } } #ファイルの情報 header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . $file_name . '"'); header('Content-Length: ' . filesize($file_path)); readfile($file_path); return response()->download($file_path); }
試したこと
現状は、event_userに登録されているユーザーデータがすべて出力され、座標など関係なく、出欠状態データが出力されています。
何か参考になりそうなサイトなどご紹介いただければ幸いです。
何卒よろしくお願いいたします。
データイメージ
ユーザー名 | 年齢 | (event_id) | (attendance) |
---|---|---|---|
一郎 | 30 | 1,2,,,,6 | 出席,出席,,,,出席 |
次郎 | 29 | ,,,,, | ,,,,, |
三郎 | 28 | 1,,,,, | 出席,,,,, |
四子 | 27 | ,,3,,, | ,,出席,,, |
五子 | 26 | 1,2,,,5, | 欠席,出席,,,出席 |
六子 | 25 | ,2,,,5, | ,欠席,,,欠席, |
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/01/10 10:07
2019/01/10 10:23
2019/01/11 10:35
2019/01/11 11:00