Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

Форум поддержки пользователей. LibreOffice, Apache OpenOffice, OpenOffice.org

7 Декабрь 2021, 18:44 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
Новости: Часто задаваемые вопросы по LibreOffice и Apache OpenOffice.org
 
   Начало   Помощь Поиск Войти Регистрация    задать вопрос  
Страниц: 1 2 3 4 5 6   Вниз
  Печать  
Автор Тема: Работа с LibreOffice, как с Com-объектом  (Прочитано 3163 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Борис_С
Форумчанин
***
Offline Offline

Сообщений: 173


« Стартовое сообщение: 22 Октябрь 2021, 17:15 »

Всем доброго дня.
Подскажите, пожалуйста, можно ли работать с LibreOffice, OpenOffice как с Com-объектоми, и если да, как их запустить на c#?
Спасибо.
Записан
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 625


WWW
« Ответ #1: 22 Октябрь 2021, 17:41 »

Только что была тема (VBS).
Записан

Владимир.
Борис_С
Форумчанин
***
Offline Offline

Сообщений: 173


« Ответ #2: 25 Октябрь 2021, 12:57 »

Какое отношение имеет тема "После обработки документа во Writer из макроса нельзя закрыть приложение" к работе с Com-объектом?
Это абсолютно разные вещи.
Мне бы хотелось бы работать с LibreOffice (OpenOffice) так же как и с Microsoft Office через Com (ActiveX).
Есть ли такая возможность?
Записан
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 2 396


« Ответ #3: 25 Октябрь 2021, 13:12 »

Какое отношение имеет тема "После обработки документа во Writer из макроса нельзя закрыть приложение" к работе с Com-объектом?
Возможно то, что скрипт в той теме создавал и работал с COM-объектами?
Записан

С уважением,
Михаил Каганский
Борис_С
Форумчанин
***
Offline Offline

Сообщений: 173


« Ответ #4: 25 Октябрь 2021, 13:15 »

Почему вы так решили? Там нигде про это не написано. Там просто говорится о работе с макросом.
Записан
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 2 396


« Ответ #5: 25 Октябрь 2021, 13:20 »

Почему вы так решили?
Потому что мы внимательно читали Подмигивающий

Тот вопрос про запуск и управление ЛО из скрипта VBS, который не связан с ЛО. Он создаёт объекты с помощью VBS-вызова CreateObject (и всё это там написано Подмигивающий)
Записан

С уважением,
Михаил Каганский
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 625


WWW
« Ответ #6: 25 Октябрь 2021, 13:22 »

Мне бы хотелось бы работать с LibreOffice (OpenOffice) так же как и с Microsoft Office через Com (ActiveX).
Рассмотрим, например, фрагменты скрипта из сообщения #19 указанной темы (фрагменты).

Код:
ServMan = CreateObject("com.sun.star.ServiceManager")  ' создает ActiveX объект ("фабрика" для создания сервисов LO)
Dsctp = ServMan.createInstance("com.sun.star.frame.Desktop")  ' создает объект для работы с фреймами
' ------------------
WriteDoc = Dsctp.loadComponentFromURL("file:///c:/temp/mail_a1.dotx", "_blank", 0, arg)  ' открывет документ (шаблон Word)
' ------------------
Set BFields = WriteDoc.getBookmarks() ' создает объект для работы с закладками документа
' ------------------


Указанный скрипт можно, естественно, запускать из приложений MS Office (VBA) или из любой программы, поддерживающей работу с ActiveX объектами (с поправками на синтаксис языка). Интересно, что объекты 64-разрядного LO могут управляться через интерфейсы автоматизации из 32-разрядных приложений (например, из 32-разрядной версии Excel).
« Последнее редактирование: 25 Октябрь 2021, 13:47 от sokol92 » Записан

Владимир.
Борис_С
Форумчанин
***
Offline Offline

Сообщений: 173


« Ответ #7: 25 Октябрь 2021, 16:56 »

А работает это в С#, и, если да, какие библиотеки нужно подключить?
Записан
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 2 396


« Ответ #8: 25 Октябрь 2021, 18:23 »

https://api.libreoffice.org/examples/examples.html#OLE_examples

Кроме ActiveX, есть ещё привязка CLI. Я сам не писал на C# для ЛО, но например здесь пишут про подключение библиотек cli_*.dll из SDK.
Записан

С уважением,
Михаил Каганский
Борис_С
Форумчанин
***
Offline Offline

Сообщений: 173


« Ответ #9: 30 Ноябрь 2021, 15:37 »

Спасибо за информацию.
Нашел в интернете очень хорошую статью про ActiveX и CLI - http://venec.ulstu.ru/lib/disk/2014/45.pdf
Там много кода и вопросы запуска приложения, загрузки документов и закрытия приложения сразу решились.
Начал с ActiveX. Выяснилось, что ActiveX не поддерживает некоторые методы API (при обращении к этим методам
получаю исключение), а кроме того при этом очень сложно отлаживаться, т.к. все объекты, с которыми нужно работать имеют тип Object.
Перешел на работу с использованием CLI-библиотек.
Нигде не нашел описание объектов и методов CLI-библиотек.
Научился читать информацию из документов,
вставлять гиперссылки в ячейках в OO Calc (как это сделать нашел в Spreadsheet Example).
Но нигде не нашел, как вставлять гиперссылки в ОО Writer.
Также не нашел, как найти гиперссылки в OO Calc и в ОО Writer.
Буду признателен за любые советы.
Записан
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 625


WWW
« Ответ #10: 30 Ноябрь 2021, 19:14 »

На вопрос "где искать" первый ответ (часто и последний) - у А.Питоньяка. Про поиск гиперссылок в ячейках Calc см. раздел 15.11 OOME_4_0.odt.

Моя точка зрения: для LO в настоящий момент целесообразно использовать Basic и/или Python.
« Последнее редактирование: 30 Ноябрь 2021, 19:17 от sokol92 » Записан

Владимир.
Борис_С
Форумчанин
***
Offline Offline

Сообщений: 173


« Ответ #11: 30 Ноябрь 2021, 21:11 »

У Питоньяка описана работа с API OpenOffice. Я же работаю с объектами, их методами и свойствами CLI-библиотек.

Для API OpenOffice для получения гиперссылок в ячейке используется операторы
oCell = ThisComponent.Sheets(0).getCellByPosition(0, 0)
oParEnum = oCell.getText().createEnumeration()

Для API CLI-библиотек все иначе (на C#):
unoidl.com.sun.star.sheet.XSpreadsheetDocument mxDocument =
                        (unoidl.com.sun.star.sheet.XSpreadsheetDocument)xComponent;
unoidl.com.sun.star.sheet.XSpreadsheets d =
                        (unoidl.com.sun.star.sheet.XSpreadsheets)(((unoidl.com.sun.star.sheet.
XSpreadsheetDocument)xComponent).getSheets());
string[] sheets = d.getElementNames();                   
uno.Any t = d.getByName(sheets[0]);
unoidl.com.sun.star.sheet.XSpreadsheet xSheet =
           unoidl.com.sun.star.sheet.XSpreadsheet)t.Value;
unoidl.com.sun.star.table.XCell xCell = xSheet.getCellByPosition(0, 0)
у xCell нет метода getText()
и соответственно и createEnumeration() мне не получить
Записан
mikekaganski
Гуру
*******
Offline Offline

Пол: Мужской
Расположение: Хабаровск -> Москва
Сообщений: 2 396


« Ответ #12: 1 Декабрь 2021, 09:18 »

У Питоньяка описана работа с API OpenOffice. Я же работаю с объектами, их методами и свойствами CLI-библиотек.

...

Для API CLI-библиотек все иначе (на C#):
...
unoidl.com.sun.star.table.XCell xCell = xSheet.getCellByPosition(0, 0)
у xCell нет метода getText()
и соответственно и createEnumeration() мне не получить

Вы ошибаетесь. В обоих случаях используется один и тот же UNO API, документированный здесь. Разница лишь в используемом языке: если Вы используете язык с нестрогой типизацией, типа Basic (или с утиной динамической типизацией, типа Python), то Вы просто обращаетесь с объектом, как имеющим нужный Вам интерфейс, и если это оказывается верно в рантайме, всё в порядке. В шарпе нужно явно приводить объект к нужному типу, если Вы хотите воспользоваться методами/свойствами определённого интерфейса, реализуемого им. Конкретный объект, возвращаемый getCellByPosition, реализует целую кучу интерфейсов, а не только com.sun.star.table.XCell. createEnumeration - метод com.sun.star.container.XEnumerationAccess, что легко определить поиском метода на странице документации API, указанной выше. getText имеют несколько интерфейсов (см. скриншот). Интерфейсы, реализованные в объекте, можно узнать методом getTypes интерфейса com.sun.star.lang.XTypeProvider. Ещё полезен список сервисов, возвращаемый getSupportedServiceNames.

Кстати, именно единство API является одновременно сильной стороной (из любого языка можно получить доступ ко всему; переход с языка на язык производится просто сменой синтаксиса) и проблемой для неопытных программистов (нет упрощённых способов сделать частоиспользуемые действия, и нужно постоянно обращаться к очень технически ориентированной документации, которая не имеет хорошего описания и достаточного количества примеров).


* getText.png (67.76 Кб, 1012x421 - просмотрено 9 раз.)
« Последнее редактирование: 1 Декабрь 2021, 09:37 от mikekaganski » Записан

С уважением,
Михаил Каганский
sokol92
Форумчанин
***
Offline Offline

Пол: Мужской
Сообщений: 625


WWW
« Ответ #13: 1 Декабрь 2021, 13:21 »

Замечательная программа (расширение) MRI является еще и полиглотом!

Открываем (создаем) документ Calc. Запускаем
Код:
mri ThisComponent
далее в меню MRI Tools / Code / C# CLI.
Переходим на вкладку Methods и последовательно вызываем соответствующие методы с соответствующими параметрами (вплоть до получения Enumeration).
Получаем записанный код:

Код:
using System;
using unoidl.com.sun.star.container;
using unoidl.com.sun.star.lang;
using unoidl.com.sun.star.sheet;
using unoidl.com.sun.star.table;
using unoidl.com.sun.star.text;
using unoidl.com.sun.star.uno;

public class Snippet {
public void snippet(XComponentContext xContext, object oInitialTarget)
{
try
{
XSpreadsheetDocument xSpreadsheetDocument = (XSpreadsheetDocument) oInitialTarget;
XSpreadsheets xSpreadsheets = xSpreadsheetDocument.getSheets();

XIndexAccess xIndexAccess = (XIndexAccess) xSpreadsheets;
XSpreadsheet xSpreadsheet = (XSpreadsheet) xIndexAccess.getByIndex(0).Value;
XCellRange xCellRange = (XCellRange) xSpreadsheet;
XCell xCell = xCellRange.getCellByPosition(0, 0);

XTextRange xTextRange = (XTextRange) xCell;
XText xText = xTextRange.getText();

XEnumerationAccess xEnumerationAccess = (XEnumerationAccess) xText;
XEnumeration xEnumeration = xEnumerationAccess.createEnumeration();

}
catch (IndexOutOfBoundsException e)
{
// getByIndex, getCellByPosition
Console.WriteLine(e.Message);
}
catch (WrappedTargetException e)
{
// getByIndex
Console.WriteLine(e.Message);
}
catch (RuntimeException e)
{
// createEnumeration
Console.WriteLine(e.Message);
}
}
}

Протестируйте, пожалуйста, этот подход и расскажите нам о впечатлениях.

Кстати, гуру @JohnSUN выложил в YouTube обучающее видео, посвященное MRI (в ностальгическом стиле старого немого кино, правда, цветное и без музыкального сопровождения. Улыбка).

Записан

Владимир.
Борис_С
Форумчанин
***
Offline Offline

Сообщений: 173


« Ответ #14: 1 Декабрь 2021, 14:25 »

Интерфейсы, реализованные в объекте, можно узнать методом getTypes интерфейса com.sun.star.lang.XTypeProvider.
Попробовал использовать метод getTypes и получил такой результат.


* 2021-12-01_14-16-31.png (170.01 Кб, 1440x900 - просмотрено 8 раз.)
Записан
Страниц: 1 2 3 4 5 6   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!