Transform the blob data into an Excel file for easy download, but beware the file is not accessible

My API returns a response containing the content of an excel file, which is displayed in the image below.

https://i.sstatic.net/2VHsL.png

Now, I am looking to convert this content into an excel file and make it downloadable for the user.

Below is the API function:

   [HttpGet]
    [IgnoreAntiforgeryToken]
    public async Task<IActionResult> DownloadLoadedTrnFile(string S3Path)
    {
        try
        {
            string bucket = "taurus-" + GetEnvironmentSettings() + "-trn";
            string fileName = "";
            string[] fileStr = S3Path.Split('-');
            if (fileStr.Count() > 0)
            {
                fileName = fileStr.Last();
            }
            Stream responseStream = await _imageStore.GetImage(bucket, S3Path);
            if (responseStream == null)
                return NotFound();
            using (MemoryStream ms = new MemoryStream())
            {
                responseStream.CopyTo(ms);

                var finalResult = File(System.Text.UTF8Encoding.UTF8.GetString(ms.ToArray()), MimeTypesMap.GetMimeType(S3Path), fileName);
                return Ok(finalResult);
            }
        }
        catch (Exception ex)
        {
            return StatusCode(500, "Error in downloading file.");
        }
    }





     public async Task<Stream> GetImage(string bucketName, string objectKey)
    {
        GetObjectRequest originalRequest = new GetObjectRequest
        {
            BucketName = bucketName,
            Key = objectKey
        };
    
        try
        {
            GetObjectResponse response = await S3Client.GetObjectAsync(originalRequest);

            // AWS HashStream doesn't support seeking so we need to copy it back to a MemoryStream
            MemoryStream outputStream = new MemoryStream();
            response.ResponseStream.CopyTo(outputStream);

            outputStream.Position = 0;

            return outputStream;
        }
        catch (AmazonS3Exception ex)
        {
            // Not found if we get an exception
            return null;
        }
    }

I have a similar function on the front-end as follows:

      function saveTextAsFile(data, filename, contentType) {
        if (!data) {
            console.error('Console.save: No data')
            toastr.error("No data received from server");
            return;
        }

        if (!filename) filename = 'noname.xlsx';

        var blob = new Blob([s2ab(atob(data))], {
            type: contentType
        });


        var a = document.createElement("a");
        a.href = URL.createObjectURL(blob);
        a.download = filename;
        a.click();
    }

And another supporting function:

     function s2ab(s) {
        var buf = new ArrayBuffer(s.length);
        var view = new Uint8Array(buf);
        for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
        return buf;
    }

This functionality works well with excel files that only contain normal text. However, when trying to download the mentioned excel file with rich content such as color border, dropdowns, and multiple sheets, it throws the following error:

https://i.sstatic.net/tIBQw.png

To provide more context about the issue, here are screenshots of the API HTTP Call:

https://i.sstatic.net/0Uy3j.png

https://i.sstatic.net/g3lN2.png

I have tried searching for solutions online but have not been successful. I am unsure of what the problem could be. Any help would be greatly appreciated. Thank you.

Answer №1

Grateful for all the responses that helped me wrap my head around the issue and finally resolve it.

Upon further investigation, I discovered that the problem stemmed from wrapping the API response inside UTF-8, when in fact Excel shouldn't be wrapped in UTF-8 unless it's a CSV file.

var finalResult = File(System.Text.UTF8Encoding.UTF8.GetString(ms.ToArray()), MimeTypesMap.GetMimeType(S3Path), fileName);

I made the necessary adjustment to:

var finalResult = File(ms.ToArray(), MimeTypesMap.GetMimeType(S3Path), fileName);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discover the power of Vue.js 3 by seamlessly integrating anonymous functions within event handlers

Is it possible to invoke an anonymous function within an event handler in Vue.js 3? I came across several options on various websites: <button @click="return function() { console.log('test')}()">Click me</button> <butto ...

I'm confused, I installed the module but it's still showing an error message saying it can

I've been working on coding a discord music bot, and here is the code I have so far: const config = require('config.json') const Discord = require('discord.js'); const ffmpeg = require('ffmpeg-extra') const client = new ...

Difficulty in extracting data from child elements of JSON documents

