Правильная реализация генерации excel отчётов в среде .NET?
Доброго времени суток. Задача. Генерация excel файлов по-расписанию (отчёты), отчёты сохраняются в папке, из интерфейса WEB-приложения отчёты доступны пользователям. Определённой группе пользователей ведётся рассылка данных отчётов. Как реализовано сейчас. Консольное приложение (запускается виндовым шедуллером по расписанию) генерирует по очереди необходимые файлы excel, используется Microsoft.Office.Interop.Excel, после того как все файлы сформированы в этом же приложении запускается метод который производит почтовую рассылку. Проблема. Microsoft.Office.Interop.Excel очень медленно работает. На формирование одного файла (20000 строк, 15 колонок) уходит 10 минут. Соответственно, чтобы сформировать 30 подобных отчётов уходит несколько часов. Ставил временные маркеры, работает медленно именно Microsoft.Office.Interop.Excel (var reader = command.ExecuteReader();), SQL запрос и другая логика отрабатывают очень быстро. Скрытая проблема. Подозреваю, что решение данной задачи таким способом архитектурно не верно. Вопросы.
1. Все библиотеки в .net так медленно формируют exel файлы? Или же есть библиотеки которые работают намного быстрее (например EPPlus, OpenXML)?
2. Имеет ли место быть описанный подход решения данной задачи?
3. Какое посоветуете решение данной задачи? (Может вообще нужно использовать другие технологии, например, sql reporting services).
OpenXML очень быстр но там много разной низкоуровневой ерунды которая врят-ли будет нужна, хотя если разберетесь то это будет самы быстрый вариант, а так, хороший выбором будет либо EPPlus либо ClosedXml.
Скорее всего, код генерации excel файлов написан криво.
У меня лист 300к на 14 колонок + несколько лёгких листов через Interop.Excel формируется несколько секунд. Ну явно меньше минуты.
Сейчас я переделал через EPPlus. Работает очень быстро.
Оригинал код я уже удалил (Interop.Excel).
Но была такая схема: в List объектов получаем данные из базы, далее в цикле перебираем это лист, вставляем в excel. Код вставки типа того:
DateTime start2 = DateTime.Now;
int i = 1;
foreach (var item in list)
{
i++;
sheet.Cells[i, 1] = item.itemName1;
sheet.Cells[i, 2] = item.itemName2;
sheet.Cells[i, 3] = item.itemName3;
sheet.Cells[i, 4] = item.itemName4;
aamaster, жаль, что Вам уже не актуально, но кому-нибудь пригодится: вставлять нужно не в каждую ячейку, а большим куском. Изначально создаем массив:
var data = new object[rowCount, columnCount];
Заполняем массив нужными данными и вставляем в Excel сразу весь массив:
var range = worksheet.get_Range("A2","Z5");
range.Value = data;
Спасибо за ответы. Настроил через EPPlus. Работает очень быстро, три больших файла формирует за 10 секунд.
А темплейты это вообще что-то суперское.
В данный момент описанная в вопросе задача решается через EPPlus, вроде, без проблем. Но всё же, если у кого есть мысли (опыт) по поводу пунктов 2 и 3 будет весьма любопытно.
Если интересуют генераторы отчётов, то можно попробовать использовать FastReport.Net/FastReport.Desktop. Первый вариант можно встроить в веб приложение на ASP.Net/Core, десктоп умеет, как и ваше консольное приложение по расписанию генерировать отчёты. Плюс - будет проще создавать шаблоны отчётов: есть графический дизайнер, есть рассылка на почту, в телеграм и др. Ну и экспорты, кроме, экселя, например PDF, Word и т.д.
Crystal Reports
Crystal Enterprise Reports
Report Application Service
сделаны для создания и поддерожки объемных систем отчетностей
формат на выходе любой pdf,excel,word,text,...