Diferencia entre revisiones de «Usuario:Luis.perez/pyunoaytozgz/pyuno»
m (Página creada con '{{MiTitulo|PyUNO: Macros y componentes para OpenOffice/LibreOffice con Python}} {{Recursos de la Web |Title=Documentación y recursos generales| === Documentación === * Guía …') |
m |
||
Línea 1: | Línea 1: | ||
{{MiTitulo|PyUNO: Macros y componentes para OpenOffice/LibreOffice con Python}} | {{MiTitulo|PyUNO: Macros y componentes para OpenOffice/LibreOffice con Python}} | ||
+ | == Documentación == | ||
{{Recursos de la Web |Title=Documentación y recursos generales| | {{Recursos de la Web |Title=Documentación y recursos generales| | ||
− | + | ;Documentación | |
* Guía oficial de desarrollo de OpenOffice: http://wiki.openoffice.org/wiki/Documentation/DevGuide | * Guía oficial de desarrollo de OpenOffice: http://wiki.openoffice.org/wiki/Documentation/DevGuide | ||
* Recopilación de enlaces a docs sobre PyUNO http://wiki.openoffice.org/wiki/Python | * Recopilación de enlaces a docs sobre PyUNO http://wiki.openoffice.org/wiki/Python | ||
* En castellano: http://wiki.openoffice.org/wiki/OOoES/Desarrollo/PyUNO_ES | * En castellano: http://wiki.openoffice.org/wiki/OOoES/Desarrollo/PyUNO_ES | ||
− | + | ;Api | |
* Libreoffice: http://api.libreoffice.org/docs/common/ref/com/sun/star/module-ix.html | * Libreoffice: http://api.libreoffice.org/docs/common/ref/com/sun/star/module-ix.html | ||
* Openoffice: http://www.openoffice.org/api/docs/common/ref/com/sun/star/text/module-ix.html | * Openoffice: http://www.openoffice.org/api/docs/common/ref/com/sun/star/text/module-ix.html | ||
− | + | ;Ejemplos | |
* Ejemplos de la guia de desarrollo: http://api.libreoffice.org/examples/DevelopersGuide/examples.html | * Ejemplos de la guia de desarrollo: http://api.libreoffice.org/examples/DevelopersGuide/examples.html | ||
* Snippets de código: http://codesnippets.services.openoffice.org/index.xml | * Snippets de código: http://codesnippets.services.openoffice.org/index.xml | ||
+ | }} | ||
+ | |||
+ | == Instalación de Libreoffice (Ubuntu) == | ||
+ | * Basta con tener instalado libreoffice si solo se van a hacer macros. | ||
+ | * Si se van a crear componentes instalar adicionalmente el paquete libreoffice-dev | ||
+ | <source lang="bash"> | ||
+ | $ apt-get install libreoffice-dev | ||
+ | </source> | ||
+ | |||
+ | == Introducción al API de Openoffice: conceptos == | ||
+ | |||
+ | ==== Interfaces ==== | ||
+ | |||
+ | * Un conjunto de métodos y/o atributos que exponen funcionalidad. Aspectos de la implementación de un objeto. | ||
+ | * En el api de UNO, todos los nombres de interfaces empiezan con X | ||
+ | * Todos los interfaces extienden XInterface | ||
+ | |||
+ | ==== Servicios ==== | ||
+ | * Servicios "New-style": Especifica que objetos que implementan un determinado interfaz (ej: com.sun.star.bridge.XUnoUrlResolver), estarán disponibles bajo un determinado nombre (ej: com.sun.star.bridge.UnoUrlResolver) en el service manager del component context (ver más adelante). Para que un objeto que implementa un servicio pueda implementar varios aspectos o interfaces, el interfaz que implementa heredará de varios otros interfaces. | ||
+ | |||
+ | * Servicios "Old-style": Los servicios oldstyle pueden verse como un conjunto de interfaces y/o propiedades. | ||
+ | ** Pueden o no exponerse a través del service manager, servir como base de otros servicios (en el new-style, el mecanismo preferido para proporcionar servicios base es implementar interfaces que heredan de varios interfaces), o simplemente servir para agrupar un conjunto de propiedades. | ||
+ | ** Pueden implementar interfaces opcionales | ||
+ | ** Pueden incluir otros servicios, lo que significa que expondrán el conjunto de sus interfaces y de los otros servicios. | ||
+ | |||
+ | Obtener un servicio a través del serviceManager: | ||
+ | <source lang="python"> | ||
+ | desktop = serviceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context) | ||
+ | </source> | ||
+ | '' Más adelante se hablará del serviceManager y del component context'' | ||
+ | |||
+ | Obtener los nombres de servicio que soporta un objeto | ||
+ | |||
+ | <source lang="python"> | ||
+ | obj.getSupportedServiceNames() | ||
+ | </source> | ||
+ | |||
+ | |||
+ | {{Reflexion| | ||
+ | Debido a la existencia de servicios old-style, hay que tener cuidado a la hora de interpretar el api: Algunos servicios no pueden ser instanciados directamente con el service manager | ||
+ | * Porque son conjuntos de propiedades | ||
+ | * Porque solo sirven como servicios base de otros servicios | ||
+ | * O necesitan un tratamiento especial. Ej: ''com.sun.star.text.TextDocument'' no puede instanciarse directamente, se obtiene a través de ''loadComponentFromUrl()'' de ''com.sun.star.frame.XComponentLoader'' | ||
+ | }} | ||
+ | |||
+ | |||
+ | ==== Propiedades ==== | ||
+ | * Pares de nombre-valor que expone un servicio. | ||
+ | * Normalmente suelen ser utilizados para atributos no estructurales (ej: color, tamaño, pero no objetos padre o hijos) | ||
+ | * Se suelen acceder mediante ''com.sun.star.beans.XPropertySet'', pero también en algunos casos, a través de ''com.sun.star.beans.XPropertyAccess'' ó ''com.sun.star.beans.XMultiPropertySet'' | ||
+ | |||
+ | Obtener propiedad (XPropertySet): | ||
+ | <source lang="python"> | ||
+ | sheet.getPropertyValue("IsVisible") | ||
+ | </source> | ||
+ | |||
+ | Establecer propiedad: | ||
+ | <source lang="python"> | ||
+ | sheet.setPropertyValue("IsVisible", False) | ||
+ | </source> | ||
+ | |||
+ | Obtener propiedades de un objeto: | ||
+ | <source lang="python"> | ||
+ | propsinfo = sheet.getPropertySetInfo() | ||
+ | props = propsinfo.getProperties() | ||
+ | for prop in props: | ||
+ | print(prop) | ||
+ | </source> | ||
+ | |||
+ | ==== Singletons ==== | ||
+ | |||
+ | * Implementación de interface del que solo existe una instancia accesible desde el component context. | ||
+ | |||
+ | ==== Componentes / extensiones ==== | ||
+ | * Son librerías que contienen implementaciones de uno o varios servicios en cualquiera de los lenguajes que soporta UNO | ||
+ | |||
+ | ==== Estructuras, Constantes, y Enumeraciones ==== | ||
+ | * Estructuras: Conjunto de miembros, similar a la estructuras en C. Soportan herencia simple. | ||
+ | :Instanciando una estructura: | ||
+ | <source lang="python"> | ||
+ | import uno | ||
+ | uno.createUnoStruct("com.sun.star.beans.PropertyValue") | ||
+ | </source> | ||
+ | * Constants: tipo que agrupa varios valores constantes | ||
+ | :Obteniendo el valor de una constante | ||
+ | <source lang="python"> | ||
+ | import uno | ||
+ | uno.getConstantByName("com.sun.star.sheet.ConditionOperator.GREATER") | ||
+ | </source> | ||
+ | * Enum: Similar a una enumeración en c++ | ||
+ | <source lang="python"> | ||
+ | </source> | ||
+ | |||
+ | ==== Módulos ==== | ||
+ | |||
+ | * Espacios de nombres, similares a los namespaces de C++ o a los paquetes en Java. Agrupan servicios, interfaces, structs... | ||
+ | |||
+ | === ComponentContext === | ||
+ | * Objeto con el que se obtene el singleton de ServiceManager | ||
+ | * Puede obtenerse dependiendo de si el código a ejecutar va a ser una macro o un componente. | ||
+ | |||
+ | === ServiceManager === | ||
+ | * Objeto con el que se instancian servicios | ||
+ | <source lang="python"> | ||
+ | serviceManager = ctx.ServiceManager | ||
+ | </source> | ||
+ | |||
+ | |||
+ | == Macros == | ||
+ | |||
+ | Son pequeños programas que usan el api UNO para automatizar tareas en documentos | ||
+ | |||
+ | Ejemplo: | ||
+ | |||
+ | <source lang="python"> | ||
+ | import uno | ||
+ | |||
+ | def holaMundoCalc(): | ||
+ | # Accedemos al modelo del documento actual | ||
+ | model = XSCRIPTCONTEXT.getDocument() | ||
+ | # Accedemos a la primer hoja del documento | ||
+ | hoja = model.getSheets().getByIndex(0) | ||
+ | # Accedemos a la celda A1 de la hoja | ||
+ | celda = hoja.getCellRangeByName("A1") | ||
+ | # Escribimos en la celda | ||
+ | celda.setString("Hola Mundo en Python") | ||
+ | return None | ||
+ | </source> | ||
+ | |||
+ | * XSCRIPTCONTEXT: variable global en el script que contiene Document (el objeto que representa un documento), Desktop y ComponentContext | ||
+ | * Por defecto todas las funciones del script se exportan como macros. Para limitarlos: | ||
+ | <source lang="python"> | ||
+ | g_exportedScripts = (holaMundoCalc, ) # solo expondrá holaMundoCalc, aunque haya otras funciones | ||
+ | </source> | ||
+ | * El comentario de una función se muestra como descripción de la macro en el diálogo de macros | ||
+ | |||
+ | |||
+ | ==== Ejecución de macros ==== | ||
+ | |||
+ | Puede hacerse a través del díalogo ''tools -> macros -> run macro...'' | ||
+ | o a través de ''tools -> macros -> organize macros -> python...'' | ||
+ | |||
+ | ==== Distribución de macros ==== | ||
+ | |||
+ | Existen varios modos de distribuir una macro | ||
+ | * En directorio de usuario: | ||
+ | ** ~/.openoffice.org/3/:user/Scripts/python | ||
+ | ** ~/.config/libreoffice/3/user/Scripts/python | ||
+ | * En directorio compartido (para todos los usuarios) | ||
+ | ** /usr/lib/libreoffice/share/Scripts/python | ||
+ | ** /usr/lib/openoffice/share/Scripts/python | ||
+ | * Embebido en documentos: | ||
+ | # Descomprimir documento con unzip | ||
+ | # Incluir el script en cualquier ruta bajo el directorio Scripts | ||
+ | # Modificar META-INF/manifest.mf, incluyendo referencia al script:<source lang="xml"><manifest:file-entry manifest:media-type="" manifest:full-path="Scripts/python/mostrarversion.py"/></source> | ||
+ | # Volver a comprimir el documento | ||
+ | * Empaquetado | ||
+ | :Se creará una estructura de archivos: | ||
+ | <source lang="bash"> | ||
+ | /description.xml | ||
+ | /Scripts/python/holamundo.py | ||
+ | /META-INF/manifest.mf | ||
+ | </source> | ||
+ | |||
+ | :Donde description.xml sirve para dar información sobre el paquete (ver 2_simplemacropkg), y manifest.mf referencia la ruta base de los scripts del siguiente modo: | ||
+ | <source lang="xml"> | ||
+ | <manifest:manifest> | ||
+ | <manifest:file-entry manifest:media-type="application/vnd.sun.star.framework-script" manifest:full-path="Scripts"/> | ||
+ | </manifest:manifest> | ||
+ | </source> | ||
+ | |||
+ | == Transformando código Java a Python: diferencias == | ||
+ | |||
+ | Una buena forma de aprender sobre UNO es mediante los ejemplos que hay disponibles. Lamentablemente la mayoría de código es Java o C++. | ||
+ | * La primera diferencia es obvia: python no es estáticamente tipado | ||
+ | * Para obtener y usar un servicio, no es necesario instanciar el servicio y luego hacer un UnoRuntime.queryInterface para obtener el interface deseado del tipo correcto. Basta con instanciar el servicio o componente, y usarlo directamente. Ej: | ||
+ | <source lang="java"> | ||
+ | // doc es un objeto documento | ||
+ | XSpreadsheetDocument xSpreadsheetDocument = (XSpreadsheetDocument) | ||
+ | UnoRuntime.queryInterface(XSpreadsheetDocument.class, doc); | ||
+ | |||
+ | XSpreadsheets xSpreadsheets = xSpreadsheetDocument.getSheets(); | ||
+ | xSpreadsheets.insertNewByName("MySheet", (short)0); | ||
+ | </source> | ||
+ | Esto se traduce a: | ||
+ | <source lang="python"> | ||
+ | xSpreadsheets = doc.getSheets() | ||
+ | xSpreadsheets.insertNewByName("MySheet", 0) | ||
+ | </source> | ||
+ | |||
+ | * Los arrays y listas se transforman de y hacia python como tuplas, NO como listas!. | ||
+ | <source lang="java"> | ||
+ | com.sun.star.beans.PropertyValue[] conditions = new com.sun.star.beans.PropertyValue[1]; | ||
+ | conditions[0] = condition1 | ||
+ | conditions[1] = condition2 | ||
+ | obj.metodoquerecibeprops(conditions) | ||
+ | </source> | ||
+ | : Lo anterior en python sería: | ||
+ | <source lang="python"> | ||
+ | conditions = (condition1, condition2) | ||
+ | obj.metodoquerecibeprops(conditions) | ||
+ | </source> | ||
+ | |||
+ | |||
+ | == Calc: Api == | ||
+ | |||
+ | {{Ejemplo|Ejemplos del api de calc | ||
+ | Leer y ejecutar paso a paso la macro del ejemplo 3_calc_api. | ||
+ | }} | ||
+ | |||
+ | == Componentes y extensiones en PyUNO == | ||
+ | |||
+ | : | ||
+ | {{Recursos de la Web |Title=Documentación| | ||
+ | ;Documentación | ||
+ | http://wiki.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Writing_UNO_Components | ||
+ | http://wiki.openoffice.org/wiki/Documentation/DevGuide/Extensions/ | ||
+ | http://wiki.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Writing_the_Specification -> especificación de UNO IDL | ||
+ | ;Ejemplo | ||
+ | http://www.biochemfusion.com/doc/Calc_addin_howto.html | ||
}} | }} |
Revisión de 09:45 23 ene 2013
Contenido
Documentación
|
Instalación de Libreoffice (Ubuntu)
- Basta con tener instalado libreoffice si solo se van a hacer macros.
- Si se van a crear componentes instalar adicionalmente el paquete libreoffice-dev
$ apt-get install libreoffice-dev
Introducción al API de Openoffice: conceptos
Interfaces
- Un conjunto de métodos y/o atributos que exponen funcionalidad. Aspectos de la implementación de un objeto.
- En el api de UNO, todos los nombres de interfaces empiezan con X
- Todos los interfaces extienden XInterface
Servicios
- Servicios "New-style": Especifica que objetos que implementan un determinado interfaz (ej: com.sun.star.bridge.XUnoUrlResolver), estarán disponibles bajo un determinado nombre (ej: com.sun.star.bridge.UnoUrlResolver) en el service manager del component context (ver más adelante). Para que un objeto que implementa un servicio pueda implementar varios aspectos o interfaces, el interfaz que implementa heredará de varios otros interfaces.
- Servicios "Old-style": Los servicios oldstyle pueden verse como un conjunto de interfaces y/o propiedades.
- Pueden o no exponerse a través del service manager, servir como base de otros servicios (en el new-style, el mecanismo preferido para proporcionar servicios base es implementar interfaces que heredan de varios interfaces), o simplemente servir para agrupar un conjunto de propiedades.
- Pueden implementar interfaces opcionales
- Pueden incluir otros servicios, lo que significa que expondrán el conjunto de sus interfaces y de los otros servicios.
Obtener un servicio a través del serviceManager:
desktop = serviceManager.createInstanceWithContext("com.sun.star.frame.Desktop", context)
Más adelante se hablará del serviceManager y del component context
Obtener los nombres de servicio que soporta un objeto
obj.getSupportedServiceNames()
Debido a la existencia de servicios old-style, hay que tener cuidado a la hora de interpretar el api: Algunos servicios no pueden ser instanciados directamente con el service manager
|
Propiedades
- Pares de nombre-valor que expone un servicio.
- Normalmente suelen ser utilizados para atributos no estructurales (ej: color, tamaño, pero no objetos padre o hijos)
- Se suelen acceder mediante com.sun.star.beans.XPropertySet, pero también en algunos casos, a través de com.sun.star.beans.XPropertyAccess ó com.sun.star.beans.XMultiPropertySet
Obtener propiedad (XPropertySet):
sheet.getPropertyValue("IsVisible")
Establecer propiedad:
sheet.setPropertyValue("IsVisible", False)
Obtener propiedades de un objeto:
propsinfo = sheet.getPropertySetInfo() props = propsinfo.getProperties() for prop in props: print(prop)
Singletons
- Implementación de interface del que solo existe una instancia accesible desde el component context.
Componentes / extensiones
- Son librerías que contienen implementaciones de uno o varios servicios en cualquiera de los lenguajes que soporta UNO
Estructuras, Constantes, y Enumeraciones
- Estructuras: Conjunto de miembros, similar a la estructuras en C. Soportan herencia simple.
- Instanciando una estructura:
import uno uno.createUnoStruct("com.sun.star.beans.PropertyValue")
- Constants: tipo que agrupa varios valores constantes
- Obteniendo el valor de una constante
import uno uno.getConstantByName("com.sun.star.sheet.ConditionOperator.GREATER")
- Enum: Similar a una enumeración en c++
Módulos
- Espacios de nombres, similares a los namespaces de C++ o a los paquetes en Java. Agrupan servicios, interfaces, structs...
ComponentContext
- Objeto con el que se obtene el singleton de ServiceManager
- Puede obtenerse dependiendo de si el código a ejecutar va a ser una macro o un componente.
ServiceManager
- Objeto con el que se instancian servicios
serviceManager = ctx.ServiceManager
Macros
Son pequeños programas que usan el api UNO para automatizar tareas en documentos
Ejemplo:
import uno def holaMundoCalc(): # Accedemos al modelo del documento actual model = XSCRIPTCONTEXT.getDocument() # Accedemos a la primer hoja del documento hoja = model.getSheets().getByIndex(0) # Accedemos a la celda A1 de la hoja celda = hoja.getCellRangeByName("A1") # Escribimos en la celda celda.setString("Hola Mundo en Python") return None
- XSCRIPTCONTEXT: variable global en el script que contiene Document (el objeto que representa un documento), Desktop y ComponentContext
- Por defecto todas las funciones del script se exportan como macros. Para limitarlos:
g_exportedScripts = (holaMundoCalc, ) # solo expondrá holaMundoCalc, aunque haya otras funciones
- El comentario de una función se muestra como descripción de la macro en el diálogo de macros
Ejecución de macros
Puede hacerse a través del díalogo tools -> macros -> run macro... o a través de tools -> macros -> organize macros -> python...
Distribución de macros
Existen varios modos de distribuir una macro
- En directorio de usuario:
- ~/.openoffice.org/3/:user/Scripts/python
- ~/.config/libreoffice/3/user/Scripts/python
- En directorio compartido (para todos los usuarios)
- /usr/lib/libreoffice/share/Scripts/python
- /usr/lib/openoffice/share/Scripts/python
- Embebido en documentos:
- Descomprimir documento con unzip
- Incluir el script en cualquier ruta bajo el directorio Scripts
- Modificar META-INF/manifest.mf, incluyendo referencia al script:
<manifest:file-entry manifest:media-type="" manifest:full-path="Scripts/python/mostrarversion.py"/>
- Volver a comprimir el documento
- Empaquetado
- Se creará una estructura de archivos:
/description.xml /Scripts/python/holamundo.py /META-INF/manifest.mf
- Donde description.xml sirve para dar información sobre el paquete (ver 2_simplemacropkg), y manifest.mf referencia la ruta base de los scripts del siguiente modo:
<manifest:manifest> <manifest:file-entry manifest:media-type="application/vnd.sun.star.framework-script" manifest:full-path="Scripts"/> </manifest:manifest>
Transformando código Java a Python: diferencias
Una buena forma de aprender sobre UNO es mediante los ejemplos que hay disponibles. Lamentablemente la mayoría de código es Java o C++.
- La primera diferencia es obvia: python no es estáticamente tipado
- Para obtener y usar un servicio, no es necesario instanciar el servicio y luego hacer un UnoRuntime.queryInterface para obtener el interface deseado del tipo correcto. Basta con instanciar el servicio o componente, y usarlo directamente. Ej:
// doc es un objeto documento XSpreadsheetDocument xSpreadsheetDocument = (XSpreadsheetDocument) UnoRuntime.queryInterface(XSpreadsheetDocument.class, doc); XSpreadsheets xSpreadsheets = xSpreadsheetDocument.getSheets(); xSpreadsheets.insertNewByName("MySheet", (short)0);
Esto se traduce a:
xSpreadsheets = doc.getSheets() xSpreadsheets.insertNewByName("MySheet", 0)
- Los arrays y listas se transforman de y hacia python como tuplas, NO como listas!.
com.sun.star.beans.PropertyValue[] conditions = new com.sun.star.beans.PropertyValue[1]; conditions[0] = condition1 conditions[1] = condition2 obj.metodoquerecibeprops(conditions)
- Lo anterior en python sería:
conditions = (condition1, condition2) obj.metodoquerecibeprops(conditions)
Calc: Api
Componentes y extensiones en PyUNO
http://wiki.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Writing_UNO_Components http://wiki.openoffice.org/wiki/Documentation/DevGuide/Extensions/ http://wiki.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Writing_the_Specification -> especificación de UNO IDL
|