Несмотря на такое большое информационное пространство как интернет, далеко не всегда удается найти нужную информацию по конкретной проблеме. С этим знаком практически каждый программист. В предлагаемой серии статей я решил поделиться своим собственным опытом по решению различных ситуаций, с которыми сталкивался в реале, а часть обсуждаемых вопросов поднимали мои знакомые или обращались читатели. Некоторые из освещаемых тем кому-то могут показаться простыми, также не исключен вариант, что есть и более оптимальные решения, но если кому-то представленная информация поможет, значит, серия сделана не зря. Все опробовано на практике.
В рамках этой серии я буду затрагивать в основном вопросы программирования на 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;
Кристофер,
[email protected], itcs.3dn.ru
Комментарии
Когда-то была в бумажных "Вестях" статья "Суперфункции". Т.к. на Делфи я не пишу, предпочитаю C++, то где-то примерно в то же время написал свою библиотеку функций, которая делает с любым Экселом ВСЁ -- читает/вставляет/считает/рисует/ищет/размечает и т.д. Не поверите -- до сих пор пользуюсь. :)
поищем...