我有一个 .Net 6 Razor 页面应用程序,我需要通过 Ajax 单击按钮来下载 Excel。我可以通过像这样使用 OpenXML 在内存流中创建一个新的 Excel 工作簿来成功地做到这一点。
C# 代码
public IActionResult OnPostAjaxExport(string somedata)
{
// Create a dummy data table
DataSet ds = MakeDummyDataSet();
//Export Excel via Memory Stream
MemoryStream ms = ExportDataSetViaMemoryStream(ds);
return new FileStreamResult(ms, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
private MemoryStream ExportDataSetViaMemoryStream(DataSet ds)
{
MemoryStream memoryStream = new MemoryStream();
using (var workbook = SpreadsheetDocument.Create(memoryStream, SpreadsheetDocumentType.Workbook))
{
var workbookPart = workbook.AddWorkbookPart();
workbook.WorkbookPart.Workbook = new Workbook();
// Further code to populate the workbook...
memoryStream.Seek(0, SeekOrigin.Begin);
return memoryStream;
}
}
Ajax代码
$.ajax({
type: "POST",
url: "/Index?handler=AjaxExport",
data: payload,
xhrFields: {
responseType: 'blob'
},
headers: {
RequestVerificationToken:
$('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (result) {
var a = document.createElement('a');
var url = window.URL.createObjectURL(result);
a.href = url;
a.download = 'download.xlsx';
a.click();
window.URL.revokeObjectURL(url);
},
error: function (result) {
alert("error: " + JSON.stringify(result));
}
});
这工作正常。在 Ajax 按钮上单击我可以在浏览器中下载 excel。
但是现在我有一个新要求,要下载一些预先存在的 Excel 文件,并将其保存到服务器中的物理位置。
这些文件的路径无法在浏览器中直接访问。所以我尝试将文件读入内存流并将它们返回到 Ajax 函数,就像我之前所做的那样。
这是我尝试过的。
public IActionResult OnPostDownloadPreGeneratedFile()
{
string FilePath = @"C:\Manas\FilePath\DownloadTest\payload2.xlsx";
string ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
//read the file and prepare memory stream
MemoryStream ms = new MemoryStream();
FileStream file = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
ms.Seek(0, SeekOrigin.Begin);
file.CopyTo(ms);
return new FileStreamResult(ms, ContentType);
}
但这不起作用,尽管我正在创建与之前创建的相同的内存流类型。
控制台或Ajax调用不显示任何错误。只是 C# 代码返回
FilestreamResult
,然后浏览器中什么也没有发生。
我怎样才能做到这一点?
没关系,我找到了解决方案。我只需要这样做:
public IActionResult OnPostDownloadPreGeneratedFile()
{
string FilePath = @"C:\Manas\FilePath\DownloadTest\payload2.xlsx";
string ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
//read the file and prepare memory stream
var stream = new FileStream(FilePath, FileMode.Open);
return new FileStreamResult(stream, ContentType);
}