首页 > 解决方案 > FileResult 上出现“文件已损坏,无法打开”错误

问题描述

我有一个将数据表转换为 excel 字节并将其作为文件发送的 web api。当我尝试打开 excel 文件时,我收到“我们发现 'Test.xlsx' 中的某些内容存在问题。您希望我们尽可能恢复吗?如果您信任此工作簿的来源,请单击是的。”。当我单击是时,我得到“文件已损坏,无法打开”。

我尝试了以下堆栈溢出问题中提到的解决方案:

ASP.NET MVC FileResult 正在损坏文件

在 C# 中保存字节流创建的 Excel 文件 (.xlsx) 无法打开

在 WebAPI 中将 HttpResponseMessage 作为 excel 文件返回的问题

'文件已损坏,无法打开' OpenXML

[HttpPost]
public FileResult GetExcelFile(string parameters)
{
      byte[] contents = generateContents(parameters);

      // Method 1:
      //Response.Clear();
//      Response.ContentType = "application/octet-stream";
  //    Response.AddHeader("Content-Disposition", "attachment; filename=" + "Test.xlsx");
    //  Response.AddHeader("Content-Length", contents.Length.ToString());
     // Response.BinaryWrite(contents);
//      Response.Flush();
  //    Response.Close();
    //  Response.End();


     return File(contents, "application/octet-stream", "Test.xlsx");
}

$.ajax({
            url: webMethod,
            type: "POST",
            data: jQuery.param(parameters),
            success: function (result, status, xhr) {
                var filename = "";
                var disposition = xhr.getResponseHeader('Content-Disposition');
                if (disposition && disposition.indexOf('attachment') !== -1) {
                    var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
                    var matches = filenameRegex.exec(disposition);
                    if (matches != null && matches[1]) {
                        filename = matches[1].replace(/['"]/g, '');
                    }
                }

                var blob = new Blob([result]);
                var link = document.createElement('a');
                link.href = window.URL.createObjectURL(blob);
                link.download = filename;
                link.click();
            }
        });

在此先感谢您的帮助!

更新:

从控制器返回的文件大小为 4 KB,在 ajax 端,接收到的 blob 大小为 7 KB。

标签: c#excelnpoi

解决方案


我不确定这是否有帮助。目前,当我的文件在 javascript 端下载时,我正在执行一项类似的任务,并遇到其他类型的问题。但是创建和下载的部分就像一个魅力。我没有使用 ajax,但这是我的代码:

在 javascript 中,我只是调用 Controller 和 HttpResponseMessage:

    XlsGlarm: function () {
        $('#mdlWait').modal('show');
        committente = globalCommittente;
        periodo = globalPeriodo;
        location.href = "Exports/XlsGLARM?CfCommit=" + committente + "&Periodo=" + periodo;
        $('#mdlWait').modal('hide');
    }

在 MVC 控制器中:

        public HttpResponseMessage XlsGLARM(string CfCommit, string Periodo)
    {
        // here I load an Excel Template and build the workbook
        // and fill it. But iit's not realted to your question.

            using (MemoryStream tmpStream = new MemoryStream())
            {
                Response.Clear();
                Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                Response.AddHeader("content-disposition", "attachment;filename=" + fileName);
                workbook.Write(tmpStream);
                Response.BinaryWrite(tmpStream.ToArray());
                Response.End();
                return null;
            }

        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

最后,我从浏览器下载了我的文件,我用 Chorme、IE 和 Modzilla 对其进行了测试。


推荐阅读