【问题标题】:convert blob to Excel file and download, file cannot be open将 blob 转换为 Excel 文件并下载,文件无法打开
【发布时间】:2020-11-25 04:26:18
【问题描述】:

我有一个返回以下响应的 api,其中包含 excel 文件内容。

所以现在我需要将它们转换为 excel 文件并为用户下载。

这里是api函数

   [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;
        }
    }

我在前端有如下这样的功能,

      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();
    }

和功能

     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;
    }

此功能适用于只有普通文本的 excel。但是,我正在尝试下载的这个excel,它具有丰富的内容,例如彩色边框,下拉菜单,多张表格。

当我尝试使用相同的功能下载 excel 文件时,它会抛出这个错误:

为了帮助你更了解我的问题,这里是 API HTTP CAll

我曾尝试在线搜索解决方案,但没有运气。我实际上不明白这里有什么问题。任何事情都会有所帮助,谢谢。

【问题讨论】:

  • 那个“�”是个坏兆头。这看起来不像一个有效的 UTF-8 json 字符串,带有正确转义的字符。我敢打赌它只是 excel 文件的原始字节,周围是看起来像 json 的东西。
  • 如果你提供了一个 api 来下载文件,不要尝试将结果包装在 json 中。
  • @JeremyLakeman 我在这里发布了我的 api 功能。你的意思是问题出在api函数上?
  • Excel *.xlsx 文件不是文本文件。 它们是二进制文件
  • @Dai 感谢您的回复,但抱歉我不明白。您的意思是需要更改 api。

标签: javascript c# angularjs


【解决方案1】:

感谢所有的回复,让我有点头绪,最后我解决了这个问题。

嗯,发现它的问题是因为在 API 中我将它包装在 UTF-8 中。但是,它 (Excel) 不应该用 UTF-8 包装。仅当我正在下载 csv 文件时。

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

改为

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

【讨论】:

  • 你不需要做ms.ToArray(),这会导致你不需要额外的堆分配。您可以将Stream 直接传递给File 方法。使用ControllerBase.File 的重载,它接受Stream 作为第一个参数。
  • 只是 return File()Ok(...) 将其转换为 json。
猜你喜欢
  • 2016-04-05
  • 1970-01-01
  • 2019-01-27
  • 1970-01-01
  • 2014-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多