Utiliser CSVHelper pour afficher le flux vers le navigateur

J'essaie D'utiliser CSVHelper pour générer un fichier CSV et le renvoyer à un navigateur, afin que l'utilisateur puisse sélectionner un emplacement et un nom de fichier de sauvegarde et sauvegarder les données.

le site web est basé sur MVC. Voici le code de bouton jQuery que j'utilise pour faire l'appel (data est une représentation JSON sérialisée d'une liste DTO):

    $.ajax({
        type: "POST",
        url: unity.baseUrl + "common/ExportPayments",
        data: data
    });

Voici le code du contrôleur:

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

qui semble précisément n'atteindre rien - invoquer la méthode fait un pas dans le bon morceau de code mais la réponse est vide, encore moins offrir à l'utilisateur un dialogue de fichier pour enregistrer les données. J'ai parcouru ce code, et il ramène des données du service, l'écrit, et ne jette aucune erreur. Donc, ce que je fais mal?

EDIT: de Retour cette ...

return File(ms.GetBuffer(), "text/csv", "export.csv");

... me donne une réponse, composé des données csv-formatted que j'attends. Mais le navigateur ne semble toujours pas savoir quoi en faire - aucune option de téléchargement n'est offerte à l'utilisateur.

25
demandé sur Matt Thrower 2014-01-13 18:02:12

3 réponses

Essayez de code ci-dessous:

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

mise à Jour

Voici comment passer un modèle de type complexe à une méthode d'action qui utilise GET méthode HTTP. Je ne préfère pas cette approche, elle vous donne juste une idée qu'il y a une approche pour y parvenir.

Modèle

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

Action:

    [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" };
    }

Vue:

@{
    var data = new Data()
    {
        Id = 1,
        Value = "This is test"
    };
}
@Html.ActionLink("Export", "ExportPayments", new { model = Data.Serialize(data) })
25
répondu Lin 2014-01-13 20:13:35

Essayer dans le contrôleur:

HttpContext.Response.AddHeader("content-disposition", "attachment; filename=payments.csv");
0
répondu Marcin Wachulski 2014-01-13 14:40:36

peut aussi utiliser le mot-clé dynamique pour convertir n'importe quelles données

Code de @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();
    }
}
0
répondu Arun Prasad E S 2017-05-03 10:42:42