91 Stimmen

Export nach CSV mit MVC, C# und jQuery

Ich versuche, eine Liste in eine CSV-Datei zu exportieren. Es funktioniert alles bis zu dem Punkt, an dem ich die Datei in den Antwortstrom schreiben möchte. Das tut aber nichts.

Hier ist mein Code:

Rufen Sie die Methode von der Seite aus auf.

$('#btn_export').click(function () {
         $.post('NewsLetter/Export');
});

Der Code im Controller sieht wie folgt aus:

[HttpPost]
        public void Export()
        {
            try
            {
                var filter = Session[FilterSessionKey] != null ? Session[FilterSessionKey] as SubscriberFilter : new SubscriberFilter();

                var predicate = _subscriberService.BuildPredicate(filter);
                var compiledPredicate = predicate.Compile();
                var filterRecords = _subscriberService.GetSubscribersInGroup().Where(x => !x.IsDeleted).AsEnumerable().Where(compiledPredicate).GroupBy(s => s.Subscriber.EmailAddress).OrderBy(x => x.Key);

                ExportAsCSV(filterRecords);
            }
            catch (Exception exception)
            {
                Logger.WriteLog(LogLevel.Error, exception);
            }
        }

        private void ExportAsCSV(IEnumerable<IGrouping<String, SubscriberInGroup>> filterRecords)
        {
            var sw = new StringWriter();
            //write the header
            sw.WriteLine(String.Format("{0},{1},{2},{3}", CMSMessages.EmailAddress, CMSMessages.Gender, CMSMessages.FirstName, CMSMessages.LastName));

            //write every subscriber to the file
            var resourceManager = new ResourceManager(typeof(CMSMessages));
            foreach (var record in filterRecords.Select(x => x.First().Subscriber))
            {
                sw.WriteLine(String.Format("{0},{1},{2},{3}", record.EmailAddress, record.Gender.HasValue ? resourceManager.GetString(record.Gender.ToString()) : "", record.FirstName, record.LastName));
            }

            Response.Clear();
            Response.AddHeader("Content-Disposition", "attachment; filename=adressenbestand.csv");
            Response.ContentType = "text/csv";
            Response.Write(sw);
            Response.End();
        }

Aber nach Response.Write(sw) Es passiert nichts. Ist es überhaupt möglich, eine Datei auf diese Weise zu speichern?

Mit freundlichen Grüßen

Editer
Wenn ich auf die Schaltfläche klicke, sehe ich die folgenden Antwort-Header:

HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/csv; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 2.0
Content-Disposition: attachment; filename=adressenbestand.csv
X-Powered-By: ASP.NET
Date: Wed, 12 Jan 2011 13:05:42 GMT
Content-Length: 113

Das scheint mir in Ordnung zu sein

Editer
Ich bin den jQuery-Teil losgeworden und habe ihn durch einen Hyperlink ersetzt, und jetzt funktioniert es bei mir gut:

<a class="export" href="NewsLetter/Export">exporteren</a>

262voto

Biff MaGriff Punkte 7991

Yan.kun war auf dem richtigen Weg, aber das hier ist viel einfacher.

    public FileContentResult DownloadCSV()
    {
        string csv = "Charlie, Chaplin, Chuckles";
        return File(new System.Text.UTF8Encoding().GetBytes(csv), "text/csv", "Report123.csv");
    }

14voto

yan.kun Punkte 6730

Mit MVC können Sie einfach eine Datei wie diese zurückgeben:

public ActionResult ExportData()
{
    System.IO.FileInfo exportFile = //create your ExportFile
    return File(exportFile.FullName, "text/csv", string.Format("Export-{0}.csv", DateTime.Now.ToString("yyyyMMdd-HHmmss")));
}

7voto

Harminder Punkte 2189

Ergänzend zur Antwort von Biff MaGriff. Um die Datei mit JQuery zu exportieren, leiten Sie den Benutzer auf eine neue Seite um.

$('#btn_export').click(function () {
    window.location.href = 'NewsLetter/Export';
});

5voto

chris Punkte 34644

Was passiert, wenn Sie den Stringwriter loswerden?

        Response.Clear();
        Response.AddHeader("Content-Disposition", "attachment; filename=adressenbestand.csv");
        Response.ContentType = "text/csv";
        //write the header
        Response.Write(String.Format("{0},{1},{2},{3}", CMSMessages.EmailAddress, CMSMessages.Gender, CMSMessages.FirstName, CMSMessages.LastName));

        //write every subscriber to the file
        var resourceManager = new ResourceManager(typeof(CMSMessages));
        foreach (var record in filterRecords.Select(x => x.First().Subscriber))
        {
            Response.Write(String.Format("{0},{1},{2},{3}", record.EmailAddress, record.Gender.HasValue ? resourceManager.GetString(record.Gender.ToString()) : "", record.FirstName, record.LastName));
        }

        Response.End();

3voto

MonsCamus Punkte 111

Respekt an Biff, hier ist ein paar Tweaks, die mich die Methode zu verwenden, um CSV von jQuery/Post gegen den Server bounce und kommen zurück als CSV-Eingabeaufforderung an den Benutzer.

    [Themed(false)]
    public FileContentResult DownloadCSV()
    {

        var csvStringData = new StreamReader(Request.InputStream).ReadToEnd();

        csvStringData = Uri.UnescapeDataString(csvStringData.Replace("mydata=", ""));

        return File(new System.Text.UTF8Encoding().GetBytes(csvStringData), "text/csv", "report.csv");
    }

Sie benötigen die unescape-Zeile, wenn Sie dies aus einem Formular mit Code wie dem folgenden aufrufen,

    var input = $("<input>").attr("type", "hidden").attr("name", "mydata").val(data);
    $('#downloadForm').append($(input));
    $("#downloadForm").submit();

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X