.net 使用CSVHelper将流输出到浏览器

dy2hfwbg  于 2023-05-01  发布在  .NET
关注(0)|答案(4)|浏览(82)

我尝试使用CSVHelper生成CSV文件并将其发送回浏览器,以便用户可以选择保存位置和文件名并保存数据。
网站是基于MVC的。下面是我用来调用的jQuery按钮代码(data是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格式的数据。但浏览器似乎仍然不知道该怎么做-没有下载选项提供给用户。

nzk0hqpo

nzk0hqpo1#

试试下面的代码:

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方法的action方法。我不喜欢这种方法,它只是给你一个想法,有一种方法来实现这一点。
型号

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

x759pob22#

ASP.NET Core解决方案:

var memoryStream = new MemoryStream();
var streamWriter = new StreamWriter(memoryStream, Encoding.UTF8); // No 'using' around this as it closes the underlying stream. StreamWriter.Dispose() is only really important when you're dealing with actual files anyhow.

using (var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture, true)) // Note the last argument being set to 'true'
    csvWriter.WriteRecords(...);

streamWriter.Flush(); // Perhaps not necessary, but CsvWriter's documentation does not mention whether the underlying stream gets flushed or not

memoryStream.Position = 0;

Response.Headers["Content-Disposition"] = "attachment; filename=somename.csv";

return File(memoryStream, "text/csv");
7uhlpewt

7uhlpewt3#

在控制器中尝试:

HttpContext.Response.AddHeader("content-disposition", "attachment; filename=payments.csv");
pb3skfrl

pb3skfrl4#

也可以使用dynamic关键字转换任何数据
来自@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();
    }
}

相关问题