0

I'm developing a report in Excel, from a WebPage. The page have some chart's and some data inside some tables. I have an excel file, that works as a model to write data inside the file. I created some chart´s inside the sheet, and write data inside some sheet, and i reference this data to use it on chart's. Everything works well, except by the fact that I cannot download the file.

I created a piece of code to do this, and I generated the file successfully. What I'm trying to do now, is download this file.

So i tried something:

So, I generate the file, and the file as been downloaded, but comes corrupted.

API

var mimeType = "application/vnd.ms-excel";

string file = Path.Combine(path, fileName);

var memory = new MemoryStream();

using (var stream = new FileStream(file, FileMode.Open))
{
    stream.CopyTo(memory);
}

memory.Position = 0;

return File(memory, mimeType, "filename.xlsx");

Angular

return $http.post(url, data, config)
    .then(function (response) {

    //TODO: Implementar o download do arquivo
    var file = new Blob([data], { type: 'application/vnd.ms-excel' });
    saveAs(file, 'filename.xlsx');

    }).catch(function (error) {
        console.log("error");
    });
Alexander
  • 9,104
  • 1
  • 17
  • 41
Bisneto
  • 141
  • 2
  • 13
  • I dont think so thatwe are speaing about the same thing. I'm using Angular1, and the solution that you are trying to give me is talking about a solution writed in Angular2. Did you read my text? – Bisneto Jan 21 '19 at 14:30
  • What do you mean "the file is corrupted"? And what is the code of saveAs(file, 'filename.xlsx') function? – Alexander Jan 21 '19 at 14:32
  • @Bisneto There is nothing in your post that says anything about Angular1. The tag you chose was for Angular 2 and above. I have fixed that. Thanks for the clarification. I don't know that it changes anything though. I don't see anything in your question that appears to be Angular1 specific. – peinearydevelopment Jan 21 '19 at 14:35
  • Hi Alexander. I created the file, and tryied to open by Excel. It´s ok, he opened. When i send this by memory stream to Angular, as you can read on the code that i attached, then i receive the message : "Excel cannot open the file "filename". Verify if the file is corrupted or if the extension of file is invalid" – Bisneto Jan 21 '19 at 14:35
  • Ah, ok, sorry, i thought that ommiting number beside of Angular you would understand. Just to let you know, I'm talking about a solution using Angular1. Thanks ! – Bisneto Jan 21 '19 at 14:38
  • You don't need to use a `MemoryStream`. You can use the `File()` overload that accepts a path. The [correct content type](https://blogs.msdn.microsoft.com/vsofficedeveloper/2008/05/08/office-2007-file-format-mime-types-for-http-content-streaming-2/) for `xlsx` is `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet`. The content type you used is for the obsolete `xls` format – Panagiotis Kanavos Jan 21 '19 at 14:43
  • I have try the changes, but the issue persists – Bisneto Jan 21 '19 at 14:47

1 Answers1

0

It looks like you have an error in this line

var file = new Blob([data], { type: 'application/vnd.ms-excel' });

Try to change it to

var file = new Blob([response.data], { type: 'application/vnd.ms-excel' });

Also you can try the following code. It works just fine

var linkElement = document.createElement('a');
try {
    var blob = new Blob([response.data], { type: 'application/vnd.ms-excel'});
    var url = window.URL.createObjectURL(blob);

    linkElement.setAttribute('href', url);
    linkElement.setAttribute("download", filename);

    var clickEvent = new MouseEvent("click", {
        "view": window,
        "bubbles": true,
        "cancelable": false
    });
    linkElement.dispatchEvent(clickEvent);

    } 
    catch (ex) {
        console.log(ex);
    }

Source: http://jaliyaudagedara.blogspot.com/2016/05/angularjs-download-files-by-sending.html

Alexander
  • 9,104
  • 1
  • 17
  • 41
  • I have try this change: return $http.post(url, data, config) .then(function (response) { //TODO: Implementar o download do arquivo var file = new Blob([response.data], { type: 'application/vnd.ms-excel' }); saveAs(file, 'filename.xlsx'); }).catch(function (error) { console.log("error"); }); But the error is the same. – Bisneto Jan 21 '19 at 14:44
  • @Bisneto Hmm, so it should be something wrong inside **saveAs** function. I will be able to say more if I see the code. – Alexander Jan 21 '19 at 14:47
  • It doesn't ocurr any error during execution of script. How i could send you the code to you take a look ? – Bisneto Jan 21 '19 at 14:53
  • @Bisneto I've updated my answer. Try this solution. If it doesn't work please edit you question by adding the code of the **saveAs** function or maybe whole javascript file code. – Alexander Jan 21 '19 at 14:57
  • How i can send you a print screen ? It´s coming data from data property of response. I think is sometinng really software – Bisneto Jan 21 '19 at 14:57
  • @Bisneto https://prnt.sc/ – Alexander Jan 21 '19 at 14:58
  • Alexander, i dont think this is the best solution, and this is not i'm looking for. This solution i could reproduce just simulating a click event from the page, but i dont want this. I want to download file directly, like Google do it.Sorry, and thank you very much to try to help me. – Bisneto Jan 21 '19 at 15:01
  • http://prntscr.com/ma4d56 – Bisneto Jan 21 '19 at 15:02
  • http://prntscr.com/ma4f7j This is the Excel file generated by Asp.NetCore. He is working fine, but, the problem is download it. – Bisneto Jan 21 '19 at 15:06
  • I have try the implementation that you suggested me, take a look on the result: https://prnt.sc/ma4hz2 https://prnt.sc/ma4ils https://prnt.sc/ma4ird and finally https://prnt.sc/ma4iwu – Bisneto Jan 21 '19 at 15:11
  • https://prnt.sc/ma4ja2 – Bisneto Jan 21 '19 at 15:12
  • @Bisneto Well, is it possible that you just read wrong file in ASP.NET code? Because js seems to be working fine and I don't know where else the error could be. – Alexander Jan 21 '19 at 15:14
  • Yeah, can be. Take a look of my server code https://prnt.sc/ma4mbr – Bisneto Jan 21 '19 at 15:18
  • I solve the problem, not as i would like, but it works. I received a name of the file on the response, and redirect directly to the file. It works. Thank you! – Bisneto Jan 21 '19 at 15:59
  • @Bisneto Sounds great. Not sure if it is good solution. I've done some research and it turns out you can save **ExcelPackage** directly into **MemoryStream** by using its SaveAs method like: var memory = new MemoryStream(); package.SaveAs(memory); And you can use parameterless constructor for it I think. I just tested it on my machine and it works. Hope it'll work for you as well. – Alexander Jan 21 '19 at 16:06
  • Alexander, Yeahh, thats i was looking for. So, you think would be a good way to test this solution, right? I agree, this solution is the right way. Thank you ! I will try to save file in memorystream ! – Bisneto Jan 21 '19 at 16:20
  • Hi Alexander, doesn't work. I tried the same way, but at this time, doesn't work. Could you please share with me your solution working? – Bisneto Jan 21 '19 at 16:39
  • https://prnt.sc/ma5x04 The changes that i made – Bisneto Jan 21 '19 at 16:39
  • YEAH! I I got it! What REALLY solve my problem was this solution. First, i needed to return a byte array, as follow: System.IO.File.ReadAllBytes(pathTo + fileName) Secondly, I needed to send a different myme type. I sent a Enum: System.Net.Mime.MediaTypeNames.Application.Octet Third, i needed to change the request, putting responseType: 'arraybuffer' in the config options. And then, IT WORKS FINE! Thank you for everyone. – Bisneto Jan 22 '19 at 14:56