AngularJS - File Download through AJAX

2020-03-24 06:42发布

问题:

I created an angular js program for downloading a file from the server here follows the code

HTML Code

<a download="fullList.csv" ng-href="{{ fullListUrl }}" type="button" class="btn btn-success btn-xs exec-batch"  ng-click="exportCSVBulk(batchExec)">
          <span class="glyphicon glyphicon-ok"></span> EXPORT AS CSV
</a>

AngularJS Controller

$scope.exportCSVBulk=function(){
 var page = "../importExportService/exportBulkCSV/"+batchExec.id;
 $http.get(page).success(function(response) {
 $scope.fullListUrl = 'data:text/csv;charset=utf-8,' + escape(response); 
});
}

Here what i am doing is when a user click on the EXPORT AS CSV link the function exportCSVBulk fires and from that function the url value (fullListUrl) sets. But this is an ajax request, so when a user click on the link the url, the response time become little bit long which results the url will not redirected properly. Is it possible to fix this problem? or is there is any alternative way to fix this?

回答1:

I have faced the similar issue for downloading files such as .pdf, .xls, .xlsx etc through Ajax.

Its a fact that we cant download files through Ajax, even though i came up with a solution which downloads files through Ajax like.

You can use jquery.fileDownload - A jQuery File Download Plugin for Ajax like, feature rich file downloads.

Demo Working

Server Side

I am using Spring at the server side

@RequestMapping(value = "exportXLS", method = RequestMethod.POST, produces = APP_JSON)
@ResponseBody
public void getCSV(final HttpServletResponse response, @RequestParam(value = "empId", required = true) final String empId) throws IOException, Exception
{
    final byte[] csv = ExportXLSUtil.getFileBytes(empId); // get the file bytes
    final OutputStream output = getOutputStream(response);
    response.setHeader("Content-Disposition", "attachment; filename=documents_" + new DateTime() + ".xls");
    response.setContentType(CONTENT_TYPE);
    response.setContentLength(csv.length);
    write(output, csv);
}

Client Side

At the client side, I am using AngularJS

$downloadXLS = function(id)
{
    $.fileDownload('/user/exportXLS', 
    {
        httpMethod : "POST",
        data : {
            empId : id
        }
    }).done(function(e, response)
    {
     // success
    }).fail(function(e, response)
    {
     // failure
    });
}

Download Link - jquery.fileDownload.js



回答2:

I created a more angular way solution. The server has to provide content-type and content-disposition if you want to sync with server info, although you could add type and download properties manually.

 vm.export = function () {
            //PopUps.showLoading()
            $http.get(Url).then(function (result) {
                //PopUps.hideLoading()
                var headers = result.headers()
                var blob = new Blob([result.data], { type: headers['content-type'] })
                var windowUrl = (window.URL || window.webkitURL)
                var downloadUrl = windowUrl.createObjectURL(blob)
                var anchor = document.createElement("a")
                anchor.href = downloadUrl
                var fileNamePattern = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
                anchor.download = fileNamePattern.exec(headers['content-disposition'])[1]
                document.body.appendChild(anchor)
                anchor.click()
                windowUrl.revokeObjectURL(blob)
            })
        }