Есть таблица в Calc. Есть страница с данными в Draw. Все сделано с помощью pyuno. Как вставить таблицу из Calc в Draw программно через pyuno?
Если просто сделать copy/paste, то это не то, что нужно. Нужно выполнить такие действия:
«Вставка» -> «Объект» -> «Объект OLE…» -> «Создать из файла» -> «Вводится имя файла документа Calc» -> «OK»
Как такое сделать через pyuno?
Пробовал через com.sun.star.frame.DispatchHelper
, но не получилось. Выводит только окно с выбором типа объекта и дальше не идет.
У кого есть какие идеи?
Короткий ответ: не получится
Длинный ответ:
Команда InsertObject не до конца реализована. Соответственно нужен другой путь.
Если вставить вручную объект в лист Draw и посмотреть на свойства вставленного объекта, то мы увидим объект OLE2Shape,
у которого есть параметр EmbeddedObject
, типа XEmbeddedObject.
Создать из файла XEmbeddedObject
, пользуясь только API можно, воспользовавшись недокументированным сервисом
import uno import unohelper smgr = uno.getComponentContext().ServiceManager # fname - имя файла url = unohelper.systemPathToFileUrl(os.path.abspath(fname)) storageFactory = smgr.createInstance("com.sun.star.embed.StorageFactory") storage = storageFactory.createInstance() medium = (PropertyValue("URL", 0, url, 0), ) objDescr = (PropertyValue(), ) eoc = smgr.createInstance("com.sun.star.embed.EmbeddedObjectCreator") # недокументированный сервис, реализующий интерфейс com.sun.star.embed.XEmbedObjectCreator eo = eoc.createInstanceInitFromMediaDescriptor(storage, "TestObject", medium, objDescr) xeoType = uno.getTypeByName("com.sun.star.embed.XEmbeddedObject") xeo = eo.queryInterface(xeoType) # xeo уже содержит заргуженный объект. Если файл является файлом OpenOffice # можно получить доступ к документу через xeo.getComponent()
Создать OLE2Shape
и добавить на лист можно как описано на примере вставки диаграммы
doc = XSCRIPTCONTEXT.getDocument() oleShape = doc.createInstance("com.sun.star.drawing.OLE2Shape") # создаем пустой объект doc.getDrawPages().getByIndex(0).add(oleShape) # добавляем объект на лист # oleShape.setSize(xeo.getVisualAreaSize(1)) # задаем размеры по загруженному XEmbeddedObject # oleShape.setPosition(Point(1000, 1000)) # задаем положение объекта на листе
А вот теперь проблема. Нужно скрестить ужа и ежа, то есть вставить xeo
в oleShape
, но у параметра EmbeddedObject
есть только геттер, то есть этот параметр реализован в режиме «только чтение». Создать объект можно задавая параметр CLSID
. Например для книги Calc’а
oleShape.CLSID = "47BBB4CB-CE4C-4E80-a591-42d9ae74950f"
Однако для привязки существующего XEmbeddedObject
к OLE2Shape
доступных путей в API нету.
Идея для реализации задачи, описанной в вопросе пока только одна: загружать книгу Calc в XEmbeddedObject
, создавать OLE2Shape
с пустой книгой и копировать нужный диапазон ячеек из XEmbeddedObject
в OLE2Shape.EmbeddedObject
. По сути — костыль, но других вариантов не найдено.