composer require "maatwebsite/excel"
続けてコンフィグファイルを生成します
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider"
config/excel.phpが生成されます。
次を変更します
'csv' => [
'enclosure' => '',
'line_ending' => "\r\n", // 改行を Windows形式にする
'use_bom' => true, // utf8 With BOM 形式にする
],
enclosure は CSVの各項目を囲む文字を設定します。 通常 “ ですが、いったん何もなしで設定しておいて blade 側で“を設定したいから無理だけセットするようにします。
ExportExcel クラスを生成します。
php artisan make:export ExportExcel
ファイル app/Exports/ExportExcel.php が自動生成されます。
次のように変更します。
<?php
namespace App\Exports;
use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
class ExportExcel extends DefaultValueBinder implements FromView, WithCustomValueBinder
{
private $view;
public function __construct(View $view)
{
$this->view = $view;
}
/**
* @return View
*/
public function view(): View
{
return $this->view;
}
/**
* 文字列型をセット
*/
public function bindValue(Cell $cell, $value)
{
// 全てを文字列型で返す
$cell->setValueExplicit($value, DataType::TYPE_STRING);
return true;
}
}
$cell->setValueExplicit($value, DataType::TYPE_STRING); メソッドですべてを文字列型に設定しています。
これを設定しないと「0001112222」は「1112222」として出力されてしまいます。
ファイル名 download.xlsx でダウンロードさせます。
$view = \view('estimates.excel_index', compact('estimates_rows'));
return \Excel::download(new \App\Exports\ExportExcel($view), 'download.xlsx');
<table>
<thead>
<tr>
<th>管理ID</th>
<th>プログラム名</th>
</tr>
</thead>
<tbody>
@forelse ( $programs as $program )
<tr>
<td>{{ $program->id }}</td>
<td>"{{ str_replace('"','""',$program->name) }}"</td>
</tr>
@empty
データがありません
@endforelse
</tbody>
</table>
1カラム目は クォーテーション 無し
2カラム目は クォーテーション あり
としています。
ファイル名を download.csv のように拡張子をCSVにするだけでokです
$view = \view('estimates.excel_index', compact('estimates_rows'));
return \Excel::download(new \App\Exports\ExportExcel($view), 'download.csv');
\Excel::download(new \App\Exports\ExportExcel($view), 'download.csv');
とすると、storage/ ディレクトリ直下にファイルが保存されます。
一旦 utf-8 のCSVファイルを tmp/myfile.csv 保存し sjis に変換してダウンロードさせます (メモリ上で utf-8 sjis 変換を行なっているのでファイルサイズが大きい場合はメモリエラーになります。 ファイルを1行ずつ処理するように適宜コードを書き換えてください)
// いったんutf8で保存
$file_path = 'tmp/myfile.csv';
$filename = pathinfo($file_path, PATHINFO_BASENAME);
\Excel::store(new \App\Exports\ExportExcel($view), $file_path);
// sjisダウンロード
$disk = \Storage::disk('local');
$content = $disk->get($file_path);
// remove BOM
$bom = hex2bin('EFBBBF');
$content = preg_replace("/^{$bom}/", '', $content);
// utf-8 to sjis
$content = mb_convert_encoding($content, 'sjis', 'UTF-8');
$headers = [
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename="' . $filename . '"'
];
return \Response::make($content, 200, $headers);