Многие сталкиваются с необходимостью передачи (экспорта) данных из своих программы в Excel.
Ниже мы рассмотрим два варианта для записи данных в Excel файл.
Первый вставка значений в каждую ячейку из кода программы, путем простого перебора (и да… оказывается так многие делают и сейчас)
Второй вариант это заполнение двумерного массива необходимыми значениями и последующая вставка этого массива целиком, так сказать разом.
Ниже представлен маленький тест демонстрирующий разницу в скорости работы двух методов вставки:
using System; using System.Diagnostics; using System.Runtime.InteropServices;</code> namespace ExcelTestNet { class Program { static void Main(string[] args) { Excel.Application xlApp; //Рабочая книга Excel.Workbook xlWorkbook; //Лист Excel._Worksheet xlWorksheet; //Диапазон Excel.Range xlRange; //Создаем Excel xlApp = new Excel.Application(); //Создали книгу xlWorkbook = xlApp.Workbooks.Add(); //Добавили новый лист xlWorksheet = (Excel._Worksheet)xlWorkbook.Sheets[1]; //Создали и запустили таймер Stopwatch watch = new Stopwatch(); watch.Start(); for (int row = 1; row < 100; row++) for (int col = 1; col < 100; col++) ((Excel.Range)xlWorksheet.Cells[row, col]).Value2 = "row:" + Convert.ToString(row) + ", col:" + Convert.ToString(col); //Остановили таймер watch.Stop(); Console.WriteLine("Потрачено времени {0}", watch.Elapsed); //Создали новый лист xlWorkbook.Sheets.Add(); xlWorksheet = (Excel._Worksheet)xlWorkbook.Sheets[1]; //Перезапустили таймер watch.Restart(); //Создаем двумерный массив типа string[,] и заполняем его string[,] data = new string[99, 99]; for (int row = 1; row < 100; row++) for (int col = 1; col < 100; col++) data[row-1,col-1]= "row:" + Convert.ToString(row) + ", col:" + Convert.ToString(col); //Определяем верхнюю левую ячейку для вставки нашего массива Excel.Range c1 = xlWorksheet.Cells[1, 1]; //Определяем нижнюю правую ячейку для вставки Excel.Range c2 = xlWorksheet.Cells[data.GetLength(0), data.GetLength(1)]; //Получаем размеры наешго массива //Создаем диапазон с верхней левой ячейки до нижней правой xlRange = xlWorksheet.get_Range(c1, c2); //Записываем в диапазон xlRange содержимое массива data xlRange.Value = data; watch.Stop(); Console.WriteLine("Потрачено времени {0}", watch.Elapsed); Console.ReadLine(); //СОхраняем файл Exel xlWorkbook.SaveAs("g:\\test.xlsx"); //Прибираемся GC.Collect(); GC.WaitForPendingFinalizers(); Marshal.ReleaseComObject(xlRange); Marshal.ReleaseComObject(xlWorksheet); xlWorkbook.Close(); Marshal.ReleaseComObject(xlWorkbook); xlApp.Quit(); Marshal.ReleaseComObject(xlApp); } } }
Результаты теста:
1. Простая вставка в каждую ячейку 99 строк, 99 столбцов — Потрачено времени 00:00:54.324226
2. Вставка массива 99 строк, 99 столбцов — Потрачено времени 00:00:00.0787437
Вполне ожидаемые результаты.
Но есть одно но, всё это достаточно быстро до того момента, пока не потребуется менять стили (шрифт, цвет шрифта, цвет фона и т.д.), тут уже тормозов не избежать. Пример из практики: выгрузка из 30К записей, вставка массивом по способу выше заняла несколько секунд, возникла необходимость стилизации выгружаемых данных, строки групп одним цветом, вложенные подстроки другим шрифтом, после решения в лоб, выгрузка длилась около 8 часов (там множество условий подсветки).
Естественно, что такой способ выгрузки уже не подходит. Лучшее решение для ускорения выгрузки это писать напрямую в экселевский файл. В моём случае я использовал библиотеку EPPlus. С тем же самым решением в лоб, выгрузка занимает 1 минуту