Продолжение первой части статьи.

Возможности:
На работе мы используем C++ Builder для написания внутренних программ, так что я делаю еще одну обертку над DLL для удобной работы с API.
Пример использования библиотеки. Результат картинкой представлен вначале статьи.
Скачать пример программы со всем необходимыми библиотеками.
В архиве лежат либы для запуска билдеровского exe их можно удалить (список либ в note.txt)
Более сложная выгрузка из реальной жизни:

На текущий момент остались проблемы:
— скрытие офиса в момент загрузки в него данных.
— генерация RDB файла под WINE (скорей всего неправильное преобразование в юникод в функции createProcess )

2. Повторное использование DLL в своей программе
Возможности:
- открытие XLS файла,
- открытие файлов OpenOffice
- возможность открытия в скрытом режиме
- чтение данных из электронной таблицы
- полный спектр манипуляции с данными: вставка текста, числа, форматирование, объединение ячеек, установка границ, установка ширина столбца
- выгрузка xls таблицы на диск
- возмоность работы под WINE, при условий установки OpenOffice под Wine
- использование формул
- генерация версионно зависимого RDB файла налету (при необходимости)
На работе мы используем C++ Builder для написания внутренних программ, так что я делаю еще одну обертку над DLL для удобной работы с API.
//ooapi3.h
#ifndef ooapi3H
#define ooapi3H
#include <windows.h>
#include <vcl.h>
#include "StrUtils.hpp"
class OOAPI3 {
private:
HANDLE hLib;
protected:
//указатели на функции
bool (*ooConect)(const char *, bool);
void (*ooDisconect)();
bool (*ooSelectSheet)(short);
void (*ooSetVal)(int, int, double);
void (*ooSetFormula)(int, int, const wchar_t *);
bool (*ooSetBold)(int, int);
bool (*ooSetFontColor)(int, int, int, int, int);
bool (*ooSetBgColor)(int, int, int, int, int);
bool (*ooSetFontSize)(int, int, short);
bool (*ooSetItalic)(int, int);
bool (*ooSetHoriz)(int, int, short);
bool (*ooSetBorders)(int, int, bool, bool, bool, bool, short, short, short);
bool (*ooSetColWidth)(int, long);
bool (*ooMergeRange)(const char *);
bool (*ooExportToUrl)(const wchar_t *);
double (*ooGetVal)(int, int);
wchar_t* (*ooGetText)(int, int);
bool (*ooIsInstall)();
bool (*ooIsWin)();
public:
__fastcall OOAPI3();
__fastcall ~OOAPI3();
bool __fastcall connect(const char* file, bool hidden = false);
bool __fastcall setSheet(short sheet);
void __fastcall setVal(int x, int y, double val);
void __fastcall setText(int x, int y, AnsiString val);
bool __fastcall setBold(int x, int y);
bool __fastcall setItalic(int x, int y);
bool __fastcall setFontColor(int x, int y, int r, int g, int b);
bool __fastcall setBgColor(int x, int y, int r, int g, int b);
bool __fastcall setFontSize(int x, int y, short size);
bool __fastcall setHoriz(int x, int y, short horiz);
bool __fastcall setBorders(int x, int y, bool l, bool t, bool r, bool d, short rd, short gr, short bl);
bool __fastcall setBorders(int x, int y, bool l, bool t, bool r, bool d);
bool __fastcall setBorders(int x, int y);
bool __fastcall setColWidth(int col, long mm);
bool __fastcall mergeRange(AnsiString from, AnsiString to);
bool __fastcall mergeRange(int x1, int y1, int x2, int y2);
bool __fastcall export2XLS(AnsiString to);
double __fastcall getVal(int x, int y);
AnsiString __fastcall getText(int x, int y);
bool __fastcall isWin();
bool __fastcall isInstall();
AnsiString __fastcall getColNameById(int id);
};
#endif
//ooapi3.cpp
#include "ooapi3.h"
__fastcall OOAPI3::OOAPI3() {
//подгружаем модуль
HMODULE hLib = LoadLibrary("ooapi3.dll");
if(hLib == NULL) {
throw;
}
//загрузим указатели на функции разом
(FARPROC &)ooConect = GetProcAddress(hLib, "connect");
(FARPROC &)ooDisconect = GetProcAddress(hLib, "disconnect");
(FARPROC &)ooSelectSheet = GetProcAddress(hLib, "selectSheet");
(FARPROC &)ooSetVal = GetProcAddress(hLib, "setVal");
(FARPROC &)ooSetFormula = GetProcAddress(hLib, "setText");
(FARPROC &)ooSetBold = GetProcAddress(hLib, "setBold");
(FARPROC &)ooSetFontColor = GetProcAddress(hLib, "setFontColor");
(FARPROC &)ooSetBgColor = GetProcAddress(hLib, "setBgColor");
(FARPROC &)ooSetFontSize = GetProcAddress(hLib, "setFontSize");
(FARPROC &)ooSetItalic = GetProcAddress(hLib, "setItalic");
(FARPROC &)ooSetHoriz = GetProcAddress(hLib, "setHoriz");
(FARPROC &)ooSetBorders = GetProcAddress(hLib, "setBorders");
(FARPROC &)ooSetColWidth = GetProcAddress(hLib, "setColWidth");
(FARPROC &)ooMergeRange = GetProcAddress(hLib, "mergeRange");
(FARPROC &)ooExportToUrl = GetProcAddress(hLib, "exportToUrl");
(FARPROC &)ooGetVal = GetProcAddress(hLib, "getVal");
(FARPROC &)ooGetText = GetProcAddress(hLib, "getText");
(FARPROC &)ooIsWin = GetProcAddress(hLib, "isWin");
(FARPROC &)ooIsInstall = GetProcAddress(hLib, "isInstall");
}
//создание нового или открытие существующего файла
//hidden - открыть(создать) файл скрытым
bool __fastcall OOAPI3::connect(const char* file, bool hidden) {
// private:factory/scalc - создает новый excel документ
//или
// file:///путь до файла
//hidden: скрыть офис можно при экспорте данных из файла
return ooConect(file, hidden);
}
//выбор листа книги
bool __fastcall OOAPI3::setSheet(short sheet) {
return ooSelectSheet(sheet);
}
//установка числового значения для ячейки
void __fastcall OOAPI3::setVal(int x, int y, double val) {
ooSetVal(x, y, val);
}
//установка текста или формулы для ячейки
void __fastcall OOAPI3::setText(int x, int y, AnsiString val) {
//конвертация в unicode
int iSize = val.WideCharBufSize();
wchar_t *uval = new wchar_t[iSize];
val.WideChar(uval, iSize);
ooSetFormula(x, y, uval);
delete[] uval;
}
//делает жирным текст в ячейке
bool __fastcall OOAPI3::setBold(int x, int y) {
return ooSetBold(x, y);
}
//курсив
bool __fastcall OOAPI3::setItalic(int x, int y) {
return ooSetItalic(x, y);
}
//установка цвета для шрифта
bool __fastcall OOAPI3::setFontColor(int x, int y, int r, int g, int b) {
//TODO: возможно нужны проверки на > 0, < 255
return ooSetFontColor(x, y, r, g, b);
}
//установка цвета фона
bool __fastcall OOAPI3::setBgColor(int x, int y, int r, int g, int b) {
return ooSetBgColor(x, y, r, g, b);
}
//установка размера шрифта
bool __fastcall OOAPI3::setFontSize(int x, int y, short size) {
return ooSetFontSize(x, y, size);
}
//горизонтальная ориентация текста
//1 - лево, 2 - центр, 3 - право
bool __fastcall OOAPI3::setHoriz(int x, int y, short horiz) {
//TODO: проверки-проверочки нужны
return ooSetHoriz(x, y, horiz);
}
//установка показа границ
//лево, верх, право, низ, r, g, b
bool __fastcall OOAPI3::setBorders(int x, int y, bool l, bool t, bool r, bool d, short rd, short gr, short bl) {
return ooSetBorders(x, y, l, t, r, d, rd, gr, bl);
}
//установка показа границ
//лево, верх, право, низ
bool __fastcall OOAPI3::setBorders(int x, int y, bool l, bool t, bool r, bool d) {
//черные границы
return ooSetBorders(x, y, l, t, r, d, 0, 0, 0);
}
//установка показа границ
//показать все границы
bool __fastcall OOAPI3::setBorders(int x, int y) {
return ooSetBorders(x, y, true, true, true, true, 0, 0, 0);
}
//установка ширины столбца в милиметрах
bool __fastcall OOAPI3::setColWidth(int col, long mm) {
return ooSetColWidth(col, mm);
}
//объединить диапозон ячеек
//к примеру A1:C7
bool __fastcall OOAPI3::mergeRange(AnsiString from, AnsiString to) {
return ooMergeRange(AnsiString(from+":"+to).c_str());
}
//наименование столбца, по его номеру
AnsiString __fastcall OOAPI3::getColNameById(int id) {
id++;
AnsiString abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//26
AnsiString ret;
int x;
if(id > 26) {
x = (int)id/26;
ret = abc.SubString(x, 1);
id = id - x*26;
}
ret += abc.SubString(id, 1);
return ret;
}
//объединить диапозон ячеек
//вариант с цифрами
bool __fastcall OOAPI3::mergeRange(int x1, int y1, int x2, int y2) {
y1++; y2++;
AnsiString from = OOAPI3::getColNameById(x1) + AnsiString(y1);
AnsiString to = OOAPI3::getColNameById(x2) + AnsiString(y2);
return OOAPI3::mergeRange(from, to);
}
//экспорт документа в excel на диск
//пример: file:///C:/тест.xls
bool __fastcall OOAPI3::export2XLS(AnsiString to) {
to = ReplaceStr(to, "\\", "/");
to = "file:///"+to;
//конвертация в unicode
int iSize = to.WideCharBufSize();
wchar_t *uval = new wchar_t[iSize];
to.WideChar(uval, iSize);
bool r = ooExportToUrl(uval);
delete[] uval;
return r;
}
//получить числовое значение ячейки
double __fastcall OOAPI3::getVal(int x, int y) {
return ooGetVal(x, y);
}
//получить текст ячейки
AnsiString __fastcall OOAPI3::getText(int x, int y) {
return AnsiString(ooGetText(x, y));
}
//определяет где запущено приложение:windows/wine
bool __fastcall OOAPI3::isWin() {
return ooIsWin();
}
//установлен ли опен офис?
bool __fastcall OOAPI3::isInstall() {
return ooIsInstall();
}
//отключаемся от сервера, освобождаем библиотеку
__fastcall OOAPI3::~OOAPI3() {
ooDisconect();
FreeLibrary(hLib);
}
2.1. Пример небольшой программы по выгрузке данных
Пример использования библиотеки. Результат картинкой представлен вначале статьи.
OOAPI3 *t = new OOAPI3();
if(!t->isInstall()) return;
t->connect("private:factory/scalc");
t->setSheet(0);
t->mergeRange(26,1,29,2);
t->setVal(1,1, -178.576);
t->setText(0, 2, "Тест1");
t->setVal(1,1, 5);
t->setVal(0,0, 3.14);
t->setBorders(0,0);
t->setText(0, 2, "Тест1");
t->setBold(0, 2);
t->setFontColor(0, 2, 0, 0, 255);
t->setBgColor(0,2,255,255,0);
t->setFontSize(0,2,20);
t->setItalic(0,2);
t->setHoriz(0,2,3);//1-л, 2-центр, 3-п
t->setColWidth(0, 100);
t->setBorders(1,1);
t->mergeRange("A1", "C2");
t->export2XLS("C:/export123.xls");
delete t;
Скачать пример программы со всем необходимыми библиотеками.
В архиве лежат либы для запуска билдеровского exe их можно удалить (список либ в note.txt)
Более сложная выгрузка из реальной жизни:

На текущий момент остались проблемы:
— скрытие офиса в момент загрузки в него данных.
— генерация RDB файла под WINE (скорей всего неправильное преобразование в юникод в функции createProcess )