laravel5.1でExcel/CSVを取り扱う方法(laravel-excelというパッケージを使おうと思ったけど、結局コーディングだけで実装した)
http://www.maatwebsite.nl/laravel-excel/docs
サイトに書いてある通りに、composer.jsonに情報を書き込んだけどエラー。
1 2 3 |
php artisan vendor:publish [Symfony\Component\Debug\Exception\FatalErrorException] Class 'Maatwebsite\Excel\ExcelServiceProvider' not found |
キャッシュクリアしたら、ちゃんと動作した。
その前に、laravel-excelの記述をせずに、composer updateしたのが良かったのか?
1 2 3 |
php artisan config:cache Configuration cache cleared! Configuration cached successfully! |
ダウンロードされたので、これで使えるようになったはず。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
composer update > php artisan clear-compiled Loading composer repositories with package information Updating dependencies (including require-dev) - Installing tijsverkoyen/css-to-inline-styles (1.5.5) Downloading: 100% - Installing phpoffice/phpexcel (1.8.1) Downloading: 100% - Installing maatwebsite/excel (v2.1.2) Downloading: 100% Writing lock file Generating autoload files > php artisan optimize Generating optimized class loader |
と思ったら、単純なサンプルプログラムすら、エラーで動かない~。
Call to undefined method Maatwebsite\Excel\Facades\Excel::create()
色々とググったら、キャッシュが悪さをしているっぽい。リフレッシュしたら普通に動いた。
http://stackoverflow.com/questions/31491381/laravel-5-excel-installation-failure
php artisan config:cache
サンプル通りエクセルでもCSVでもダウンロードできた(exportもdownloadも同じ動作)
問題は、csvでutf-8だとエクセルで開けない(文字化けする)
なので、文字コードを設定する方法が書いてない…。しょうがないので内部コードを読んでいると、以下の関数で生成しているらしい。
PHPExcel_IOFactory::createWriter($this->excel, $this->format);
公式HPに行ってみると、FAQの先頭に以下のような記述が! http://phpexcel.codeplex.com/
There seems to be a problem with character encoding…
(文字コードに問題があるみたいなんだけど…。)
It is necessary to use UTF-8 encoding for all texts in PHPExcel. If the script uses different encoding then it is possible to convert the texts with PHP’s iconv() function.
(PHPExcelでは、全てのテキストはUTF-8を使用する必要があります。異なった文字コードを使いたい場合は、可能な限りiconv()関数で変換して使って下さい)
マジか~、道理で文字コードを指定する場所が全然無いわけだよ!
う~ん、これだと面倒だな。
1, カラムは、””で囲む
2, 文字コードは、sjis(エクセルで開くため)
の条件を満たせない…。
leage/CSVってのも試してみたけど、似たり寄ったりな感じだ。
http://qiita.com/kumechang/items/59ae5dc4b5d065e4d766
結局、以下のサイトを参考に自分でガリガリコーディングするのが一番早かった…。
http://xirasaya.com/?m=detail&hid=411
http://qiita.com/zaburo/items/07c5729e542030496006
User.php (テーブルに関わる処理なので、モデルクラスに実装)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
// 参考サイトにあったカラムをダブルクオーテーションで囲んでくれるfputcsv public static function mb_fputcsv($fp=null, $fields=null, $delimiter=',', $enclosure='"', $rfc=false) { $str=null; $chk=true; if($chk) { $cnt=0; $last=count($fields); foreach($fields as $val) { $cnt++; if(!$rfc) { // fputcsv()の挙動 $val = preg_replace('/(?<!\\\\)\"/u', '""', $val); }else { // RFC4180に準拠 $val = preg_replace('/\"/u', '""', $val); }// end if $str.= '"'. $val. '"'; if($cnt!=$last) $str.= ','; }// end foreach }// end if if($chk) $chk = fwrite($fp, $str); if($chk) $chk = fwrite($fp, "\r\n"); return $chk; }// end function // 条件付きでUsersテーブルをCSVエクスポートする public static function csv_export() { // なんかフラグが立っているユーザを取得 $users = User::where('flag', '=', 1)->orderby('id')->get(); //仮ファイルOpen $stream = fopen('php://temp','w'); // CSVヘッダ self::mb_fputcsv($stream,['id','name','email']); //loop foreach($users as $user) { //カラムを選択 self::mb_fputcsv($stream,[ sprintf("%05d",$user->employee_number), $user->id, $user->name, $user->email ]); //全カラムの場合はtoArray()を使えば良い //fputcsv($stream,$user->toArray()); } //ポインタの先頭へ rewind($stream); //いろいろ変換(文字コードと改行) $csv = mb_convert_encoding(str_replace(PHP_EOL, "\r\n", stream_get_contents($stream)), 'sjis-win', 'UTF-8'); //file名 $filename = "users_".date('Ymd').".csv"; //header $headers = array( 'Content-Type' => 'text/csv', 'Content-Disposition' => 'attachment; filename="' . $filename . '"' ); //response return \Response::make($csv, 200, $headers); } |