Работа с OpenOffice Calc из Lazarus

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Работа с OpenOffice Calc из Lazarus

Сообщение bestonix » 12.04.2011 15:17:46

Доброго здоровья уважаемые коллеги.

Вдохновленный топиком - http://www.sql.ru/forum/actualthread.as ... n%20object
стал разбираться с OpenOffice Calc. Вроде бы понял смысл "общения" с Calc'ом, но встали две проблемы, которые никак не могу решить.
Пожалуйста прошу помочь разобраться в чем я не прав. Написал вот такой код
Код: Выделить всё
  StarOffice := CreateOleObject('com.sun.star.ServiceManager');

  StarDesktop := StarOffice.createInstance('com.sun.star.frame.Desktop');
  Document := StarDesktop.LoadComponentFromURL(
                  'private:factory/scalc', '_blank', 0,
                  VarArrayCreate([0, -1], varVariant));
  MyStruct := StarOffice.Bridge_GetStruct('com.sun.star.table.BorderLine');

  try

    Sheets := Document.getSheets;
    //Sheet := Sheets.getByName('Лист1');
    Sheet := Sheets.getByIndex(0);
    Cell := Sheet.getCellRangeByName('C10:C13');
    Cell.setPropertyValue('CellBackColor', 255);
    Cell.Merge(true);
    Cell := Sheet.getCellByPosition(2, 9);
    Cell.setString('Пробная строка');
  finally
    StarOffice := Unassigned;
  end;


В результате в кальке русские буквы прописываются китайскими иероглифами. Ни одна из функций преобразования (UTF8ToSys, UTF8ToCP1251) не приводит к желаемому результату.

Вторая проблема, не могу открыть уже существующий файл. Код на открытие файла
Код: Выделить всё
 
function ConvertToURL(FileName: string): string;
var
  URL:string;
  i:integer;
  ch:char;
begin
  URL:='';
  for i:=1 to Length(FileName) do
    begin
      ch:=FileName[i];
      case ch of
        ' ':URL:=URL+'%20';
        '\':URL:=URL+'/';
      else
        URL:=URL+ch;
      end;
    end;
  Result:='file://localhost/'+URL;
end;   

   FileName    := ConvertToURL(ExtractFilePath(Application.ExeName)+'OOclient.ods');

  if FileExists(ExtractFilePath(Application.ExeName)+'OOclient.ods') then begin
    ShowMessage(FileName);
  StarOffice  := CreateOleObject('com.sun.star.ServiceManager');
  StarDesktop := StarOffice.createInstance('com.sun.star.frame.Desktop');
  Document := StarDesktop.LoadComponentFromURL(
                  FileName, '_blank', 0,
                  VarArrayCreate([0, -1], varVariant));

  end else
  ShowMessage('File not found'); 

Сообщение звучит так: com.sun.star.lang.IllegalArgumentException: URL seems to be an unsupported one
bestonix
новенький
 
Сообщения: 66
Зарегистрирован: 15.04.2010 08:26:00
Откуда: Жигулёвск

Re: Работа с OpenOffice Calc из Lazarus

Сообщение Sergei I. Gorelkin » 12.04.2011 15:36:46

bestonix писал(а):В результате в кальке русские буквы прописываются китайскими иероглифами. Ни одна из функций преобразования (UTF8ToSys, UTF8ToCP1251) не приводит к желаемому результату.


Сам исходник в utf-8? В начале есть {$codepage utf8} ?
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1407
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Работа с OpenOffice Calc из Lazarus

Сообщение bestonix » 12.04.2011 16:19:46

Sergei I. Gorelkin писал(а):
bestonix писал(а):В результате в кальке русские буквы прописываются китайскими иероглифами. Ни одна из функций преобразования (UTF8ToSys, UTF8ToCP1251) не приводит к желаемому результату.


Сам исходник в utf-8? В начале есть {$codepage utf8} ?


Судя по всему кодировка UTF8. В NotePad++ с кодировкой Ansi русские буквы вовсе не русские.
Хотя строки {$codepage utf8} в начале модуля нет. Если ее все же прописать, то программа отказывается компилится без объяснения причин.
Просто пишет Fatal: Compilation aborted

Добавлено спустя 1 минуту 21 секунду:
Да забыл написать.
Lazarus 0.9.31 FPC: 2.4.3
bestonix
новенький
 
Сообщения: 66
Зарегистрирован: 15.04.2010 08:26:00
Откуда: Жигулёвск

Re: Работа с OpenOffice Calc из Lazarus

Сообщение Sergei I. Gorelkin » 12.04.2011 17:01:12

