Иногда возникает необходимость выгрузить какие-то данные в удобном для пользователя формате, который позволит на них не только смотреть, но и как-то обрабатывать и редактировать. Самым очевидным межплатформенным решением в таком случае видится форма CSV.
Выгрузить CSV-файл с нужными данными можно несколькими способами:
красивым и правильным, с использованием ASP.NET хэндлера (о хендлерах я как-нибудь напишу отдельно),
изврашенным - написав консольное приложение, которое будет запускаться по определенному графику и создавать где-нибудь доступный для web-сервера файл,
и простым и не очень правильным - просто изменив MIME-тип в ASPX-странице.
Какой бы способ вы не выбрали, все сведется примерно к такому коду:
StringBuilder sb = new StringBuilder(); sb.AppendLine("1,2,3,4"); sb.AppendLine("5,6,7,8"); sb.AppendLine("9,10,11,12"); Response.ClearContent(); Response.Clear(); Response.ContentEncoding = Encoding.GetEncoding("Windows-1251"); Response.ContentType = "application/vnd.ms-excel"; Response.AddHeader("Content-Disposition", "attachment; filename=csvfile.csv;"); Response.Write(sb.ToString()); Response.Flush(); Response.End();
Если у вас операционная система Windows и установлена англоязычная локаль, то все будет работать и вы не узнаете что есть небольшая проблема до того момента, пока кто-то из пользователей вам об этом не сообщит.
А проблема вот в чем, если сменить локаль, например, на русскую или испанскую, то при открытии сгенерированного вами файла в Excel будет получаться вот такая ерунда:
Не знаю, как на других операционных системах и в других системах электронных таблиц, но Excel берет данные о разделителе элементов из настроек локали, посмотреть которые можно тут (это установки для русскоязычных настроек):
В ASP.NET единственное, что мы может узнать о локали пользователя - это ISO 639-1 строку, например "ru-RU". Это наводит на неприятные мысли либо о создании справочника разделителей для каждой строки локали или использования чего-нибудь типа OpenXML и создания полноценных .XLSX-файлов.
На самом деле, все значительно проще. Достаточно добавить в начало CSV-файла строку вида sep=<ваш разделитель>
например вот так:
sb.AppendLine("sep=,");
и все. Теперь сгенерированный вами файл будет открываться корректно. И естественно, разделителем можно назначит не только запятую.
Более короткий вариант:
ОтветитьУдалитьreturn File(Encoding.GetEncoding("Windows-1251").GetBytes(sb.ToString()), "text/csv", "Report123.csv");