Ajax 如何在.net MVC4上正确创建和下载动态生成的二进制*.xlsx文件?
我需要制作一个“导出到excel”功能 Excel是一个二进制文件,如果您使用其XML格式,它会在msExcel上发送警告 我目前正在做的是用我的所有数据保留一个状态对象(因为我需要知道用户正在做的各种更改),并使用ajax将其传递给一个.net MVC控制器,该控制器使用一个库来创建*.xlsx文件 客户端:Ajax 如何在.net MVC4上正确创建和下载动态生成的二进制*.xlsx文件?,ajax,asp.net-mvc-4,export-to-excel,xlsx,Ajax,Asp.net Mvc 4,Export To Excel,Xlsx,我需要制作一个“导出到excel”功能 Excel是一个二进制文件,如果您使用其XML格式,它会在msExcel上发送警告 我目前正在做的是用我的所有数据保留一个状态对象(因为我需要知道用户正在做的各种更改),并使用ajax将其传递给一个.net MVC控制器,该控制器使用一个库来创建*.xlsx文件 客户端: $.ajax({ type: "POST", url: "/path/to/exportController", data: exporter.getData(
$.ajax({
type: "POST",
url: "/path/to/exportController",
data: exporter.getData(),
success: success,
error: error,
dataType: 'json'
});
服务器端:
public ActionResult Excel(mySpecialandIrrelevantDescriptiveClass jsonData)
{
//excel generation logic
.....
}
现在从我的角度来看,我有3个选择:
实现我所需要的最好方法是什么?有很多这样的问题:
、
或窗口使用某种重定向
这可能是一种方法,但是如果你觉得足够冒险,我也会尝试HTML5 Blob API、文件系统和/或类型化数组的组合。因此我最终得到了它:
您不能使用ajax返回二进制文件—您将收到其数据—但无法显示二进制文件
我将其用作excel库,并通过通用HTML表单隐藏字段中的post方法传递数据。
输出是使用流作为返回值生成的,因此用户可以在页面上保持不刷新/重定向
服务器:
//the expected data description - automatic tool @ http://json2csharp.com/
public class ExpectedJSON
{
public class SomeDataSet
{
public string dude{ get; set; }
public string what { get; set; }
public string foo { get; set; }
public string bar { get; set; }
public string baz { get; set; }
public int asd { get; set; }
public string someDate { get; set; }
public string wat { get; set; }
public string grrr { get; set; }
}
public class AnotherDataSet
{
public int type { get; set; }
public string date { get; set; }
public string dancing { get; set; }
public double camels { get; set; }
public int are { get; set; }
public int crying { get; set; }
public double _for { get; set; }
public double some { get; set; }
public double beer { get; set; }
}
public class MoreData
{
public int dark { get; set; }
public double side { get; set; }
public int of { get; set; }
public int the { get; set; }
public double moon { get; set; }
public double iz { get; set; }
public double da { get; set; }
public string bomb { get; set; }
}
}
public class ExportToController : Controller
{
public ActionResult Excel([FromUri(Name= "someData")] string someDataSet,
[FromUri(Name = "anotherData")] string anotherDataSet,
[FromUri(Name = "moreData")] string moreData)
{
ExpectedJSON.SomeDataSet someDataSetJson = JsonConvert.DeserializeObject<ExpectedJSON.SomeDataSet>(someData);
ExpectedJSON.AnotherDataSet[] anotherDataSetJson = JsonConvert.DeserializeObject<Campaign.OnlineComulativeDailyBuildChart[]>(anotherData);
ExpectedJSON.MoreData[] moreDataJson = JsonConvert.DeserializeObject<Campaign.OnlineSitesGrid[]>(moreData);
string fileName = "file.xlsx";
ExcelPackage p = new ExcelPackage();
p.Workbook.Worksheets.Add("Some Sheet");
ExcelWorksheet ws = p.Workbook.Worksheets[1];
//excel library logic follows...
//...
//..
//stream logic
MemoryStream stream = new MemoryStream(p.GetAsByteArray());
FileStreamResult result = new FileStreamResult(stream, "application/vnd.ms-excel")
{
FileDownloadName = fileName
};
return result;
}
}
使用rails/sinatra/nodeJS只需几分钟,使用.net只需几天/几周,但你就可以做到了。如果你注意到这一点,你会发现使用ajax下载文件是不可能的:你可以接收二进制文件的数据,但你没有任何方法将其显化。为了实现这一点,你可以使用flash,类似于Downloadify,不过你知道,flash:)谢谢你的提示,会让每个人都发帖的。是的,我知道了,大多数解决方案都是将这些数据重定向到某种mime类型的url。我相信它也可以通过HTML5 blob api实现。
<form id="exportToExcel" action="../ExportTo/Excel/" target="_blank" method="post">
<input type="hidden" id="someData" name="someData" />
<input type="hidden" id="anotherData" name="anotherData" />
<input type="hidden" id="moreData" name="moreData" />
<button type="submit">export</button>
</form>
function bindEvents() {
var exportForm = $("#exportToExcel");
var someData= exportForm.find("#someData");
var anotherData= exportForm.find("#anotherData");
var moreData = exportForm.find("#moreData");
exportForm.on('submit', function (e) {
someData.attr("value", JSON.stringify(exporter.getData().someData));
anotherData.attr("value", JSON.stringify(exporter.getData().anotherData));
moreData .attr("value", JSON.stringify(exporter.getData().moreData));
});
}