Download file from Ajax (sort of)

前端 未结 4 798
梦如初夏
梦如初夏 2021-01-03 08:11

I have this ajax call in my GSP:

$.ajax({
    url: \'${request.contextPath + \'/Ticket/passAll\'}\',
    type: \'POST\',
    data: data,
    success: functio         


        
相关标签:
4条回答
  • 2021-01-03 08:34

    Im a little late on this one but stumbled upon it doing some research. This solution is a bit longer and cobbled together from various questions answered here. I think its a direct answer to this question and I have it working in an application.

    <script>
    function getCSV() {
    console.log("in get csv");
      $.ajax({
          url: "<url string>",
          dataType: 'json',
          type: "post",
          data: {},
          success: function (data) {
              console.log(data);
              downloadCSV({filename: "<filename.csv", data: data.<array from 
                                          backend call>});
          },
          error: function () {
          }
      });
    }
    }
    function downloadCSV(args) {
    var data, filename, link;
    var csv = convertArrayOfObjectsToCSV({
        data: args.data
    });
    if (csv == null) return;
    filename = args.filename || 'export.csv';
    if (!csv.match(/^data:text\/csv/i)) {
        csv = 'data:text/csv;charset=utf-8,' + csv;
    }
    data = encodeURI(csv);
    link = document.createElement('a');
    link.setAttribute('href', data);
    link.setAttribute('download', filename);
    link.click();
    }
    function convertArrayOfObjectsToCSV(args) {
    var result, ctr, keys, columnDelimiter, lineDelimiter, data;
    data = args.data || null;
    if (data == null || !data.length) {
        return null;
    }
    columnDelimiter = args.columnDelimiter || ',';
    lineDelimiter = args.lineDelimiter || '\n';
    keys = Object.keys(data[0]);
    result = '';
    result += keys.join(columnDelimiter);
    result += lineDelimiter;
    data.forEach(function (item) {
        ctr = 0;
        keys.forEach(function (key) {
            if (ctr > 0) result += columnDelimiter;
            result += item[key];
            ctr++;
        });
        result += lineDelimiter;
    });
    return result;
    }
    </script>
    

    The first function is a standard ajax call to get the array of data from a backend call. The next is to create the csv. The second line calls a third function that formats the csv file. The second function moves on from the csv creation and finally creates a dynamic link that is appended to the dom and clicked for the download. Seems the longer way round but works with standard ajax call to the backend.

    0 讨论(0)
  • 2021-01-03 08:46

    I guess the url property should be fixed as your quotes are colliding.

    Try with:

    $.ajax({
        url: "${request.contextPath}/Ticket/passAll",
        type: 'POST',
        data: aoData,
        dataType: 'text',
        success: function(result) {
            var uri = 'data:application/csv;charset=UTF-8,' + encodeURIComponent(result);
            window.open(uri, 'tiketi.csv');
        }
    });
    
    0 讨论(0)
  • 2021-01-03 08:52

    As far as I know, it's not possible to trigger file-downloads via AJAX. Instead you may do something like this (e.g. with jQuery):

    function downloadComplete(){ hideSpinner();}
    function downloadStart(){ showSpinner();}
    
    function download(){
        downloadStart()
        var urlParams = data // or e.g. $(form).serialize() 
        var downloadUrl = "${request.contextPath}/Ticket/passAll?" + urlParams 
        $("#download-iframe").remove()
        $('<iframe style="display:none" id="download-iframe" src="' + downloadUrl + '" onreadystatechange="downloadComplete()" onload="downloadComplete()">').appendTo('body');
    }
    

    You may have problems because it's a GET-request: "security" or too many arguments. But in normal it should be no problem.

    0 讨论(0)
  • 2021-01-03 08:53

    You dont need to do it via ajax. The page will not redirect for file downloads.

    0 讨论(0)
提交回复
热议问题