Используйте Laravel для загрузки таблицы в формате CSV

Я пытаюсь экспортировать таблицу базы данных, используя 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,

33

Решение

Почти все хорошо, кроме этой строки:

return Response::download($handle, 'tweets.csv', $headers);

Вы должны изменить эту строку на:

return Response::download($filename, 'tweets.csv', $headers);
25

Другие решения

Я наткнулся здесь, пытаясь понять, есть ли в 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);
}
57

РЕДАКТИРОВАТЬ: см. этот ответ для лучшего решения; Я оставлю свой ответ ниже, но учтите, что у него есть проблемы, такие как не экранирование значений и использование неоправданного количества памяти при генерации больших файлов.

Вы излишне создаете файл на диске; это вызывает дисковый ввод-вывод и вызывает проблемы, если два человека запрашивают этот URL-адрес в одно и то же время (два экземпляра платформы будут записывать в один и тот же файл, и будут происходить плохие вещи, такие как обслуживание поврежденного файла или сбой с исключением).

Используйте это вместо:

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);
});
15

Все выглядит хорошо, кроме этой строки:

return Response::download($handle, 'tweets.csv', $headers);

$handle не указывает на правильный путь к файлу. Это должен быть полный путь к файлу tweets.csv, например:

return Response::download($file, 'tweets.csv', $headers);

где $file должно быть что-то вроде $file = '/path/to/download/tweets.csv'

1

Вот полный код для загрузки 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);
1

попробуй это

 $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');
0

принимая во внимание текущий ответ с самым высоким рейтингом это 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();
}
0
По вопросам рекламы [email protected]