C# 从控制器将数据导出到CSV
我正在使用ASP.NET MVC项目中的库将数据导出到CSV,发现导出的数据要么被切断,要么在较小的列表中,根本没有写入任何数据,并且我收到一个空白的CSV文件 My base controller有这样一个方法,继承自该类的控制器调用该方法以导出实体列表:C# 从控制器将数据导出到CSV,c#,asp.net-mvc,csvhelper,csvtools,C#,Asp.net Mvc,Csvhelper,Csvtools,我正在使用ASP.NET MVC项目中的库将数据导出到CSV,发现导出的数据要么被切断,要么在较小的列表中,根本没有写入任何数据,并且我收到一个空白的CSV文件 My base controller有这样一个方法,继承自该类的控制器调用该方法以导出实体列表: protected FileContentResult GetExportFileContentResult(IList data, string filename) { using (var memoryStrea
protected FileContentResult GetExportFileContentResult(IList data, string filename)
{
using (var memoryStream = new MemoryStream())
{
using (var streamWriter = new StreamWriter(memoryStream))
{
using (var csvWriter = new CsvWriter(streamWriter))
{
csvWriter.WriteRecords(data);
return File(memoryStream.ToArray(), "text/csv", filename);
}
}
}
}
随着1k+项列表的导出,最后几项似乎被切断。当项目列表小于~100时,返回的CSV文件为空且不包含任何数据
我尝试直接写入输出流而不是MemoryStream,得到了相同的结果
还尝试删除using语句,以防流被过早释放,但也没有导致任何更改
使用此库正确创建CSV文件的正确方法是什么?即,包含所有行,并且无论列表大小如何工作
编辑
决定放弃使用,转而使用另一个名为的库。这项工作没有任何问题。下面是我的代码供参考
protected FileContentResult GetExportFileContentResult(IList data, string filename)
{
using (var memoryStream = new MemoryStream())
{
using (var streamWriter = new StreamWriter(memoryStream))
{
var dt = DataTable.New.FromEnumerable(data);
dt.SaveToStream(streamWriter);
return File(memoryStream.ToArray(), "text/csv", filename);
}
}
}
另一方面,尝试了Simon在下面提出的直接使用内存流而不是调用ToArray的建议,但遇到了一个关于关闭内存流的错误,并且还没有时间调试它。原因是您没有将写入程序中的数据刷新到内存流中。写入程序在满时会定期刷新自身,但您需要确保在最后刷新 备选案文1:
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var csvWriter = new CsvWriter(streamWriter))
{
csvWriter.WriteRecords(data);
streamWriter.Flush();
memoryStream.Position = 0;
return File(memoryStream, "text/csv", filename);
}
备选案文2:
using (var memoryStream = new MemoryStream())
{
using (var streamWriter = new StreamWriter(memoryStream))
using (var csvWriter = new CsvWriter(streamWriter))
{
csvWriter.WriteRecords(data);
} // The stream gets flushed here.
memoryStream.Position = 0;
return File(memoryStream, "text/csv", filename);
}
原因是您没有将writer中的数据刷新到流中。写入程序在满时会定期刷新自身,但您需要确保在最后刷新 备选案文1:
using (var memoryStream = new MemoryStream())
using (var streamWriter = new StreamWriter(memoryStream))
using (var csvWriter = new CsvWriter(streamWriter))
{
csvWriter.WriteRecords(data);
streamWriter.Flush();
memoryStream.Position = 0;
return File(memoryStream, "text/csv", filename);
}
备选案文2:
using (var memoryStream = new MemoryStream())
{
using (var streamWriter = new StreamWriter(memoryStream))
using (var csvWriter = new CsvWriter(streamWriter))
{
csvWriter.WriteRecords(data);
} // The stream gets flushed here.
memoryStream.Position = 0;
return File(memoryStream, "text/csv", filename);
}
作为旁白:考虑使用实际的内存流对象从文件返回。这样它就变成了一个FileStreamResult。这是流到浏览器块,不分配大对象。嘿,这个帖子是有用的,但我们如何做到这一点没有记忆流?作为旁白:考虑使用实际的内存流对象从文件返回。这样它就变成了一个FileStreamResult。这是流到浏览器的块,不分配大对象。嘿,这篇文章是有用的,但我们如何做到这一点没有MemoryStream?我正在使用CsvHelper的CsvFactory类,所以有点不同,但textWriter.Flush为我做了诀窍!谢谢这是一个吹毛求疵的问题,但在选项2中,您可以使用memoryStream.ToArray作为文件的第一个参数,而不是将Position设置回0。我正在为CsvHelper使用CSVFFactory类,所以有点不同,但textWriter.Flush为我做了这件事!谢谢这是一个吹毛求疵的问题,但在选项2中,您可以使用memoryStream.ToArray作为文件的第一个参数,而不是将位置设置回0。