Как просто работать с / открыть / изменить / сохранить Excel - xlsx / CSV файлы

195
20 августа 2019, 21:40

Сколько я ни искал, всё как-то уж больно сложно и избыточно функционально...

А я хотел максимальной простоты — работать с таблицей как с двумерным массивом строк.

Ответ к которому я пришел - внизу :)

Полная поддержка CSV должна в себя включать:

  1. возможность изменять делимитер
  2. считывание ячеек между делимитерами
  3. считывание строк
  4. если знак делимитера есть в ячейке, ячейка должна братся в кавычки и нормально обрабатыватся самым ридером
  5. если знак перехода на следующую строку есть в ячейке, ячейка должна братся в кавычки и нормально обрабатыватся самим ридером.
  6. если ячейка выделена кавычками, а внутри есть кавычки, то они так же должны обрабатыватся без ошибок.
Answer 1
EXCEL:

Здесь я написал очень простую библиотеку на основе ClosedXML для того, чтобы не задумываясь иметь возможность работать с таблицами MS Excel как с двумерным массивом: что может быть легче в использовании?

Пример конечного кода для работы с моим классом:

Excel xl = new Excel(); //создаем инстанс
xl.FileOpen("c:\\file1.xlsx"); //открываем файл
var row1Cell6Value = xl.Rows[0][5]; //вытягиваем значение из 1 строки 6й ячейки
xl.AddRow("asdf","asdffffff","5"); //добавляем еще одну строку с 3мя ячейками
xl.FileSave("c:\\file2.xlsx"); //сохраняем файл

Фактически, это и есть все методы — аскетский минимализм :)

Если нужно написать формулу, можно использовать следующий код:

var widthAdress = Excel.GetExcelPos(0, 1);
var heightAdress = Excel.GetExcelPos(0, 2);
xl.Rows[0][0] = String.Format("={0}*{1}", widthAdress , heightAdress);
CSV:

И абсолютно с тем же подходом аскетизма есть не менее простая либа для работы с CSV файлами как с двумерным массивом данных.

Csv csv = new Csv(); //создаем инстанс читалки
csv.FileOpen("c:\\file1.csv"); //открываем файл
var row1Cell6Value = csv.Rows[0][5]; //читаем 6ю ячейку 1й строки
csv.AddRow("asdf","asdffffff","5"); // добавляем строку из 3х ячеек
csv.FileSave("c:\\file2.csv"); // сохраняем файл

Актуальный код обоих классов вы найдете здесь: https://github.com/ukushu/DataExporter

Теперь немного отступим что бы рассказать почему мой код написан именно так, а не иначе

Этот блок будет полезен тем, кому будет мало моей либы, и кто хочет больше возможностей в работе с Microsoft Excel.

Сначала я пытался работать с Excel-файлами при помощи Microsoft.Office.Interop.Excel, который по факту:

  • Медленный (я сейвил таблицу всего лишь в 11 250 ячеек на протяжении 22 секунд!!!).
  • У него много утечек памяти (ни в коем случае не используйте эту библиотеку для веб-сайтов или приложений, где на сервере генерируются файлы Office-форматов: у вас кончится оперативная память довольно быстро и сайт или приложение упадёт).
  • Требует наличия MS Office определённой версии. На каждую машину, где будет работать ваше приложение.
  • Неудобный в использовании.
  • Имеет множество подводных камней из-за которых лишние Excel'евские сервисы будут оставаться запущенными...

Считаю очень неудачным решением через него взаимодействовать.

Потом я пытался работать через OleDB. Этот путь привел меня в никуда просто по той причине, что там невозможно работать с формулами. Считать формулу ты не можешь — только записать. В целом этот путь явно лучше, быстрее и приятнее, но отсутствие возможности править формулы меня очень огорчало.

И так я пришел к OpenXML. Как следствие — тоже относительно печальный опыт. Работать с ним просто-напросто неудобно. Не знаю, чем авторы думали.

И я пришел к конечному решению — обертки вокруг OpenXML - ClosedXML. Это решение уже позволило написать:

  • Удобный и легко читаемый код либы.
  • При этом достаточно быстрый код. (сейв файла на 20 000 ячеек обходится в 00:00:00.6787608, что быстрее более чем в 57 раз чем путь Interop).
  • А также не требует установленного MS Excel. :)

Важные минуса:

  • нужно уточнить что работает только с ".xlsx" файлами! Но не с ".xls"!
  • Решение для работы с Excel требует подтягивание целых 2х библиотек (OpenXML, ClosedXML)
  • решение для работы с CSV не будет работать, например, на Unity. Это из-за того, что пришось использовать библиотеку с VB.
READ ALSO
Проблема подключения Sql Server к Visual Studio

Проблема подключения Sql Server к Visual Studio

Проблема вот в чемЕсть MS sql server Manager studio и MS sql server 2012

169
Выбор конкретного сообщения из очереди rabbitmq

Выбор конкретного сообщения из очереди rabbitmq

Имеем: 2 очереди - messages и error_messages, при ошибке сообщение падает в error_message, у каждого сообщения есть уникальный ID

158
C# UWP и веб-сервис

C# UWP и веб-сервис

Есть просто приложение на C# UWP, в котором по нажатию на кнопку происходит определенное событие (включается реле на плате)Подскажите, можно...

164
Как сделать sluggable в asp .net core

Как сделать sluggable в asp .net core

Подскажите как в asp net core сделать sluggableК примеру ввожу я в статье в поле title "лорем айпсам долорем сит", и в поле url генерировалось "lorem-ipsum-dolorom-sit"...

138