Експорт у CSV за допомогою MVC, C # та jQuery


85

Я намагаюся експортувати список у файл CSV. Я все це працював до того моменту, до якого я хочу написати файл у потік відповідей. Це нічого не робить.

Ось мій код:

Викличте метод зі сторінки.

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

Код у контролері такий:

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

Але після Response.Write(sw)нічого не відбувається. Чи можливо зберегти файл таким чином?

З повагою

Редагувати
заголовки відповідей, які я бачу, натискаючи кнопку:

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

Що здається мені нормально ..

Редагувати
Я позбувся частини jQuery en, замінивши її гіперпосиланням, і це зараз у мене працює нормально:

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

1
Можливо, це питання щодо SO допомагає: stackoverflow.com/questions/4522590/…
Роб

Не могли б ви задокументувати свою відповідь як фактичну, а не редагувати запитання, будь ласка.
Калтор

Відповіді:


250

yan.kun був на правильному шляху, але це набагато простіше.

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

Як би ми обробляли рядки, які містять коми? Я спробував використовувати подвійні лапки в якості кваліфікаторів тексту, але, здається, це не працює.
Mike Cole

1
@mmssaann У цьому вся краса, ви не використовуєте javascript. Ви просто встановили href тегу прив’язки до дії. <a href="ControllerName/ActionName">Download CSV</a>
Biff MaGriff

1
Я встановив href для прив'язки тегу. Це працює нормально. Однак я все ще бачу, що вся сторінка розміщена назад. чи є спосіб обмежити зворотну передачу?
mmssaann

1
@mmssaann Вам слід задати нове запитання з деталями про вашу конкретну установку.
Biff MaGriff

1
Я використовую твій спосіб для створення CSV для завантаження, все здається нормально, я налагоджую, це надходить до контролера. Але браузер не відображає жодних ознак завантаження файлу? Ви думаєте, що сталося, мені потрібно змінити Web.config чи щось інше?
zquanghoangz

13

За допомогою MVC ви можете просто повернути такий файл:

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

8
Ви дійсно хочете створити купу файлів на веб-сервері? А як щодо їх очищення? А як щодо безпеки?
chris

@chris хіба це не створює файли в пам'яті сервера, а не у файловій системі?
galdin

Я використовую твій спосіб для створення CSV для завантаження, все здається нормально, я налагоджую, це надходить до контролера. Але браузер не відображає жодних ознак завантаження файлу? Ви думаєте, що сталося, мені потрібно змінити Web.config чи щось інше?
zquanghoangz,

7

На додаток до відповіді Біффа Маґріфа. Щоб експортувати файл за допомогою JQuery, переспрямуйте користувача на нову сторінку.

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

5

Що станеться, якщо ви позбудетеся авторів струн:

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

ні, що теж не має значення. Я вирішив це вже по-іншому. Перегляньте мою редакцію. Дякуємо за вашу допомогу!
Gerard

3

З повагою до Біффа, ось кілька налаштувань, які дозволяють мені використовувати метод, щоб відхилити CSV від jQuery / Post проти сервера і повернутися як запит CSV до користувача.

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

Вам знадобиться рядок Unescape, якщо ви натискаєте це з форми з кодом, як показано нижче,

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

3

За допомогою кнопки у вікні виклику .click (викликати якийсь сценарій Java). Звідти викличте метод контролера за допомогою window.location.href = 'Контролер / Метод';

У контролері або виконують виклик бази даних і отримують таблицю даних, або виклик якогось методу отримує дані з таблиці бази даних до таблиці даних, а потім виконує наступне:

using (DataTable dt = new DataTable())
                        {
                            sda.Fill(dt);
                            //Build the CSV file data as a Comma separated string.
                            string csv = string.Empty;
                            foreach (DataColumn column in dt.Columns)
                            {
                                //Add the Header row for CSV file.
                                csv += column.ColumnName + ',';
                            }
                            //Add new line.
                            csv += "\r\n";
                            foreach (DataRow row in dt.Rows)
                            {
                                foreach (DataColumn column in dt.Columns)
                                {
                                    //Add the Data rows.
                                    csv += row[column.ColumnName].ToString().Replace(",", ";") + ',';
                                }
                                //Add new line.
                                csv += "\r\n";
                             }
                             //Download the CSV file.
                             Response.Clear();
                             Response.Buffer = true;
                             Response.AddHeader("content-disposition", "attachment;filename=SqlExport"+DateTime.Now+".csv");
                             Response.Charset = "";
                             //Response.ContentType = "application/text";
                             Response.ContentType = "application/x-msexcel";
                             Response.Output.Write(csv);
                             Response.Flush();
                             Response.End();
                           }

1

Навіть якщо ви вирішили свою проблему, ось ще одна спроба експортувати CSV за допомогою mvc.

return new FileStreamResult(fileStream, "text/csv") { FileDownloadName = fileDownloadName };

0

Я думаю, ви забули використовувати

  Response.Flush();

під

  Response.Write(sw);

будь ласка, перевірте


-3

Простий файл Excel, створений у mvc 4

public ActionResult results () {return File (new System.Text.UTF8Encoding (). GetBytes ("string data"), "application / csv", "filename.csv"); }


Це невдала відповідь. Будь ласка, зверніться до розділу Як написати хорошу відповідь?
Клайстерс,

Це хороша відповідь. Він просто погано відформатований і дублює найкращу відповідь, яка була розміщена 6 роками раніше. : D
Калтор
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.