Работа с LibreOffice, как с Com-объектом

Автор Борис_С, 22 октября 2021, 17:15

0 Пользователи и 1 гость просматривают эту тему.

sokol92

Хочу поблагодарить и автора за интересную тему.
Владимир.

Борис_С

Привожу полный код программы. Возможно кому-нибудь пригодится.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Diagnostics;

using unoidl.com.sun.star.lang;
using unoidl.com.sun.star.uno;
using unoidl.com.sun.star.bridge;
using unoidl.com.sun.star.frame;
namespace ConsoleApp
{
    class Program
    {
        private static unoidl.com.sun.star.sheet.XSpreadsheetDocument mxDocument;
        static void Main(string[] args)
        {
            try
            {
                unoidl.com.sun.star.uno.XComponentContext localContext =
                    uno.util.Bootstrap.bootstrap();
                unoidl.com.sun.star.lang.XMultiServiceFactory multiServiceFactory =
                    (unoidl.com.sun.star.lang.XMultiServiceFactory)localContext.getServiceManager();
                XComponentLoader componentLoader = (XComponentLoader)
                    multiServiceFactory.createInstance("com.sun.star.frame.Desktop");
                string fileName = "c:\\Users\\sbe.CSOFT-SPB\\Documents\\OO\\t1.ods";
                fileName = @"file:///" + fileName.Replace('\\', '/');
                XComponent xComponent = componentLoader.loadComponentFromURL(
                    fileName, "_blank",
                    0, new unoidl.com.sun.star.beans.PropertyValue[0]);
                if (fileName.ToLower().EndsWith(".ods"))
                {
                    mxDocument = (unoidl.com.sun.star.sheet.XSpreadsheetDocument)xComponent;
                    // адреса гиперссылок
                    List<string> url = new List<string>();
                    // тексты гиперссылок
                    List<string> representation = new List<string>();
                    getHyperLinksInCell(0, 0, 0, ref url, ref representation);
                   
                }
                xComponent.dispose();
            }
            catch (System.Exception e)
            {
                string message = String.Format("Ошибка.\n{0}\n{1}",
                    e.Message, e.StackTrace.TrimStart());
                Debug.WriteLine(message);
            }
        }
        // получение гиперссылок в ячейке
        private static void getHyperLinksInCell(int nIndexSheet, int row, int col,
            ref List<string> url, ref List<string> representation)
        // nIndex - индекс листа
        // row - номер строки
        // col - номер колонки
        // url - адреса гиперссылок
        // representation - тексты гиперссылок
        {
            unoidl.com.sun.star.sheet.XSpreadsheet xSheet = getSpreadsheet(nIndexSheet);
            unoidl.com.sun.star.table.XCell xCell = xSheet.getCellByPosition(row, col);
            if (xCell.getType() == unoidl.com.sun.star.table.CellContentType.TEXT)
            {
                unoidl.com.sun.star.text.XTextRange xCell1 =
                    (unoidl.com.sun.star.text.XTextRange)xCell;
                unoidl.com.sun.star.container.XEnumerationAccess gText =
                    (unoidl.com.sun.star.container.XEnumerationAccess)xCell1.getText();
                unoidl.com.sun.star.container.XEnumeration oParEnum = gText.createEnumeration();
                while (oParEnum.hasMoreElements())
                {
                    uno.Any oParElement = oParEnum.nextElement();
                    unoidl.com.sun.star.container.XEnumeration oEnum =
                        ((unoidl.com.sun.star.container.XEnumerationAccess)oParElement.Value).
                        createEnumeration();
                    while (oEnum.hasMoreElements())
                    {
                        uno.Any oElement = oEnum.nextElement();
                        unoidl.com.sun.star.text.XTextRange xTextRange =
                            (unoidl.com.sun.star.text.XTextRange)oElement.Value;
                        unoidl.com.sun.star.beans.XPropertySet xPropSet =
                            (unoidl.com.sun.star.beans.XPropertySet)xTextRange;
                        String sTextPortionType =
                            (String)xPropSet.getPropertyValue("TextPortionType").Value;
                        if (sTextPortionType == "TextField")
                        {
                            unoidl.com.sun.star.lang.XServiceInfo xTextField =
                                (unoidl.com.sun.star.lang.XServiceInfo)xPropSet.
                                getPropertyValue("TextField").Value;
                            if (xTextField.supportsService("com.sun.star.text.TextField.URL"))
                            {
                                unoidl.com.sun.star.beans.XPropertySet xPropSet1 =
                                    (unoidl.com.sun.star.beans.XPropertySet)xTextField;
                                string sRepresentation =
                                    (String)xPropSet1.getPropertyValue("Representation").Value;
                                representation.Add(sRepresentation);
                                string sUrl =
                                    (String)xPropSet1.getPropertyValue("URL").Value;
                                url.Add(sUrl);
                            }
                        }
                    }
                }
            }

        }
        /** Returns the spreadsheet with the specified index (0-based).
                @param nIndex  The index of the sheet.
                @return  XSpreadsheet interface of the sheet. */
        private static unoidl.com.sun.star.sheet.XSpreadsheet getSpreadsheet(int nIndex)
        {
            // Collection of sheets
            unoidl.com.sun.star.sheet.XSpreadsheets xSheets =
                mxDocument.getSheets();

            unoidl.com.sun.star.container.XIndexAccess xSheetsIA =
                (unoidl.com.sun.star.container.XIndexAccess)xSheets;

            unoidl.com.sun.star.sheet.XSpreadsheet xSheet =
                (unoidl.com.sun.star.sheet.XSpreadsheet)
                  xSheetsIA.getByIndex(nIndex).Value;

            return xSheet;
        }
    }
}