Перед "Fatal: Compilation aborted" обычно бывает что-то еще. Возможно, оно скрывается в окне сообщений lazarus. Попробуй либо команду "копировать все включая скрытые" из контекстного меню окна сообщений (потом вставить в какой-нибудь блокнот), либо компилировать из командной строки.

По поводу второго пункта, попробуй сначала просто имя файла вместо url. Если файл лежит в каталоге с программой, должен открыться.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1407
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: Работа с OpenOffice Calc из Lazarus

Сообщение Ism » 12.04.2011 17:49:13

Код: Выделить всё
file://localhost/'+URL


Вообщето должно быть так

Код: Выделить всё
file://c:/mydir/myfile.xls


Кроме того у офиса есть своя функция для конвертации (пример из скрипта OpenOffice, но то же самое должно быть в объекте ole, через который вы работаете)
Код: Выделить всё
Dim oFile as String
oFile = "C:\mydir\Trost_meteor.xlsx"
args1(0).Value = convertToUrl ("C:\AutoBase\Autobase Access\Ishodnaya_Basa\www.meteor.com.ua\Trost_meteor.txt")
Ism
энтузиаст
 
Сообщения: 908
Зарегистрирован: 06.04.2007 17:36:08

Re: Работа с OpenOffice Calc из Lazarus

Сообщение bestonix » 13.04.2011 16:10:33

Sergei I. Gorelkin писал(а):Перед "Fatal: Compilation aborted" обычно бывает что-то еще. Возможно, оно скрывается в окне сообщений lazarus. Попробуй либо команду "копировать все включая скрытые" из контекстного меню окна сообщений (потом вставить в какой-нибудь блокнот), либо компилировать из командной строки.

По поводу второго пункта, попробуй сначала просто имя файла вместо url. Если файл лежит в каталоге с программой, должен открыться.


То что скрыто:
Hint: Start of reading config file C:\lazarus\fpc\2.4.3\bin\i386-win32\fpc.cfg
Hint: End of reading config file C:\lazarus\fpc\2.4.3\bin\i386-win32\fpc.cfg
Free Pascal Compiler version 2.4.3 [2011/03/23] for i386
Copyright (c) 1993-2010 by Florian Klaempfl
Target OS: Win32 for i386
Compiling RepExecuter.lpr
Compiling UMain.pas
UMain.pas(89,35) Hint: Parameter "Sender" not used
UMain.pas(89,87) Hint: Parameter "aState" not used
UMain.pas(90,33) Hint: Parameter "Sender" not used
UMain.pas(91,33) Hint: Parameter "Sender" not used
UMain.pas(290,26) Note: Local variable "Document" is assigned but never used
UMain.pas(92,33) Hint: Parameter "Sender" not used
UMain.pas(93,27) Hint: Parameter "Sender" not used
UMain.pas(94,34) Hint: Parameter "Sender" not used
UMain.pas(94,51) Hint: Parameter "Node" not used
UMain.pas(86,26) Hint: Parameter "Sender" not used
UMain.pas(87,30) Hint: Parameter "Sender" not used
UMain.pas(88,30) Hint: Parameter "Sender" not used
UMain.pas(83,31) Hint: Parameter "SenderAn unhandled exception occurred at $00401FD2 :
EAccessViolation : Access violation
$00401FD2
$004E4253
$004E1CE5
$004E148A
$004CB4B1
$004C3AF3
$004C5ECF
$004C6730
$004C69E0
$004C3AF3
$004C5ECF
$0042EC9E
$004F94CC
" not used
UMain.pas(82,28) Hint: Parameter "Sender" not used
UMain.pas(84,29) Hint: Parameter "Sender" not used
UMain.pas(85,25) Hint: Parameter "Sender" not used
UMain.pas(85,46) Hint: Parameter "CloseAction" not used
UMain.pas(1,1) Fatal: Compilation aborted

