我正在尝试使用CSVHelper生成CSV文件并将其发送回浏览器,因此用户可以选择保存位置和文件名并保存数据。
该网站基于MVC。这里是我用于调用的jQuery按钮代码(数据是DTO列表的一些序列化Json表示):
$.ajax({
type: "POST",
url: unity.baseUrl + "common/ExportPayments",
data: data
});
这是控制器代码:
[HttpPost]
public FileStreamResult ExportPayments()
{
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
CsvWriter writer = new CsvWriter(sw);
List<Payment_dto> pd = _commonService.GetPayments();
foreach (var record in pd)
{
writer.WriteRecord(record);
}
sw.Flush();
return new FileStreamResult(ms, "text/csv");
}
这似乎完全没有实现 - 将方法步骤调用到正确的代码位但响应为空,更不用说为用户提供文件对话框来保存数据。我已经完成了这段代码,它从服务中恢复数据,写入并且不会抛出任何错误。那么我做错了什么?
编辑:回复此...
return File(ms.GetBuffer(), "text/csv", "export.csv");
...给我一个回复,包括我期待的csv格式的数据。但浏览器似乎仍然不知道如何处理它 - 没有为用户提供下载选项。
答案 0 :(得分:28)
尝试以下代码:
public FileStreamResult ExportPayments()
{
var result = WriteCsvToMemory(_commonService.GetPayments()());
var memoryStream = new MemoryStream(result);
return new FileStreamResult(memoryStream, "text/csv") { FileDownloadName = "export.csv" };
}
public byte[] WriteCsvToMemory(IEnumerable<Payment_dto> records)
{
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var csvWriter = new CsvWriter(streamWriter))
{
csvWriter.WriteRecords(records);
streamWriter.Flush();
return memoryStream.ToArray();
}
}
更新
下面是如何将复杂类型模型传递给使用GET
HTTP方法的操作方法。我不喜欢这种方法,它只是让你知道有一种方法来实现这一目标。
模型
public class Data
{
public int Id { get; set; }
public string Value { get; set; }
public static string Serialize(Data data)
{
var serializer = new JavaScriptSerializer();
return serializer.Serialize(data);
}
public static Data Deserialize(string data)
{
var serializer = new JavaScriptSerializer();
return serializer.Deserialize<Data>(data);
}
}
动作:
[HttpGet]
public FileStreamResult ExportPayments(string model)
{
//Deserialize model here
var result = WriteCsvToMemory(GetPayments());
var memoryStream = new MemoryStream(result);
return new FileStreamResult(memoryStream, "text/csv") { FileDownloadName = "export.csv" };
}
查看:
@{
var data = new Data()
{
Id = 1,
Value = "This is test"
};
}
@Html.ActionLink("Export", "ExportPayments", new { model = Data.Serialize(data) })
答案 1 :(得分:0)
尝试使用控制器:
HttpContext.Response.AddHeader("content-disposition", "attachment; filename=payments.csv");
答案 2 :(得分:0)
也可以使用动态关键字来转换任何数据
来自@Lin的代码
public FileStreamResult ExportPayments()
{
var result = WriteCsvToMemory(_commonService.GetPayments()());
var memoryStream = new MemoryStream(result);
return new FileStreamResult(memoryStream, "text/csv") { FileDownloadName = "export.csv" };
}
public byte[] WriteCsvToMemory(dynamic records)
{
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var csvWriter = new CsvWriter(streamWriter))
{
csvWriter.WriteRecords(records);
streamWriter.Flush();
return memoryStream.ToArray();
}
}