Експорт у 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.