Открыть существующий файл так и не выходит. Одна и та же ошибка :(
Наверное придется через библиотеку работать с OpenOffice.

ЗЫ.Черт по моему, как-то это не правильно.
bestonix
новенький
 
Сообщения: 66
Зарегистрирован: 15.04.2010 08:26:00
Откуда: Жигулёвск

Re: Работа с OpenOffice Calc из Lazarus

Сообщение khvalera » 21.12.2011 03:33:04

Аватара пользователя
khvalera
новенький
 
Сообщения: 57
Зарегистрирован: 29.06.2010 00:49:43

Re: Работа с OpenOffice Calc из Lazarus

Сообщение Tango » 18.01.2013 17:42:45

Может кто подскажет, делаю всё как надо, в Делфи работает, а в Лазаре, нет.

Код: Выделить всё
    unit OOoTest;

    {$mode objfpc}{$H+}

    interface

    uses
      Classes, SysUtils, FileUtil, LResources, Forms, Controls, Graphics, Dialogs,
      StdCtrls, EditBtn, MaskEdit, ComObj, Variants, LCLProc, lconvencoding;
    var
      Server: Variant;
      Desktop    : Variant;
      LoadParams : Variant;
      Document   : Variant;
      TextCursor : Variant;
      BookmarksSupplier: Variant;
      Bookmark: Variant;

      instext: string;
      OO,VariantArray,Sheets,Sheet,Range,Cell: Variant;
      GetTemplateErrorCode,StartRow,StartCol,RecRepNum,i:Word;

    const
      ServerName = 'com.sun.star.ServiceManager';

    procedure ReportOpenOfficeCalc(Save: Boolean);

    implementation

    Function MakePropertyValue(PropertyName, PropertyValue: Variant): Variant;
    var
      Structure: Variant;
    Begin
      Structure:=OO.Bridge_GetStruct('com.sun.star.beans.PropertyValue');
      Structure.Name:=PropertyName;
      Structure.Value:=PropertyValue;
      Result:=Structure;
    End;

    procedure InsertTextByXY(Const Text: String; row, col: Integer);
    Begin
      Cell:=Sheet.getCellByPosition(col, row);
      Cell.setString(Text);
    End;

    Function FileNameToURL(FileName: String): Variant;
    var
      i: Integer;
      ch: Char;
    Begin
      Result:='';
      For i:=1 to Length(FileName) do
      Begin
        ch:=FileName[i];
        Case ch of
        'А'..'Я', 'а'..'я':
        Result:=Result+'%'+IntToHex(Ord(ch), 8);
        ' ':
        Result:=Result+'%20';
        '':
        Result:=Result+'/';
        ':':
        Result:=Result+'|';
      Else
      Result:=Result+ch;
        End;
      End;
      Result:='file:///'+Result;
    End;


  procedure ReportOpenOfficeCalc(Save: Boolean);
  var
    SQLStr, FileName, ColorStr: String;
    ToPDF, ToHTML: Boolean;
  Begin
    {$IFDEF MSWINDOWS}
    FileName:='D:TangoMy ProjectsOOoLazTestOOo.xls';
    If GetTemplateErrorCode=0 then
      If FileExists(FileName) then
      Begin
          If VarIsEmpty(OO) then
            OO:=CreateOleObject('com.sun.star.ServiceManager');
          Desktop:=OO.CreateInstance('com.sun.star.frame.Desktop');
          VariantArray:=VarArrayCreate([0, 0], varVariant);
          VariantArray[0]:=MakePropertyValue('FilterName', 'MS Excel 97');
          Document:=Desktop.LoadComponentFromURL(FileNameToURL(FileName), '_blank', 0,
            VariantArray);
          Sheets:=Document.GetSheets;
          Sheet:=Sheets.getByIndex(0);
        Try
          Range:=Sheet.getCellRangeByName('DATA');
          StartRow:=Range.RangeAddress.StartRow;
          StartCol:=Range.RangeAddress.StartColumn;
        Except
          Exit;
        End;


        RecRepNum:=1;
        For i:=1 to 10 do
        Begin
          InsertTextByXY('Привет OO!', RecRepNum+StartRow-1, 1+StartCol-1);
          Inc(RecRepNum);
        End;

        If Save then
        Begin
          Document.StoreToURL(FileNameToURL(FileName), VariantArray);
          Document.Close(True);
          Document:=Unassigned;
        End;
        OO:=Unassigned;

        If not Save then
          If FileName<>'' then
            If FileExists(FileName) then
              Try
                DeleteFile(FileName);
              Except
                //
              End;
      End
      Else
        ShowMessage(' - 5007/'+FileName);
    {$ENDIF}
  End;

end.


Не хочет открывать файл. Пишет ошибку EPleSysError.

Добавлено спустя 29 минут 21 секунду:
Ошибка выскакивает на строке:

Код: Выделить всё
Document:=Desktop.LoadComponentFromURL(FileNameToURL(FileName), '_blank', 0,
            VariantArray);
Аватара пользователя
Tango
постоялец
 
Сообщения: 162
Зарегистрирован: 31.05.2012 17:07:30

Re: Работа с OpenOffice Calc из Lazarus

Сообщение Tango » 21.01.2013 11:35:33

Разобрался сам.

Проблема крылась вот в чём:

Результат функции FileNameToURL должен быть не просто типа Variant а типизированным вариантом, для этого результат приводится к типу так:

Код: Выделить всё
Result:=VarAsType('file:///'+Result, varOleStr);


тоже лучше делать и со значениями посылаемыми в сам ОО.
Аватара пользователя
Tango
постоялец
 
Сообщения: 162
Зарегистрирован: 31.05.2012 17:07:30


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 245

Рейтинг@Mail.ru