Перейти до основного вмісту

Qt + Microsoft Excel 2003 XML

Останнім часом все більше часу приділяю розробці програм для машинної обробки прайс-листів. Прайси приходять в різних форматах xml, xls, txt, csv. І найчастіше результат готую в csv для завантаження його в інтернет магазин. Але не так давно з'явився клієнт, який побажав результат в xslx. У нього самопісний сайт і він хотів би деяке візуальне оформлення, наприклад, підсвітити кольором певні або проблемні позиції, в заданій умові.

Але я працюю з Ubuntu і скажемо так, xlsx - тут не зовсім зручний формат. Честно зізнаюся, я зневірився адже засобами CSV такого не реалізувати. Фактично я вирішив перемогти цю проблему найпростішим шляхом і вже почав готувати "запасний" Windows, щоб там налагодити тандем Qt + Excel. І в цьому процесі я натрапив на формат Microsoft Excel 2003 XML. Пошук в Google дав небагато інформації, частково навіть не помилкової, але всеж таки перспективною.

Перше, що я зробив - це створив файл в Calc. Невеличку таблицю 4х3, виділив деякі клітини кольором, десь поставив жирний шрифт. Зберіг файл у форматі Microsoft XML 2003 XML. На виході виявився звичайний XML файл.

Відкрив я його в Sublime Text - ну, що звичайний xml. Нічого цікавого, структура логічна і абсолютно зрозуміла. Я вирішив, що таким чином цілком зможу передати потрібну інформацію після обрабки прайс-листа. Потім відкрию його в Calc, перевірю правильність підсвічування, перезберегу в xlsx і обойдустя без Windows. Так я і зробив. Один в один передав структуру, як в збереженому прикладі, вивантажив для проби 10 рядків.

Цікаво, що файл в цей формат зберігається швидше, незважаючи на те, що даних в кілька разів більше.

В результаті Calc не відкрив мій файл. Фактично він навіть не говорить, де у мене помилка.

Пересів за Windows. Excel 2007 його теж не відкрив, але в процесі відкриття лаявся досить конкретно. Після 10-12 спроб і наступних виправлень я здався. Незважаючи на першу поразку, я все-таки вирішив спробувати зайти з іншого боку. Тестовий файл я зберіг тепер в Excel, все-таки це його рідний формат, а не Calc. Відкривши його в Notepad++ знайшлося досить багато відмінностей, імовірно через які мій файл і не відкривався. Після коригування коді програми відповідно до другого тестового файлу прийшов успіх. Все відкривалося і в Calc, і Excel, з потрібною передачею стилів і підсвічуванням необхідних даних.

Але не обійшлося без нюансів. Я потім збирав і довші файли (>70000 рядків), так ось їх Calc не відчиняє. Довго міркує, явно страждає при цьому і не відкриває. Excel 2007 все відкриває швидко і без проблем, так що зовсім без Windows не вдалося.

В деталях, як і що я робив, а краще як потрібно робити щоб вийшло з першого разу розповім і картинки покажу в наступних постах.

Коментарі

Популярні дописи з цього блогу

QString в HEX и обратно

Спочатку з QString робимо QByteArray. Зауважимо, якщо у вас по тексту тільки латинські букви цілком підійде варіант з .toUtf8(). Якщо ж присутня і кирилиця - обов'язково використовуємо .toLocal8Bit(). QString strA = "Some text"; QByteArray bA = strA.toLocal8Bit().toHex(); Перетворення QByteArray в початковий текст має такий вигляд: QString strB = QString::fromLocal8Bit(QByteArray::fromHex(bA))); Цікаво, що якщо ми для зберігання записали отриманий Нех куди-небудь, наприклад, в файл або базу даних у вигляді текстового рядка, то для зворотного перетворення цей рядок потрібно додатково перетворити в QByteArray. QString strA2 = QString::fromUtf8(bA); QByteArray bB = strA2.toUtf8(); QString strB = QString::fromLocal8Bit(QByteArray::fromHex(bB)));

Qt та Excel. QTableWidget туди і назад.

У цій статті мова піде про те, як прийняти дані з Excel в QTableWidget і відправити назад в Excel. Візьмемо книгу Excel у якої є 2 листа, на першому розташована невелика таблиця (її ми і буде читати в QTableWidget), а в другій лист порожній, сюди ми віддамо таблицю з QTableWidget.   Ось так, як на малюнку праворуч, виглядає цільова таблиця. На формі розташуємо QTableWidget. Заздалегідь знаючи, якого розміру таблиця, можна відразу виставити кількість стовпців, рядків, прописати назви стовпців, але ми не будемо цього робити. Почнемо з читання таблиці. QAxObject * list;      list = sheets-> querySubObject ("Item (int)", 1); / / оголошуємо лист, на якому таблиця      int colEx = 6; / / оголошуємо кількість стовпців      QStringList headers; / / сюди запишемо заголовки стовпців      for (int a = 1; a <= colEx; a + +) {/ / вичитуємо заголовки        ...

Qt Округлення до певного розряду

Округлення - тривіальна задача в математиці, але в Qt немає функції округлення до певного розряду. Проте в QtMath є такі функції як qFloor (qreal) і QCeil (qreal), в результаті яких int. А також можна використовуючи round (double), отримати double. Дуже швидко я знайшов ось цей ресурс звідки взяв вихідну формулу. Вона без сумніву працює, але дає результати, які не відповідаю моїм очікуванням: toRound(187.156, 2); //187.15 toRound(187.156, 1); //187.1 toRound(187.156, 0); //187 toRound(187.156, -1); //180 toRound(187.156, -2); //100 Після невеликої корекції самої функції, її підсумковий варіант виглядає так: double wcsv::toRound(double val, int r) {   double outpValue;   double tempVal;   tempVal=val*pow(10,r);   if (double(int(tempVal))+0.5==tempVal){     int(tempVal)%2 == 0       ? outpValue=double(qFloor(tempVal))/pow(10,r)       :outpValue=d...