2

I have an api to download file. It is able to download file but showing only after download completes. there is no download progress. I want when user hit that url it will show download progress in chrome, currently it is showing after completion. I am using spring boot.

public responseEntity<Resource>getFile(String fileName){
    byte[] data=null;
    File file=new File(fileName);
    InputStream inputStream=new FileInputStream(file);
    data=IOUtils.toByteArray(inputStream);
    ByteArrayResource fileToDownload = new ByteArrayResource(data);
    return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType("application/octet-stream"))
                .header("Content-Disposition", "filename=" + fileName)
                .body(fileToDownload);
}
Dan
  • 3,647
  • 5
  • 20
  • 26
Vikash Mishra
  • 319
  • 3
  • 11
  • I suspect that the answer has nothing to do with the server side, and must be implemented client-side – tucuxi May 27 '22 at 07:52

1 Answers1

0

Use JavaScript in your webpage. This has nothing to do with how the server sends the file, and must be displayed client-side -- well, the server could output somewhere how far it is along sending the file, but that is not what you want to show - you are interested in showing how much you have received, and showing it in the client; so any answer will have to rely on JS+html to an extent. Why not solve it entirely in the client side?

In this answer they use the following code:

function saveOrOpenBlob(url, blobName) {
    var blob;
    var xmlHTTP = new XMLHttpRequest();
    xmlHTTP.open('GET', url, true);
    xmlHTTP.responseType = 'arraybuffer';
    xmlHTTP.onload = function(e) {
        blob = new Blob([this.response]);   
    };
    xmlHTTP.onprogress = function(pr) {
        //pr.loaded - current state
        //pr.total  - max
    };
    xmlHTTP.onloadend = function(e){
        var fileName = blobName;
        var tempEl = document.createElement("a");
        document.body.appendChild(tempEl);
        tempEl.style = "display: none";
        url = window.URL.createObjectURL(blob);
        tempEl.href = url;
        tempEl.download = fileName;
        tempEl.click();
        window.URL.revokeObjectURL(url);
    }
    xmlHTTP.send();
}

Note that you are missing part where you display the progress somewhere. For example, you could implement it as follows:

    xmlHTTP.onprogress = function(pr) {
        //pr.loaded - current state
        //pr.total  - max
        let percentage = (pr.loaded / pr.total) / 100;
        document.getElementById("progress").textContent = "" + percentage + "% complete";
    };

This assumes that there is something like

  <span id="progress">downloading...</span>

in your html

tucuxi
  • 17,561
  • 2
  • 43
  • 74