Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从控制器将数据导出到CSV_C#_Asp.net Mvc_Csvhelper_Csvtools - Fatal编程技术网

C# 从控制器将数据导出到CSV

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

我正在使用ASP.NET MVC项目中的库将数据导出到CSV,发现导出的数据要么被切断,要么在较小的列表中,根本没有写入任何数据,并且我收到一个空白的CSV文件

My base controller有这样一个方法,继承自该类的控制器调用该方法以导出实体列表:

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。