クラス CPfOOCalc

CPfOOCalc.cppは次のとおりです。

//
// PfOOCalc.cpp
//
#include <vcl.h>
#pragma hdrstop

#include "PfOOCalc.h"

//---------------------------------------------------------------------------
// class CPfOOCalc
//---------------------------------------------------------------------------
CPfOOCalc::CPfOOCalc() {
Opened = false;
ColCount = RowCount = -1;
OpenOffice = Unassigned;
Desktop = Unassigned;
Document = Unassigned;
Sheet = Unassigned;
}
//---------------------------------------------------------------------------
CPfOOCalc::~CPfOOCalc() {
Close();
}
//---------------------------------------------------------------------------
bool CPfOOCalc::IsInstalled() {
bool rtn = false;
Variant obj;
try {
obj = Variant::CreateObject("com.sun.star.ServiceManager");
}
catch (Exception &e) {
;//ErrMsg = e.Message;
}
if (obj.Type() == varDispatch)
rtn = true;
obj = Unassigned;
return rtn;
}
//---------------------------------------------------------------------------
bool CPfOOCalc::Open(const String &fname) {
Opened = false;
ColCount = RowCount = -1;
FileName = fname;
if (FileName.IsEmpty())
return false;
try {
//サービスマネージャ生成
OpenOffice = Variant::CreateObject("com.sun.star.ServiceManager");
if (OpenOffice.Type() != varDispatch)
throw Exception("Unknown");
//サービス生成
Desktop = OpenOffice.OleFunction("createInstance", "com.sun.star.frame.Desktop");
if (Desktop.Type() != varDispatch)
throw Exception("Unknown");
// ファイルを読む
Variant props, prop;
props = VarArrayCreate(OPENARRAY(int, (0, 1)), varVariant);
prop = OpenOffice.OleFunction("Bridge_GetStruct",
(OleVariant)"com.sun.star.beans.PropertyValue");
// 非表示
prop.OlePropertySet("Name", (OleVariant)"Hidden");
prop.OlePropertySet("Value", true);
props.PutElement(prop, 0);
prop = OpenOffice.OleFunction("Bridge_GetStruct",
(OleVariant)"com.sun.star.beans.PropertyValue");
// ReadOnly
prop.OlePropertySet("Name", (OleVariant)"ReadOnly");
prop.OlePropertySet("Value", true);
props.PutElement(prop, 1);
Document = Desktop.OleFunction("loadComponentFromURL",
(OleVariant)ConvertToURL(fname),
(OleVariant)"_blank", (OleVariant)0, props);
if (Document.Type() != varDispatch)
throw Exception("Unknown");

// シート
Sheet = Document.OleFunction("getSheets").OleFunction("getByIndex", 0);
if (Sheet.Type() != varDispatch)
throw Exception("Unknown");
// 使用している範囲
Variant cursor, addr;
cursor = Sheet.OleFunction("createCursor");
cursor.OleProcedure("gotoStartOfUsedArea", false);
addr = cursor.OleFunction("getCellByPosition", 0, 0)
.OlePropertyGet("CellAddress");
Col0 = addr.OlePropertyGet("Column");
Row0 = addr.OlePropertyGet("Row");

cursor.OleProcedure("gotoEndOfUsedArea", false);
addr = cursor.OleFunction("getCellByPosition", 0, 0)
.OlePropertyGet("CellAddress");
Col1 = addr.OlePropertyGet("Column");
Row1 = addr.OlePropertyGet("Row");

ColCount = Col1 - Col0 + 1;
RowCount = Row1 - Row0 + 1;

Opened = true;
}
catch (Exception &e) {
ErrMsg = e.Message;
}
return Opened;
}
//---------------------------------------------------------------------------
int CPfOOCalc::GetColCount() {
return ColCount;
}
//---------------------------------------------------------------------------
int CPfOOCalc::GetRowCount() {
return RowCount;
}
//---------------------------------------------------------------------------
bool CPfOOCalc::GetRow(int irow, TStringList *list) {
// irow は 0 から
int rtn = false;
if (!Opened)
return rtn;
if (irow >= RowCount)
return rtn;
try {
Variant range, varray;
int idx0, idx1;
irow += Row0;
range = Sheet.OleFunction("getCellRangeByPosition", Col0, irow, Col1, irow);
varray = range.OleFunction("getDataArray");
if (varray.ArrayDimCount() != 1)
throw Exception("Invalid array");
idx0 = varray.ArrayLowBound(1);
varray = varray.GetElement(idx0);
if (varray.ArrayDimCount() != 1)
throw Exception("Invalid array");
idx0 = varray.ArrayLowBound(1);
idx1 = varray.ArrayHighBound(1);
for (int ii = idx0; ii <= idx1; ii++) {
list->Add(varray.GetElement(ii));
}
rtn = true;
}
catch (Exception &e) {
ErrMsg = e.Message;
}
return rtn;
}
//---------------------------------------------------------------------------
void CPfOOCalc::Close() {
if (Opened) {
try {
if (Document.Type() == varDispatch)
Document.OleProcedure("dispose");
Variant venum = Desktop.OleFunction("getComponents")
.OleFunction("createEnumeration");
// 他にコンポーネントが無ければterminate
if (!(bool)venum.OleFunction("hasMoreElements")) {
Desktop.OleProcedure("terminate");
}
}
catch (Exception &e) {
ErrMsg = e.Message;
}
Opened = false;
}
Sheet = Unassigned;
Document = Unassigned;
Desktop = Unassigned;
OpenOffice = Unassigned;
}
//---------------------------------------------------------------------------
OleVariant CPfOOCalc::DummyArray()
{
return VarArrayCreate(OPENARRAY(int, (0, -1)), varVariant);
}
//---------------------------------------------------------------------------
String CPfOOCalc::ConvertToURL(const String &path)
{
String rtn = "file:";
String svv = ExpandUNCFileName(path);
if (svv.Length() > 0 && svv[1] != '\\')
rtn += String("///");
for (int i = 1; i <= svv.Length(); i++) {
#if __BORLANDC__ < 0x600
if (svv.IsLeadByte(i)) {
rtn += svv.SubString(i, 2);
i++;
continue;
}
#endif
switch (svv[i]) {
case '\\': rtn += String('/'); break;
case '%': rtn += String("%25"); break;
case ' ': rtn += String("%20"); break;
default: rtn += String(svv[i]);
}
}
return rtn;
}
//---------------------------------------------------------------------------

CPfOOCalc.hは次のとおりです。

//---------------------------------------------------------------------------
// PfOOCalc.h
#ifndef PfOOCalcH
#define PfOOCalcH
//---------------------------------------------------------------------------
class CPfOOCalc
{
protected:
Variant OpenOffice, Desktop, Document, Sheet;
String FileName;
String ErrMsg;
bool Opened;
int ColCount, RowCount;
int Col0, Row0;
int Col1, Row1;
public:
CPfOOCalc();
~CPfOOCalc();
bool Open(const String &fname);
int GetColCount();
int GetRowCount();
bool GetRow(int irow, TStringList *list);
// irow は 0 から
void Close();

static bool IsInstalled();
static OleVariant DummyArray();
static String ConvertToURL(const String &path);
};
//---------------------------------------------------------------------------
#endif