将数据从Controller导出到CSV [英] Exporting data to CSV from Controller

查看:243
本文介绍了将数据从Controller导出到CSV的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在ASP.NET MVC项目中使用 CsvHelper 库将数据导出到CSV,并且发现导出的数据已被切断,或者在列表较小的情况下,根本没有写入任何数据,并且我收到的是空白CSV文件.

I'm using the CsvHelper library in an ASP.NET MVC project to export data to CSV, and am finding that the exported data is either cut off, or in the case of smaller lists, no data is being written at all, and I'm receiving a blank CSV file.

我的基本控制器具有这样的方法(由从此类继承以导出实体列表的控制器调用):

My base controller has a method like this (which is called by controllers inheriting from this class to export lists of entities):

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文件为空白,并且不包含任何数据.

With exports of lists 1k+ items, it seems like the last few items get cut off. When the list of items is less than ~100, the CSV file returned is blank and contains no data.

我尝试直接写到输出流而不是MemoryStream上,并收到相同的结果.

I've tried writing straight to the output stream instead of a MemoryStream, and received the same results.

还尝试删除using语句,以防流被过早处置,但也未导致任何更改.

Also tried removing the using statements in case the stream was being disposed too early, but didn't result in any change either.

使用此库正确创建CSV文件(即包含所有行,并且不管列表大小如何)的正确方法是什么?

What is the correct way to use this library to create CSV files properly (ie. contains all rows, and works regardless of size of list)?

修改

决定使用 CsvHelper 进行报废,并使用另一个名为

Decided to scrap using CsvHelper and went with a different library called CsvTools instead. This works without any problems. My code is below for reference.

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);
        }
    }
}

顺便提一下,下面尝试了西蒙的建议,即直接使用内存流而不是调用ToArray,但遇到了有关流被关闭的错误,并且尚未进行调试.

On a side note, tried Simon's suggestion below of using the memory stream directly instead of calling ToArray but got an error about the stream being closed, and haven't got round to debugging this yet.

推荐答案

原因是因为您没有将写入器中的数据刷新到流中.写满后,编写器会定期刷新自身,但是您需要确保最后完成刷新.

The reason is because you're not flushing the data in the writer to the stream. The writer will periodically flush itself when it's full, but you need to make sure to do it at the end.

选项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);
}

这篇关于将数据从Controller导出到CSV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