Below is the JSON String: "book_types": { "type": "1", "books": [ { "name": "default", "cover": null, "lastUpdated": { "microsecond": 114250, "ctime": "Fri Aug 9 01:27:45 ...

How can I assign an object as the default value for the ng-model of a 'select' element?

Currently, I am in the process of creating a search engine interface using Angular. The workflow involves users selecting parameters within a form, clicking "search," and populating the URL with these parameters through the use of $location.search(). The ...

Typescript encounters ERROR TS1128: Expecting a declaration or statement

Having trouble with a TypeScript error in my game-details.component.ts file that I've been trying to fix for a couple of hours. It's showing up at line 26, column 54 and everything seems correct to me. Interestingly, when I press CTRL + S in my ...

JavaScript: Troubleshooting Array Formatting

Seeking assistance with formatting this JavaScript array accurately. It seems like I am overlooking something crucial: Javascript: <script type="text/javascript"> var dimensions = new Array("225","320","480", "--"); var walls = new Array() ...

The replaceWith() function in jQuery is able to transform PHP code into an HTML comment

How can I change a div element in a click event handler, while ensuring that PHP code inside the element remains intact and does not get moved into an HTML comment? You can find my code snippet below: $("#replaceCat1").click(function(){ $("div.boxconte ...

Methods for applying a style property to a div element with JavaScriptExecutor in Selenium utilizing C#

I have been attempting to change the style of a div element using JavascriptExecutor in C#, but so far, nothing has happened. IJavaScriptExecutor js = (IJavaScriptExecutor)driver; IWebElement element = driver.FindElement(By.XPath("//div[contains(@class, ...

The image within the ion-slide-box remains hidden until the page is resized

I am facing a very peculiar issue. There is an ion-slide-box containing some images: <ion-view > <ion-content overflow-scroll="false" > <ion-slide-box show-pager="true"> <ion-slide ng-repeat="item in featured"> ...

Encountered issues while installing a package with npm instead of yarn

I have established a Git repository that will serve as an NPM package in another project. Let's refer to this sharable repository as genesis-service-broker. Within one of my services (specifically the activation service), I am utilizing this shareabl ...

Perform an asynchronous request using a data variable retrieved from a previous asynchronous request

I have a function using ajax to parse XML data. Here is an example: $.ajax({ type: "GET", url: "the.xml", dataType: "xml", success: function parseXml(data){ $(data).find("ITEM").each(function(){ var x = $("URL", this).t ...

Modify the information and return it to me

I am attempting to modify and return the content inside a custom directive (I have found some resources on SO but they only cover replacement). Here is an example: HTML <glossary categoryID="199">Hello and welcome to my site</glossary> JS . ...

Unable to store user data in the MongoDB Database

I'm currently facing an issue while trying to store user information in my MongoDB database. Everything was working fine until I implemented hashing on the passwords using bcrypt. After implementing password hashing, I am encountering difficulties in ...

Navigate to the specified location using AJAX

When I update a comment using AJAX, I want to automatically scroll down to the updated comment: $("#aggiorna").click(function(){ var value = $("#id").val(); var dato = $("#comment_edit").val(); var dato1 = $("#user_id").val(); var dato2 = ...

Connecting elements within an object using VueJs

Within my object "info_login," I gather account information: async created() { try { const res = await axios.get(inscriptionURL); this.comptes = res.data; this.comptes.forEach(element => { const data = {'pseudo': ...

Toggle Vue transitions on and off with a boolean parameter

Is there a way to dynamically disable a transition animation in Vue based on a boolean value? Currently, the animation is enabled with the following code: <transition name="fadeUp"> <div v-if="elIsVisible"> <p>Foo Bar</p> ...

Attempting to display a singular form

Currently, I am working on a MERN app and encountering a small issue... I am developing an application where users can create rooms and within those rooms, they can plan their daily activities. It's similar to a TODO app but more intricate. I wanted ...

Issues with jQuery slide operation

I'm facing an issue with jQuery and I can't figure out where it's coming from. Here is the error message that keeps showing up in the console: Uncaught TypeError: Object [object Object] has no method 'getElement' script_16.js:46Un ...

Setting up an event listener for a newly added list through the use of node appendChild

I am currently working on dynamically adding a select list to my HTML document. While I have successfully added the node to the DOM, I am struggling with creating an event listener in a separate JavaScript file that recognizes the newly created select list ...

Display the element solely when the user enters a value greater than 0 into the input box

I am in the process of developing a WoW Classic statistics calculator that allows users to select a class and input various values. As the user makes changes to the inputs, the calculations are displayed below the form using vanilla JS and jQuery. I am ple ...