0

I have a Flask application that sends an Excel file to Ajax. The file is sent from memory but the downloaded file is corrupt. How should I be handling the response from Flask in Ajax? Should I be using a different mimetype or content type? I've tried changing content type and blob type with no luck and I can't figure out what to do next. Thanks for the help!

View.py

@app.route('/RuleMetricQuery', methods=['POST'])
def rulequery():
  query = request.json
  df = fetch_data('my_data.csv', 's3_bucket')

  output = BytesIO()
  writer = pd.ExcelWriter(output, engine='openpyxl')

  df.to_excel(writer, sheet_name='Simple Data')

  writer.close()
  output.seek(0)

  m_type = 'application/vnd.openxmlformatsofficedocument.spreadsheetml.sheet'
  cd = 'attachment; filename=sample_data.xlsx'
  ct = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

  return Response(output, mimetype=m_type,
                  headers={'Content-disposition':cd, 'Content-type':ct})

Query.js

let get_query_params = function() {
    let rules = $('#rules').val()
    let mp_id = $('#mp_id').val()
    let time_window = $('#timewindow').val()
    return {'rules' : rules,
            'mp_id' : mp_id,
            'time_window' : time_window}
 };

let send_query = function(query_params) {
    $.ajax({
        url: '/RuleMetricQuery',
        contentType: 'application/json; charset=utf-8',
        type: 'POST',
        data: JSON.stringify(query_params),
        complete: function (data){
            $("button#fetch_data").text('Fetch my data!');
            $("button#fetch_data").attr("disabled", false);

            var blob = new Blob([data.responseText, {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}]);
            var link = document.createElement("a");
            link.href = window.URL.createObjectURL(blob);
            link.style = "visibility:hidden";
            link.download = 'rule_data.xlsx';

            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        }
    });
};

$(document).ready(function() {

    $("button#fetch_data").click(function() {

        $(this).attr('disabled', true);

        $(this).text('Please wait...');

        let query_params = get_query_params();
        send_query(query_params);

    })

});
danius
  • 1
  • 1
  • You have to specify a response type of blob or arraybuffer (or override mime type) to get binary data from an ajax request. See similar https://stackoverflow.com/questions/17657184/using-jquerys-ajax-method-to-retrieve-images-as-a-blob – Musa Feb 07 '18 at 19:34
  • I switched the mime type and content type in view.py and query.js to application/octet-stream and the file is still corrupt. Should I not be using data.responseText? – danius Feb 07 '18 at 20:27
  • I meant [overrideMimeType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/overrideMimeType) also did you check out the link – Musa Feb 07 '18 at 21:42

0 Answers0