[英]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.