Download CSV File Using "Ajax"

Download Generated CSV file via Ajax

In short, you need to create an anchor, assign an object URL for the result to the href, and then call click() on it. Additionally, your $.ajax call will need to specify that you're expecting a blob response, as the default in jQuery is to treat the response as text. What that boils down to is code like the following:

$.ajax({
url: "@Url.Action("GenerateEventLogsReport", @ViewContext.RouteData.Values["controller"].ToString())",
method: "POST",
xhrFields: {
responseType: 'blob'
},
data: JSON.stringify(event_form_data),
contentType: "application/json",
success: function (result) {
var a = document.createElement('a');
var url = window.URL.createObjectURL(result);
a.href = url;
a.download = 'report.csv';
document.body.append(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
},
error: function (error) {
console.log(error);
}
});

I also have a working CodePen to demo.

Download CSV file using AJAX

If you are forcing a download, you can redirect the current page to the download link. Since the link will generate a download dialog, the current page (and its state) will be kept in place.

Basic approach:

$('a#query_name').click(function(){
$('#wait-animation').show();
document.location.href = '/php_scripts/utils/csv_export.php?query_name='+query_name;
$('#wait-animation').hide();
});

More complicated:

$('a#query_name').click(function(){
MyTimestamp = new Date().getTime(); // Meant to be global var
$('#wait-animation').show();
$.get('/php_scripts/utils/csv_export.php','timestamp='+MyTimestamp+'&query_name='query_name,function(){
document.location.href = '/php_scripts/utils/csv_export.php?timestamp='+MyTimestamp+'&query_name='+query_name;
$('#wait-animation').hide();
});
});

At PHP script:

@header("Last-Modified: " . @gmdate("D, d M Y H:i:s",$_GET['timestamp']) . " GMT");
@header("Content-type: text/x-csv");
// If the file is NOT requested via AJAX, force-download
if(!isset($_SERVER['HTTP_X_REQUESTED_WITH']) || strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) != 'xmlhttprequest') {
header("Content-Disposition: attachment; filename=search_results.csv");
}
//
//Generate csv
//
echo $csvOutput
exit();

The URL for both requests must be the same to trick the browser not to start a new download at document.location.href, but to save the copy at the cache. I'm not totally sure about it, but seems pretty promising.

Download csv file as response on AJAX request

In modern browsers, you can prompt a download by creating a Blob with your file contents (in your case received by Ajax), creating a URL for it, and using the download attribute:

const saveData = (function () {
const a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, fileName) {
const blob = new Blob([data], {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
};
}());

const data = 'a,b,c\n5,6,7',
fileName = "my-csv.csv";

saveData(data, fileName);

JSFiddle

If your Ajax endpoint URL has the proper headers (or possibly even if it isn't as long as you use the download attribute), you can forego the Blob and Ajax and just add the URL to the link with the download attribute. Adapting @pritesh's code,

const saveData = (function () {
const a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (url, fileName) {
a.href = url;
a.download = fileName;
a.click();
};
}());

const url = 'http://www.sample-videos.com/csv/Sample-Spreadsheet-10-rows.csv', // Replace with your own URL: window.location + "/downloadUserAction?draw=3&search%5Bvalue%5D=NLP_SEARCH&order%5B0%5D%5Bcolumn%5D=6&order%5B0%5D%5Bdir%5D=desc"
fileName = "my-csv.csv";

saveData(url, fileName);

JSFiddle

How to download the csv file by ajax

You can try this using Blob api:

const DownloadCsv = (function() {
const a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function(data, fileName) {
const blob = new Blob([data], {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
};
}());

$.ajax({
type: "GET",
url: url,
success: function(response) {
//console.log(response);
DownloadCsv(response, 'somefilename.csv')
}
});

How to download a csv file requested through jquery/ajax from flask server

I think it's because the file's content is stored in the data variable (of the "success" callback of $.ajax), so it's just a js variable for the browser.

I think the best (cleanest maybe?) thing you can do is wrap your .download-btn in a <a> tag with your download url in href

<a href="/downloadFile" target="_blank">
<button class="download-btn">Download</button>
</a>

This way "the browser itself" makes the GET request to /downloadFile (in a new tab because of the target="_blank" attribute), receives the stream and downloads the file (and closes tab once the download is started).

How to download CSV file from PHP script via AJAX?

Further to my comment(s), I would make the form able to submit normally or using ajax. Ajax for search, normal submit for download:

<div class="container">
<!-- Make this a proper form tag again -->
<form id="ldap-form" method="post" action="working_csv.php">
<h2><strong><p>Search the LDAP server</p></strong></h2>
<label for="location"><p>Enter your search location (ex: dc=example,dc=com)</p></label>
<input type="text" id="location" name="location" placeholder="Search Location.." />
<label for="filter"><p>Enter your search filter(s) (ex: uid=* or </p></label>
<input type="text" id="filter" name="filter" placeholder="Filter(s).." />
<input type="submit" name="search" id="search" value="Search LDAP Server" />
<input type="submit" name="download" id="download" value="Download results as CSV file" />
</form>
<!-- Response container -->
<p id="msg"></p>
</div>

<script>
$(function(){
$('input[type="submit"]').on('click', function(e){
// Stop form from submission
e.preventDefault();
// Detect button press type
let thisSubmission = $(this).attr('name');
// If the button is search, do ajax
if(thisSubmission == 'search') {
$.ajax({
type: "post",
url: $('#ldap-form').attr('action'),
data: $('#ldap-form').serialize(),
cache: false,
success: function(html){
$('#msg').html(html);
}
});
}
else {
// Just submit the form normally
$('#ldap-form').submit();
}
});
});
</script>


Related Topics



Leave a reply



Submit