Борис_С

Цитата: sokol92 от  2 декабря 2021, 17:32Предположим, что в ячейке A1 есть гиперссылка с последующим простым текстом (итого две части).
Вызываем MRI:
Код:
mri ThisComponent
Переходим на вкладку Methods и далее (методы вызываются двойным щелчком):
1. Добираемся до ячейки A1 первого листа текущего документа:
- getSheets
- getbyIndex. Параметр: 0
- getCellByPosition. Параметры: 0, 0

Контрольная точка: на владке Properties свойство AbsoluteName имеет вид типа: $Sheet1.$A$1
Можно сразу получить объект для ячейки A1:
Код:
mri ThisComponent.Sheets(0).getCellByPosition(0,0)

2. Следуем тексту макроса А.Питоньяка.

  Получаем нумератор для текста:
- getText
- createEnumeration
- Можно получить все элементы нумератора с помощью пункта меню Macros / bundle.py / Inspect Elements of Enumeration Container
  
  Окно должно называться --nextElement() и быть единственным (пока) с этим названием.
Володя, стал разбираться, как работать с MRI.
Дошел до этой точки. Не понял, о каком окне идет речь.

sokol92

#78
Добрый день! Combobox под меню (на 3-й строке экрана). Это история всех действий пользователя. Можно возвращаться к предыдущим действиям.
Владимир.

Борис_С

Цитата: sokol92 от  2 декабря 2021, 17:323. Получаем элементы для вложенного нумератора.
 - createEnumeration
 - указанным выше способом получаем все элементы нумератора.
Здесь уже должно быть два элемента, соотвествующих гиперссылке и простому тексту.
Где эти элементы? Как их увидеть?

sokol92

Владимир.

Борис_С

Все получилось. Получил код, перевел его на C# CLI.
И тут вопрос. В коде есть оператор: XTextRange xTextRange = (XTextRange) xCell;
Он не работает. Его нужно заменить на
unoidl.com.sun.star.text.XTextRange xTextRange = (unoidl.com.sun.star.text.XTextRange)xCell;
Почему?

sokol92

Может быть, соответствующего Using не хватает?
Владимир.

Борис_С

Да. Это так. Теперь все в порядке. Спасибо.

Борис_С

Цитата: sokol92 от  2 декабря 2021, 21:01Работа с массивами показана в ViewSample.cs из примеров по ссылке Михаила
Владимир, в файле ViewSample.cs я не нашел работу с массивами. Может вы подскажете в каком методе это нужно посмотреть.

sokol92

Посмотрите на фрагмент указанного файла:

unoidl.com.sun.star.beans.PropertyValue[] aArguments =
new unoidl.com.sun.star.beans.PropertyValue[2];


и далее.
Владимир.

Борис_С

Цитата: sokol92 от  2 декабря 2021, 21:01XScriptProviderSupplier xScriptProviderSupplier = (XScriptProviderSupplier) oInitialTarget;
Что это за переменная oInitialTarget?

sokol92

#87
Так MRI именует объект, который был ему передан при вызове в качестве параметра (например, параметром мог быть ThisComponent).
Владимир.

Борис_С

Получилось. Вот код:


    class Program
    {
        private static unoidl.com.sun.star.sheet.XSpreadsheetDocument mxDocument;
        static void Main(string[] args)
        {
            try
            {
                unoidl.com.sun.star.uno.XComponentContext localContext =
                    uno.util.Bootstrap.bootstrap();
                unoidl.com.sun.star.lang.XMultiServiceFactory multiServiceFactory =
                    (unoidl.com.sun.star.lang.XMultiServiceFactory)localContext.getServiceManager();
                XComponentLoader componentLoader = (XComponentLoader)
                    multiServiceFactory.createInstance("com.sun.star.frame.Desktop");
                string fileName = "c:\\Users\\sbe.CSOFT-SPB\\Documents\\OO\\ForInvoke.ods";
                fileName = @"file:///" + fileName.Replace('\\', '/');
                XComponent xComponent = componentLoader.loadComponentFromURL(
                    fileName, "_blank",
                    0, new unoidl.com.sun.star.beans.PropertyValue[0]);

                XScriptProviderSupplier xScriptProviderSupplier =
                        (XScriptProviderSupplier)xComponent;
                XScriptProvider xScriptProvider = xScriptProviderSupplier.getScriptProvider();
                XScript xScript = xScriptProvider.getScript(
                        "vnd.sun.star.script:Standard.Module1.Myfunc1?language=Basic&location=document");

                uno.Any[] array1 = { new uno.Any(1), new uno.Any(2) };
                short[] array2 = new short[0];
                uno.Any[] array3 = new uno.Any[0];
                uno.Any v = xScript.invoke(array1, out array2, out array3);
                string v1 = v.Value.ToString();

                xComponent.dispose();
            }
            catch (System.Exception e)
            {
                string message = String.Format("Ошибка.\n{0}\n{1}",
                    e.Message, e.StackTrace.TrimStart());
                Debug.WriteLine(message);
            }
        }


Параметры для вызова скрипта формируются иначе, чем в файле ViewSample.cs

sokol92

Цитата: Борис_С от  7 декабря 2021, 15:32Получилось.
Хорошо. Метод invoke - это что-то вроде USB, дает возможность обращаться по единому интерфейсу ко всем встроенным языкам LO.  :)
Владимир.