我正在研究以CSV格式导出数据的机制。我正在使用jQuery以JSON
格式发送数据:
var data = JSON.stringify(dataToSend);
$.post('DumpToCSV', { 'data': data });
然后在控制器中我正在生成一个CSV文件:
public ActionResult DumpToCSV(string data)
{
Response.Clear();
XmlNode xml = JsonConvert.DeserializeXmlNode("{records:{record:" + data + "}}");
XmlDocument xmldoc = new XmlDocument();
//Create XmlDoc Object
xmldoc.LoadXml(xml.InnerXml);
//Create XML Steam
var xmlReader = new XmlNodeReader(xmldoc);
DataSet dataSet = new DataSet();
//Load Dataset with Xml
dataSet.ReadXml(xmlReader);
//return single table inside of dataset
var csv = CustomReportBusinessModel.ToCSV(dataSet.Tables[0], ",");
HttpContext context = System.Web.HttpContext.Current;
context.Response.Write(csv);
context.Response.ContentType = "text/csv";
context.Response.AddHeader("Content-Disposition", "attachment;filename=Custom Report.csv");
Response.End();
return null;
}
它会返回 CSV 作为响应,但我如何告诉浏览器卸载它?
这个主题的区别: 在 MVC 中返回文件以查看/下载 ASP.NET 是我在使用 AJAX 请求吗
根据一些可以发布到控制器的数据下载文件,最好不要使用Ajax,因为通过Ajax处理文件真的很难。一种可能的解决方案是添加指向其他库的链接。
我想建议你的是使用简单的GET请求:
在javaScript
代码中:
var urlParams = $.param(dataToSend);
window.location.href = "DumpToCSV"+ urlParams;
通过这种方式,您可以将所有数据序列化为 url 字符串,并且通过 Ajax 获取文件没有问题。
然后在您的Controller
中,如果您有非常大的文件,最好返回FileContentResult
甚至FileStreamResult
。此外,进入控制器的模型可以强类型化,MVC ModelBuilder
轻松地从 url 字符串映射它。所以你的数据对象可以是这样的c#类:
public class CSVData
{
public string Name { get; set; }
public int Count { get; set; }
public int SomeId { get; set; }
}
而且您根本不需要在控制器中对数据进行定制。在此处查看更多信息。
public FileContentResult DumpToCSV(CSVData data)
{
XmlNode xml = data.ToXmlNode();
XmlDocument xmldoc = new XmlDocument();
//Create XmlDoc Object
xmldoc.LoadXml(xml.InnerXml);
//Create XML Steam
var xmlReader = new XmlNodeReader(xmldoc);
DataSet dataSet = new DataSet();
//Load Dataset with Xml
dataSet.ReadXml(xmlReader);
//return single table inside of dataset
var csv = CustomReportBusinessModel.ToCSV(dataSet.Tables[0], ",");
return File(new System.Text.UTF8Encoding().GetBytes(csv), "text/csv", "Custom Report.csv");
}
如您所见,无需在 MVC 中使用HttpContext
在您的情况下,您可以以更干净、更明显的方式做到这一点。
附言。如果你的csv
对象只是一个byte[]
那么你可以这样写:
return File(csv, "text/csv", "Custom Report.csv");