OpenXML — редактирование большого файла Excel без утечки памяти ⇐ Excel
OpenXML — редактирование большого файла Excel без утечки памяти
Я использую подход SAX для записи файлов .xlsx непосредственно с помощью DataReader (без использования памяти), и это отлично работает. Но я хочу, чтобы столбцы в файле Excel также подбирались автоматически.
Использование подхода SAX означает запись файлов .xlsx непосредственно с помощью OpenXmlWriter, к сожалению, только в одном направлении (вниз по дереву xml). Столбцы - из-за порядка XML - должны быть записаны до фактических данных, то есть я не могу вычислить их ширину, поскольку DataReader еще не открыт.
Раньше я уже реализовал автоподбор, выполнив DataReader дважды — сначала для поиска самых длинных строк для расчета ширины столбцов, а затем для записи фактических данных в файл .xlsx. При написании больших файлов это отнимает много времени, поэтому меня это не устраивает.
Единственный вариант, который я вижу, — это отредактировать файл .xlsx, но я не могу найти подход к SAX.
Мне удалось выполнить автоподбор, используя метод, описанный ниже, но это требует огромного потребления памяти (2 ГБ памяти для файла размером 300 МБ, около 1 миллиона строк), когда в дело вмешивается Linq:
private void Autofit(string _filename) { используя (SpreadsheetDocument Excel = SpreadsheetDocument.Open(_filename, true)) { foreach (var wp в Excel.WorkbookPart.WorksheetParts) { //Эта строка потребляет 2 ГБ памяти, проверено на 1 млн строк для файла .xlsx var sd = wp.Worksheet.Descendants().First(); вар cs = новые столбцы (); uint Col_index = 1; //MaxText — это List, содержащий самые длинные строки каждого столбца foreach (var longest_string в MaxText) { //CalculateWidth — метод расчета ширины столбца double cell_width = CalculateWidth(new System.Drawing.Font("Arial", 10), самая длинная_строка) + 1,5; Столбец c = новый столбец {Мин = Col_index, Макс = Col_index, Ширина = cell_width, CustomWidth = true }; cs.Append(с); столбец_индекс++; } wp.Worksheet.InsertAfter(cs, SD); } } } Можно ли еще что-нибудь попробовать с OpenXml? Или, может быть, преобразование xlst, XStreamingElement? Или я могу исправить верхний метод Linq, чтобы он не потреблял такую память? Будем очень признательны за любые примеры или ссылки.
Я использую подход SAX для записи файлов .xlsx непосредственно с помощью DataReader (без использования памяти), и это отлично работает. Но я хочу, чтобы столбцы в файле Excel также подбирались автоматически.
Использование подхода SAX означает запись файлов .xlsx непосредственно с помощью OpenXmlWriter, к сожалению, только в одном направлении (вниз по дереву xml). Столбцы - из-за порядка XML - должны быть записаны до фактических данных, то есть я не могу вычислить их ширину, поскольку DataReader еще не открыт.
Раньше я уже реализовал автоподбор, выполнив DataReader дважды — сначала для поиска самых длинных строк для расчета ширины столбцов, а затем для записи фактических данных в файл .xlsx. При написании больших файлов это отнимает много времени, поэтому меня это не устраивает.
Единственный вариант, который я вижу, — это отредактировать файл .xlsx, но я не могу найти подход к SAX.
Мне удалось выполнить автоподбор, используя метод, описанный ниже, но это требует огромного потребления памяти (2 ГБ памяти для файла размером 300 МБ, около 1 миллиона строк), когда в дело вмешивается Linq:
private void Autofit(string _filename) { используя (SpreadsheetDocument Excel = SpreadsheetDocument.Open(_filename, true)) { foreach (var wp в Excel.WorkbookPart.WorksheetParts) { //Эта строка потребляет 2 ГБ памяти, проверено на 1 млн строк для файла .xlsx var sd = wp.Worksheet.Descendants().First(); вар cs = новые столбцы (); uint Col_index = 1; //MaxText — это List, содержащий самые длинные строки каждого столбца foreach (var longest_string в MaxText) { //CalculateWidth — метод расчета ширины столбца double cell_width = CalculateWidth(new System.Drawing.Font("Arial", 10), самая длинная_строка) + 1,5; Столбец c = новый столбец {Мин = Col_index, Макс = Col_index, Ширина = cell_width, CustomWidth = true }; cs.Append(с); столбец_индекс++; } wp.Worksheet.InsertAfter(cs, SD); } } } Можно ли еще что-нибудь попробовать с OpenXml? Или, может быть, преобразование xlst, XStreamingElement? Или я могу исправить верхний метод Linq, чтобы он не потреблял такую память? Будем очень признательны за любые примеры или ссылки.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение