Reputation: 39
I have a Flask web app with a URL route that receives a post request with some json, parses it to an .xlsx file, then returns the file with send_file()
.
Server side, I can see that the .xlsx file that is generated is correct but, once downloaded on the client side, the file is corrupted and can't be opened and is much larger than expected (201KB vs. 112KB).
I suspect it's some sort of encoding issue, but I've tried a whole bunch of stuff and can't make any headway. Can anyone help, please?
Flask route:
@app.route('/request/export_XLSX',methods=['POST'])
def request_export_XLSX():
json_model = json_util.loads(request.data.decode('ascii', 'ignore'))
xlsx_model = detox.xlsxFromJSONModel(json_model) # Returns file path
result = send_file(xlsx_model, as_attachment=True, attachment_filename=json_model['id']+'.xlsx', mimetype='application/vnd.ms-excel')
return result
JavaScript:
var exportModelExcel = function(){
var model = detox.fba.model
d3.selectAll('*').style("cursor","wait")
var modelJson = JSON.stringify(model)
$.ajax({
type: "POST",
url: "/request/export_XLSX",
data: modelJson,
success: function(d){
d3.selectAll('*').style("cursor","")
var blob = new Blob([d], {type: 'application/vnd.ms-excel'})
var link=document.createElement("a");
link.href=window.URL.createObjectURL(blob);
link.download=model.id+".xlsx";
link.click();
},
error: function(jqxhr,textStatus,errorThrown){
console.log("Error: " ,textStatus,errorThrown)
d3.selectAll('*').style("cursor","")
alert("There was an error exporting the model")
},
contentType: 'application/json',
responseType: 'blob',
processData: false,
});
}
Here's a link where you can see the good and bad .xlsx files: https://gofile.io/d/xywI1D
Upvotes: 0
Views: 1155
Reputation: 39
Well, I ended up ripping out the ajax and using an XMLHTTPRequest
instead.
It works nicely and results in an uncorrupted .xlsx file. 🙂
var exportModelExcel = function(){
var model = detox.fba.model;
var modelJson = JSON.stringify(model);
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var downloadUrl = URL.createObjectURL(xhttp.response);
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
a.href = downloadUrl;
a.download = model.id+".xlsx";
a.click();
}
};
xhttp.open("POST", "/request/export_XLSX", true);
xhttp.setRequestHeader("Content-Type", "application/json");
xhttp.responseType = "blob";
xhttp.send(modelJson);
}
Upvotes: 3