繁体   English   中英

文件下载问题——ASP.NET MVC应用

[英]File download problem - ASP.NET MVC application

我在 ASP.NET MVC 应用程序的视图中有两个 controller 操作和 js,用于生成和下载 Excel 文件。 所有相关代码都显示在这里:

public ActionResult GetExcel()
{
    string handle = Guid.NewGuid().ToString();

    using (MemoryStream MemoryStream = new MemoryStream())
    {
        //GetExcelData returns an OfficeOpenXml.ExcelPackage object
        GetExcelData().SaveAs(MemoryStream);
        MemoryStream.Position = 0;
        TempData[handle] = MemoryStream.ToArray();
    }

    return new JsonResult()
    {
        Data = new { FileGuid = handle, FileName = "FileName" + DateTime.Now.ToString() + ".xlsx" }
    };
}

public virtual ActionResult Download(string fileGuid, string fileName)
{
    if (TempData[fileGuid] != null)
    {
        byte[] data = TempData[fileGuid] as byte[];
        return File(data, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
    }
    else
    {
        return new EmptyResult();
    }
}

$.ajax({
  url: '@Url.Action("GetExcel", "Products")',
  type: 'POST',  
}).done(function (data) {  
  window.location = '@Url.Action("Download", "Products")' + '?fileGuid=' + data.FileGuid + '&filename=' + data.FileName;
});

我的问题是此代码导致不一致的行为。

有时它会按预期工作,我会收到下载文件屏幕的提示,但有时会导致空白页面,文件路径为浏览器的 url。

在此处输入图像描述

我注意到的一件事是,当问题发生时,浏览器的 .network 选项卡上的文档类型是普通的,而不是预期application/vnd.openxmlformats-officedocument.spreadsheetml.sheet

还有一点就是这个刚好发生在应用在服务器上的IIS上。 这不会在开发环境中本地发生。

此外,显然,这似乎与文件大小无关,因为它发生在小型和大型数据集上。

我使用EPPlus库生成并下载了一个 excel 文件。 从 Manage Nuget Packages 安装EPPLUS 确保如果您使用该库,则在 NonCommercial LicenseContext 下使用它作为 ExcelPackage.LicenseContext = LicenseContext.NonCommercial

如果您想直接通过锚标记链接“@Url.Action("Test","Test")" 生成,请使用以下代码。

 using (ExcelPackage excel = new ExcelPackage())
    {
          var stream = new MemoryStream();
          ExcelWorksheet worksheet = 
          excelPackage.Workbook.Worksheets.Add("TestWork");
        //add values in your worksheet cells you can also loop through it like  
        //worksheet.Cells[i + 2, 1].Value where i is an index starting from 0 and 1 is the column index [rowIndex,columnIndex]
         worksheet.Cells["A1"].Value = "Date";
         worksheet.Cells["A2"].Value = "10-10-2021";
        //add table styling
        int firstRow = 1;
        int lastRow = worksheet.Dimension.End.Row;
        int firstColumn = 1;
        int lastColumn = worksheet.Dimension.End.Column;
        ExcelRange rg = worksheet.Cells[firstRow, firstColumn, lastRow, lastColumn];
        string tableName = "Table1";
        ExcelTable tab = worksheet.Tables.Add(rg, tableName);
        tab.TableStyle = TableStyles.Medium2;
        excel.Save();
        byte[] bin = excelPackage.GetAsByteArray();
        Response.ClearHeaders();
        Response.Clear();
        Response.Buffer = true;
        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        Response.AddHeader("content-length", bin.Length.ToString());
        this.Response.AddHeader("content-disposition", string.Format("attachment;  filename={0}", YourFileName));
        Response.OutputStream.Write(bin, 0, bin.Length);
        Response.Flush();
    }

如果您发送 ajax 请求,则代码将相同,直到 excel.Save(); 只需更改响应的返回类型,例如 JsonResult

 var fileObject = File(excel.GetAsByteArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "Report.xlsx");
 return new JsonResult()
                            {
                                Data = fileObject,
                                ContentType = "application/json;  charset=utf-8",
                                ContentEncoding = Encoding.UTF8,
                                JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                                MaxJsonLength = Int32.MaxValue
                            };

您遇到的问题可能与文件大小有关,只需尝试使用最大长度将响应包装在 JSON 中

 return new JsonResult()
                        {
                            Data = fileObject,
                            ContentType = "application/json;  charset=utf-8",
                            ContentEncoding = Encoding.UTF8,
                            JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                            MaxJsonLength = Int32.MaxValue
                        };

Ajax 请求从服务器返回的JSONResult响应中下载文件object 成功 function

 $.ajax({
            type: 'POST',
            url: '',
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (response) {
                var bytes = new Uint8Array(response.FileContents);
                var blob = new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
                var downloadUrl = URL.createObjectURL(blob);
                var a = document.createElement("a");
                a.href = downloadUrl;         
                a.download = "Filename.xlsx";
                document.body.appendChild(a);
                a.click();
            },
            error: function (err) {
                alert(err);
            },
            cache: false
        });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM