Laravel
をcsv
ファイルとして使用して、データベーステーブルをエクスポートしようとしています。ユーザーがExport as CSV
ボタンを選択し、テーブルをcsv
ファイルとしてダウンロードできるようにしたいと思います。現在、このコードを取得していますが、機能していません:
私のボタン:
<a href="/all-tweets-csv" class="btn btn-primary">Export as CSV</a>
私のルート:
Route::get('/all-tweets-csv', function(){
$table = Tweet::all();
$filename = "tweets.csv";
$handle = fopen($filename, 'w+');
fputcsv($handle, array('Tweet text', 'screen name', 'name', 'created at'));
foreach($table as $row) {
fputcsv($handle, array($row['Tweet_text'], $row['screen_name'], $row['name'], $row['created_at']));
}
fclose($handle);
$headers = array(
'Content-Type' => 'text/csv',
);
return Response::download($handle, 'tweets.csv', $headers);
});
このエラーが返されます:
The file "Resource id #154" does not exist
そして、私はそれが存在しないファイルをダウンロードしようとしているためだということを集めました。 csv
としてダウンロードするためにコードを変更する代替方法はありますか。
この行を除いて、ほとんどすべてが正常です。
return Response::download($handle, 'tweets.csv', $headers);
この行を次のように変更する必要があります。
return Response::download($filename, 'tweets.csv', $headers);
Laravelにデフォルトで何かが組み込まれているかどうかを確認しようとしてここにつまずきました-この質問に対する答えは少し心配です。@andré-danielには、適切な方法は書かないことです最初にファイルを作成しますが、彼の実装は手動で値をまとめています。値に引用符やスペースなどが含まれていると失敗します。
これは、LaravelのResponse::stream
およびphpのfputcsv
は、各行を適切にフォーマットします(引用符をエスケープし、必要な文字列を引用します。 http://php.net/manual/en/function.fputcsv.php を参照してください。詳細については)
<?php
public function download()
{
$headers = [
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0'
, 'Content-type' => 'text/csv'
, 'Content-Disposition' => 'attachment; filename=galleries.csv'
, 'Expires' => '0'
, 'Pragma' => 'public'
];
$list = User::all()->toArray();
# add headers for each column in the CSV download
array_unshift($list, array_keys($list[0]));
$callback = function() use ($list)
{
$FH = fopen('php://output', 'w');
foreach ($list as $row) {
fputcsv($FH, $row);
}
fclose($FH);
};
return Response::stream($callback, 200, $headers);
}
編集: この答え を参照して、より良い解決策を見つけてください。以下に回答を残しますが、値をエスケープしない、大きなファイルを生成する場合に不当な量のメモリを使用するなどの問題があることに注意してください。
ディスク上にファイルを不必要に作成しています。ディスクIOを誘発し、2人がそのURLを正確に同時に要求すると問題が発生します(フレームワークの2つのインスタンスが同じファイルに書き込み、破損したサービスを提供するなどの悪いことが起こりますファイルまたは例外でクラッシュする)。
代わりにこれを使用してください:
Route::get('/all-tweets-csv', function() {
$tweets = Tweets::all();
// the csv file with the first row
$output = implode(",", array('Tweet text', 'screen name', 'name', 'created at'));
foreach ($tweets as $row) {
// iterate over each Tweet and add it to the csv
$output .= implode(",", array($row['Tweet_text'], $row['screen_name'], $row['name'], $row['created_at'])); // append each row
}
// headers used to make the file "downloadable", we set them manually
// since we can't use Laravel's Response::download() function
$headers = array(
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename="tweets.csv"',
);
// our response, this will be equivalent to your download() but
// without using a local file
return Response::make(rtrim($output, "\n"), 200, $headers);
});
現在の最高ランクの回答 を考慮すると、これはLaravel 5.7 CSV書き込みです。return
の変更に注意してください。
<?php
public function download()
{
$headers = [
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0'
, 'Content-type' => 'text/csv'
, 'Content-Disposition' => 'attachment; filename=galleries.csv'
, 'Expires' => '0'
, 'Pragma' => 'public'
];
$list = User::all()->toArray();
# add headers for each column in the CSV download
array_unshift($list, array_keys($list[0]));
$callback = function() use ($list) {
$FH = fopen('php://output', 'w');
foreach ($list as $row) {
fputcsv($FH, $row);
}
fclose($FH);
};
return (new StreamedResponse($callback, 200, $headers))->sendContent();
}
この行を除くすべてが見栄えが良い:
return Response::download($handle, 'tweets.csv', $headers);
$handle
は正しいファイルパスを指していません。以下のように、tweets.csvへのフルパスにする必要があります。
return Response::download($file, 'tweets.csv', $headers);
$file
は$file = '/path/to/download/tweets.csv'
のようなものでなければなりません
ここにCSVをダウンロードするための完全なコードがあります
$headers = array(
'Content-Type' => 'application/vnd.ms-Excel; charset=utf-8',
'Cache-Control' => 'must-revalidate, post-check=0, pre-check=0',
'Content-Disposition' => 'attachment; filename=abc.csv',
'Expires' => '0',
'Pragma' => 'public',
);
$filename = "doenload.csv";
$handle = fopen($filename, 'w');
fputcsv($handle, [
"id",
"name"
]);
DB::table("tablename")->chunk(100, function ($data) use ($handle) {
foreach ($data as $row) {
// Add a new row with data
fputcsv($handle, [
$row->id,
$row->name
]);
}
});
fclose($handle);
return Response::download($filename, "download.csv", $headers);
私はこれらの例をフォローしていましたが、私のコードでは動作しませんでした。私のプロジェクト用に書いたコードを例として添付します。これは、単なる例のガイドのように、OPには対応していません。私のデータはオブジェクトの配列の形式です
public function Export($data) {
$headers = array(
"Content-type" => "text/csv",
"Content-Disposition" => "attachment; filename=summary.csv",
"Pragma" => "no-cache",
"Cache-Control" => "must-revalidate, post-check=0, pre-check=0",
"Expires" => "0"
);
$columns = array('Period', 'RevenueArea', 'Subs');
$callback = function() use ($data, $columns)
{
$file = fopen('php://output', 'w');
fputcsv($file, $columns);
foreach($data as $items) {
fputcsv($file, array($items->PERIOD, $items->REVENUE_AREA, $items->SUBS));
}
fclose($file);
};
return Response::stream($callback, 200, $headers)->send();
}
私のreturnステートメントで気付いた場合、csvファイルを生成してダウンロードを初期化する-> send()を含めています。どことして-> sendContent();日付を画面にダンプするだけです。ファイルをダウンロードしていないのと同じ問題でこの投稿に出くわした場合は、公式ドキュメントを確認してください。
https://api.symfony.com/2.3/Symfony/Component/HttpFoundation/StreamedResponse.html
これを試して
$file_name = "abc";
$postStudent = Input::all();
$ck = DB::table('loan_tags')->select('LAN')->where('liabilitiesId', $postStudent['id'])->get();
$i = 0;
foreach ($ck as $row) {
$apps[$i]['LAN'] = $row->LAN;
$apps[$i]['Account_number'] = $postStudent['account_number'];
$apps[$i]['Bank_Name'] = $postStudent['bank_name'];
$i++;
}
ob_end_clean();
ob_start();
Excel::create($file_name, function($Excel) use($apps){
$Excel->sheet('Sheetname', function($sheet) use($apps){
$sheet->row(1, array(
'LAN', 'Account number' , 'Bank Name'
));
$k = 2;
foreach ($apps as $deta) {
$sheet->row($k, array($deta['LAN'], $deta['Account_number'], $deta['Bank_Name']
));
$k++;
}
});
})->download('xlsx');