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?
Try this version out - this should allow you to get a nice output using 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); }
(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.
/** * @param array $columnNames * @param array $rows * @param string $fileName * @return \Symfony\Component\HttpFoundation\StreamedResponse */ public static function getCsv($columnNames, $rows, $fileName = 'file.csv') { $headers = [ "Content-type" => "text/csv", "Content-Disposition" => "attachment; filename=" . $fileName, "Pragma" => "no-cache", "Cache-Control" => "must-revalidate, post-check=0, pre-check=0", "Expires" => "0" ]; $callback = function() use ($columnNames, $rows ) { $file = fopen('php://output', 'w'); fputcsv($file, $columnNames); foreach ($rows as $row) { fputcsv($file, $row); } fclose($file); }; return response()->stream($callback, 200, $headers); } public function someOtherControllerFunction() { $rows = [['a','b','c'],[1,2,3]];//replace this with your own array of arrays $columnNames = ['blah', 'yada', 'hmm'];//replace this with your own array of string column headers return self::getCsv($columnNames, $rows); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With