So I have made a little ajax request to my reviewsController@export
.
Now when I console.log()
the data in my success method, the ajax response shows the correct data. However my CSV has not downloaded. So I have all the right info and have created the csv essentially.
I think this has possibly to do with setting the headers maybe?
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();
}
Is there anything I am doing wrong here, or does Laravel have something to cater for this?
I have made a little package LaravelCsvGenerator
and placed it on packagist
Installation
example of use in your controller
Please, do not hesitate to comment your ideas below this answer.
Try this:
Note: Works only if you don't load relationships, otherwise it will give exception
Try this version out - this should allow you to get a nice output using
Response::stream()
.(Adapted from this SO answer: Use Laravel to Download table as CSV)
Try using a regular link with
target="_blank"
rather than using JavaScript/AJAX. Because it's a file download opening in a new tab, the user experience shouldn't be too clunky.The simples way
This may not answer your question directly, but I'm using a package called 'thephpleague/csv' for this purpose...
To use this package:
Put the following 'use' statements in your controller:
and any model classes you plan on using.
Abstract CSV creating code to a function (in your controller), e.g:
In your controller, create get function to retrieve/download CSV (replace 'MainMeta' with your own model class):
When you create a route to call this function, it will download a CSV file in your browser, of your chosen Model collection/data.
Create a route in App\Http\routes.php like the following:
(Optional) In a blade view file (e.g. data.blade.php), include a link or button so you can easily access the download url/route:
When you click on the link, the CSV file will be downloaded in your browser. In an application I have coded, you will stay on the page you click this link.
Of course, this will differ depending on your own application. There is so much more you can do with this package (full documentation is at http://csv.thephpleague.com/). The project I am using this in is at https://github.com/rattfieldnz/bitcoin-faucet-rotator - I have just started coding on it again after a few months away, so still have a bit of refactoring/testing/tidying up to do :).
My approach in Laravel 5.7