Reputation: 2893
I am trying to stream a large CSV from the server. I load a JSON file, convert it to an array, and then process it as a CSV. From the frontend, I am calling the following on a button click
downloadCSVData() {
axios({
url: '/downloadCSVData',
method: 'GET'
}).then((response) => {
console.log(response)
});
}
And then this function does the following
public function downloadCSVData()
{
//load JSON file
$data = file_get_contents($file_path, true);
//Convert file to array
$array = json_decode($data, true);
$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'
];
$response = new StreamedResponse(function() use($array){
// Open output stream
$handle = fopen('php://output', 'w');
// Add CSV headers
fputcsv($handle, array_keys($array['element'][0]), ',');
foreach ($array['element'] as $key => $row) {
fputcsv($handle, $row);
}
// Close the output stream
fclose($handle);
}, 200, $headers);
return $response->send();
}
Now on the frontend, within the console, I can see the reponse being printed the way it needs to be. From my understanding however, the backend should trigger the file to be downloaded which is not happening.
Am I missing something here, how can I get this downloaded on the frontend as a physical file?
Thanks
Upvotes: 0
Views: 2018
Reputation: 5149
If you visited the URL directly, your PHP settings should work to force a download. But you are already in a fully loaded HTML page, so you need to use the <iframe>
trick to get the file to download. This will allow the browser to receive the incoming data as if you've opened a new browser window.
Try changing your download function to this:
downloadCSVData() {
$('<iframe />')
.attr('src', '/downloadCSVData')
.hide()
.appendTo('body');
}
Upvotes: 1