Реальное программирование: экспорт и импорт данных из/в Excel

Несмотря на такое большое информационное пространство как интернет, далеко не всегда удается найти нужную информацию по конкретной проблеме. С этим знаком практически каждый программист. В предлагаемой серии статей я решил поделиться своим собственным опытом по решению различных ситуаций, с которыми сталкивался в реале, а часть обсуждаемых вопросов поднимали мои знакомые или обращались читатели. Некоторые из освещаемых тем кому-то могут показаться простыми, также не исключен вариант, что есть и более оптимальные решения, но если кому-то представленная информация поможет, значит, серия сделана не зря. Все опробовано на практике.

В рамках этой серии я буду затрагивать в основном вопросы программирования на C#, PHP, JS (jQuery), AS, работы с БД MySQL и всевозможных сопутствующих технологий. В общем, веб и базы данных.


Экспорт данных в Excel

Довольно часто программистам ставят задания по написанию программ автоматического обновления баз данных с возможностями импорта/экспорта Excel-файлов. Нужно сказать, что несмотря на множество предлагаемых в интернете решений, подводных камней на этапе реализации именно импорта/экспорта можно встретить довольно много. Также стоит отметить, что некоторые из вариантов хоть и дают ожидаемый результат, но имеют некоторые ограничения, например, по тем же версиям Microsoft Office и форматам (только xls и т.п.), а экспорт в Excel-файл при большом объеме данных может занять довольно продолжительное время. Например, та же многими любимая библиотека + подключаемый программный блок ExcelXMLWriter при создании xls-файла с большим объемом данных требует длительное время на произведение расчетов (десятки минут и более).

Я прошел довольно интересный путь с использованием различных реализаций импорта/экспорта в Excel и, в конце концов, остановился на наиболее приемлемом для меня варианте, а именно, сохранение результатов работы своих программ в текстовый формат TSV. Это специальный формат для хранения баз данных, который довольно часто используется в различного рода ПО, именно там я его и подсмотрел. В качестве символьного разделителя в TSV используется символ табуляции, записи в полях могут заключаться в двойные или одинарные кавычки (хотя это может и не использоваться), а одна строка текстового файла соответствует одной строке в таблице БД. А в целом, для реализации вы используете стандартный StreamWriter.

 

Вариант TSV открывается любой современной версией Microsoft Excel, автоматически преобразуется в структурированную таблицу, но и здесь есть некоторые тонкие нюансы, которые нужно устранить.

Если вы используете двойные либо одинарные кавычки для выделения записей в строке, то их (эти кавычки) лучше удалить внутри самих записей во избежание дальнейших проблем с чтением в Excel'е. Это целесообразнее сделать, используя класс StringBuilder и его метода Replace(). Замена символов с использованием StringBuilder производится быстрее, нежели просто через класс String, что становится ощутимо при обработке большого количества данных.

Также проблему могут вызывать записи, в которых есть разбиение по строкам или абзацам, поэтому нужно обработать и их.

Пример кода необходимых преобразований в записях (двойные кавычки заменяются на одинарные, переход на новую строку - на HTML-тег <br/>, два пробела - на один, символ табуляции - на четыре HTML-символа пробела):

static string ubratKav(string p)
{
 StringBuilder b = new StringBuilder(p);
 b.Replace("\"", "\'");
 b.Replace(Environment.NewLine, "<br/>");
 b.Replace("\n", "<br/>");
 b.Replace(" ", " ");
 b.Replace("\t", "    ");
 return b.ToString();
}

Использование TSV выгодно еще и тем, что вы можете использовать данный формат и в обход Excel, например, написав собственный небольшой модуль импорта/экспорта, но не Excel-файлов, а вашего формата - обыкновенного текстового TSV из которого построчно извлекаются данные и затем парсятся.

Excel автоматически распознает TSV-формат


Импорт данных из Excel

Что же касается импорта данных из xls либо xlsx файлов, то наиболее часто встречаемый "подводный камень" - неправильная обработка данных при чтении. Да, это есть и встречается довольно часто. Например, артикулы товаров могут иметь как буквенную, так и цифровую маркировку. И если вы будете использовать стандартную библиотеку, такую как, например, Microsoft.Jet.OLEDB4.0, то она будет читать в колонке либо только буквенные, либо только числовые артикулы, это можно обнаружить при загрузке Excel-файла в DataGridView - вместо части данных пустые поля.

Как отличный вариант, решающий данную проблему, можно рассматривать замену "читающей" библиотеки на Microsoft.ACE.OLEDB 12.0. Ее можно найти в рамках системного драйвера для Office 2007 - AccessDatabaseEngine (скачивается здесь). Устанавливается в папку, где у вас находится Microsoft Office, а к C#-проекту его нужно подключить в References, взяв dll-ку из этого же каталога.

Затем все стандартно (в данном случае вы выбираете файл через OpenFileDialog):

const string CONNECTION_STRING =
 @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source = {0};
 Extended Properties=Excel 8.0;";

private const string QUERY_EXCEL = "SELECT * FROM[Лист1$]";

string connection_String =
 string.Format(CONNECTION_STRING, openFileDialog1.FileName);

OleDbDataAdapter adapter =
 new OleDbDataAdapter(QUERY_EXCEL, connection_String);

DataTable dataTable = new DataTable();

adapter.Fill(dataTable);

dataGridView.DataSource = dataTable;

Кристофер,
christopher@tut.by, itcs.3dn.ru

Версия для печатиВерсия для печати

Рубрики: 

  • 1
  • 2
  • 3
  • 4
  • 5
Всего голосов: 0
Заметили ошибку? Выделите ее мышкой и нажмите Ctrl+Enter!

Читайте также

 

Комментарии

Аватар пользователя mike

Когда-то была в бумажных "Вестях" статья "Суперфункции". Т.к. на Делфи я не пишу, предпочитаю C++, то где-то примерно в то же время написал свою библиотеку функций, которая делает с любым Экселом ВСЁ -- читает/вставляет/считает/рисует/ищет/размечает и т.д. Не поверите -- до сих пор пользуюсь. :)

Аватар пользователя batt

поищем...