Поэтому я сделал небольшой запрос ajax на мои reviewsController@export
.
Теперь, когда я console.log()
данные в моем методе успеха, ответ ajax показывает правильные данные. Однако мой CSV не скачал. Таким образом, у меня есть вся необходимая информация и вы создали csv.
Думаю, возможно, это связано с настройкой заголовков?
public function export() { header("Content-type: text/csv"); header("Content-Disposition: attachment; filename=file.csv"); header("Pragma: no-cache"); header("Expires: 0"); $reviews = Reviews::getReviewExport($this->hw->healthwatchID)->get(); $columns = array('ReviewID', 'Provider', 'Title', 'Review', 'Location', 'Created', 'Anonymous', 'Escalate', 'Rating', 'Name'); $file = fopen('php://output', 'w'); fputcsv($file, $columns); foreach($reviews as $review) { fputcsv($file, array($review->reviewID,$review->provider,$review->title,$review->review,$review->location,$review->review_created,$review->anon,$review->escalate,$review->rating,$review->name)); } exit(); }
-public function export() { header("Content-type: text/csv"); header("Content-Disposition: attachment; filename=file.csv"); header("Pragma: no-cache"); header("Expires: 0"); $reviews = Reviews::getReviewExport($this->hw->healthwatchID)->get(); $columns = array('ReviewID', 'Provider', 'Title', 'Review', 'Location', 'Created', 'Anonymous', 'Escalate', 'Rating', 'Name'); $file = fopen('php://output', 'w'); fputcsv($file, $columns); foreach($reviews as $review) { fputcsv($file, array($review->reviewID,$review->provider,$review->title,$review->review,$review->location,$review->review_created,$review->anon,$review->escalate,$review->rating,$review->name)); } exit(); }
-public function export() { header("Content-type: text/csv"); header("Content-Disposition: attachment; filename=file.csv"); header("Pragma: no-cache"); header("Expires: 0"); $reviews = Reviews::getReviewExport($this->hw->healthwatchID)->get(); $columns = array('ReviewID', 'Provider', 'Title', 'Review', 'Location', 'Created', 'Anonymous', 'Escalate', 'Rating', 'Name'); $file = fopen('php://output', 'w'); fputcsv($file, $columns); foreach($reviews as $review) { fputcsv($file, array($review->reviewID,$review->provider,$review->title,$review->review,$review->location,$review->review_created,$review->anon,$review->escalate,$review->rating,$review->name)); } exit(); }
-public function export() { header("Content-type: text/csv"); header("Content-Disposition: attachment; filename=file.csv"); header("Pragma: no-cache"); header("Expires: 0"); $reviews = Reviews::getReviewExport($this->hw->healthwatchID)->get(); $columns = array('ReviewID', 'Provider', 'Title', 'Review', 'Location', 'Created', 'Anonymous', 'Escalate', 'Rating', 'Name'); $file = fopen('php://output', 'w'); fputcsv($file, $columns); foreach($reviews as $review) { fputcsv($file, array($review->reviewID,$review->provider,$review->title,$review->review,$review->location,$review->review_created,$review->anon,$review->escalate,$review->rating,$review->name)); } exit(); }
Есть ли что-то, что я делаю неправильно здесь, или у Laravel есть что-то, чтобы удовлетворить это?
Попробуйте эту версию – это должно позволить вам получить хороший результат с помощью Response::stream()
.
public function export() { $headers = array( "Content-type" => "text/csv", "Content-Disposition" => "attachment; filename=file.csv", "Pragma" => "no-cache", "Cache-Control" => "must-revalidate, post-check=0, pre-check=0", "Expires" => "0" ); $reviews = Reviews::getReviewExport($this->hw->healthwatchID)->get(); $columns = array('ReviewID', 'Provider', 'Title', 'Review', 'Location', 'Created', 'Anonymous', 'Escalate', 'Rating', 'Name'); $callback = function() use ($reviews, $columns) { $file = fopen('php://output', 'w'); fputcsv($file, $columns); foreach($reviews as $review) { fputcsv($file, array($review->reviewID, $review->provider, $review->title, $review->review, $review->location, $review->review_created, $review->anon, $review->escalate, $review->rating, $review->name)); } fclose($file); }; return Response::stream($callback, 200, $headers); }
(Адаптировано из этого ответа SO: используйте Laravel для загрузки таблицы как CSV )
Попробуйте использовать обычную ссылку с target="_blank"
а не с помощью JavaScript / AJAX. Поскольку это открытие загрузки файлов на новой вкладке, пользовательский интерфейс не должен быть слишком неуклюжим.
Это может не отвечать на ваш вопрос напрямую, но я использую пакет под названием « thephpleague / csv » для этой цели …
Чтобы использовать этот пакет:
Поместите следующие инструкции «use» в ваш контроллер:
use Illuminate\Database\Eloquent\Collection; use League\Csv\Writer; use Schema; use SplTempFileObject;
и любые классы моделей, которые вы планируете использовать.
Абстрактный CSV, создающий код для функции (в вашем контроллере), например:
/** * A function to generate a CSV for a given model collection. * * @param Collection $modelCollection * @param $tableName */ private function createCsv(Collection $modelCollection, $tableName){ $csv = Writer::createFromFileObject(new SplTempFileObject()); // This creates header columns in the CSV file - probably not needed in some cases. $csv->insertOne(Schema::getColumnListing($tableName)); foreach ($modelCollection as $data){ $csv->insertOne($data->toArray()); } $csv->output($tableName . '.csv'); }
В вашем контроллере создайте функцию get для извлечения / загрузки CSV (замените «MainMeta» на свой собственный класс модели):
public function getMainMetaData(){ $mainMeta = MainMeta::all(); // Note: $mainMeta is a Collection object //(returning a 'collection' of data from using 'all()' function), //so can be passed in below. $this->createCsv($mainMeta, 'main_meta'); }
Когда вы создаете маршрут для вызова этой функции, он загружает CSV-файл в вашем браузере, выбранной вами коллекции / данных модели.
Создайте маршрут в App \ Http \ routes.php следующим образом:
Route::get( '/data/download/main_meta', [ 'as' => 'data/download/main_meta', 'uses' => 'YourController@getMainMetaData' ] );
(Необязательно). В файле просмотра лезвия (например, data.blade.php) укажите ссылку или кнопку, чтобы вы могли легко получить доступ к URL-адресу загрузки:
<p><a href="{{ URL::route('data/download/main_meta') }}" class="btn btn-lg btn-primary pull-left">Download Main Meta Data</a></p>
Когда вы нажмете на ссылку, файл CSV будет загружен в вашем браузере. В приложении, которое я закодировал, вы останетесь на странице, на которую вы нажмете эту ссылку.
Конечно, это будет отличаться в зависимости от вашего собственного приложения. С этим пакетом вы можете сделать гораздо больше (полная документация находится по адресу http://csv.thephpleague.com/ ). Проект, в котором я использую это, находится по адресу https://github.com/rattfieldnz/bitcoin-faucet-rotator. Я только что начал кодировать его снова через несколько месяцев, поэтому у меня есть немного рефакторинга / тестирования / очистки до делать :).
Попробуй это:
<?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); }