Python - Copiar apartados de un documento a otro conservando los estilos
-
- Mensajes: 10
- Registrado: Lun Oct 05, 2015 11:13 am
Python - Copiar apartados de un documento a otro conservando los estilos
Buenas compañeros del foro.
He trabajado desde hace tiempo con macros en basic para Libre Office. Y como Mauricio siempre recomendaba python, desde hace un tiempo estoy haciendo cosas con ese lenguaje para las macros.
Estoy utilizando PySide6, para utilizar una aplicación de escritorio desde la que poder hacer llamadas a macros de Libre Office, la cosa funciona.
Pero estoy atascado desde hace días en una macro de python para Libre Office para copiar apartados de un documento conservando sus estilos:
Mi idea es copiar apartados de un documento a otro icluyendo sus estilos, entendiendo como apartado del documento el título de dicho apartado y su texto asociado, ilustraciones, etc.). Sé como controlar los documentos, pero no sé como seleccionar los apartados mencionados y copiar/pegar con sus correspondientes estilos.
He probado con cursores y puedo recorrer todos los títulos del documento, pongamos como ejemplo títulos de tipo "Título 2", buscando un texto de título2 en particular, por lo que deberé copiar desde ese título hasta justo antes de que comience el siguiente título. Pero con dichos cursores solo consigo copiar el texto.
Acudí a este tema del foro: https://forum.openoffice.org/en/forum/v ... hp?t=79540
Con lo que puedo copiar todo el contenido del documento (incluyendo estilos), y pegarlo con [dispatcher.executeDispatch(frame, ".uno:Paste", "", 0, ())]: ver ejemplo inferior
document = XSCRIPTCONTEXT.getDocument()
ctx = uno.getComponentContext()
sm = ctx.ServiceManager
dispatcher = sm.createInstanceWithContext("com.sun.star.frame.DispatchHelper", ctx)
frame = document.CurrentController.Frame
dispatcher.executeDispatch(frame, ".uno:SelectAll", "", 0, ())
dispatcher.executeDispatch(frame, ".uno:Copy", "", 0, ())
dispatcher.executeDispatch(frame, ".uno:GoToEndOfDoc", "", 0, ())
dispatcher.executeDispatch(frame, ".uno:Paste", "", 0, ())
Funciona por lo que parece que la copia con estilos es posible, ¿sabría alguien como podría seleccionar un apartado en concreto y pegarlo?
Aprovecho para preguntar si saben si Mauricio sigue manteniendo ZAZ EasyMacros para Python, la idea es buena, o si alguien conoce otro framework útil.
Lástima que no hay mucha información de macros en python.
Un saludo y gracias de antemano.
He trabajado desde hace tiempo con macros en basic para Libre Office. Y como Mauricio siempre recomendaba python, desde hace un tiempo estoy haciendo cosas con ese lenguaje para las macros.
Estoy utilizando PySide6, para utilizar una aplicación de escritorio desde la que poder hacer llamadas a macros de Libre Office, la cosa funciona.
Pero estoy atascado desde hace días en una macro de python para Libre Office para copiar apartados de un documento conservando sus estilos:
Mi idea es copiar apartados de un documento a otro icluyendo sus estilos, entendiendo como apartado del documento el título de dicho apartado y su texto asociado, ilustraciones, etc.). Sé como controlar los documentos, pero no sé como seleccionar los apartados mencionados y copiar/pegar con sus correspondientes estilos.
He probado con cursores y puedo recorrer todos los títulos del documento, pongamos como ejemplo títulos de tipo "Título 2", buscando un texto de título2 en particular, por lo que deberé copiar desde ese título hasta justo antes de que comience el siguiente título. Pero con dichos cursores solo consigo copiar el texto.
Acudí a este tema del foro: https://forum.openoffice.org/en/forum/v ... hp?t=79540
Con lo que puedo copiar todo el contenido del documento (incluyendo estilos), y pegarlo con [dispatcher.executeDispatch(frame, ".uno:Paste", "", 0, ())]: ver ejemplo inferior
document = XSCRIPTCONTEXT.getDocument()
ctx = uno.getComponentContext()
sm = ctx.ServiceManager
dispatcher = sm.createInstanceWithContext("com.sun.star.frame.DispatchHelper", ctx)
frame = document.CurrentController.Frame
dispatcher.executeDispatch(frame, ".uno:SelectAll", "", 0, ())
dispatcher.executeDispatch(frame, ".uno:Copy", "", 0, ())
dispatcher.executeDispatch(frame, ".uno:GoToEndOfDoc", "", 0, ())
dispatcher.executeDispatch(frame, ".uno:Paste", "", 0, ())
Funciona por lo que parece que la copia con estilos es posible, ¿sabría alguien como podría seleccionar un apartado en concreto y pegarlo?
Aprovecho para preguntar si saben si Mauricio sigue manteniendo ZAZ EasyMacros para Python, la idea es buena, o si alguien conoce otro framework útil.
Lástima que no hay mucha información de macros en python.
Un saludo y gracias de antemano.
OpenOffice 4.1.1 - Windows 8.1 Pro x64
-
- Mensajes: 10
- Registrado: Lun Oct 05, 2015 11:13 am
Re: Python - Copiar apartados de un documento a otro conservando los estilos
Perdón, se me pasó poner correctamente mi configuración:
7.4.7.2 (x64) / LibreOffice Community
Windows 10.0 Build 22621
7.4.7.2 (x64) / LibreOffice Community
Windows 10.0 Build 22621
OpenOffice 4.1.1 - Windows 8.1 Pro x64
Re: Python - Copiar apartados de un documento a otro conservando los estilos
Esta macro copia los primeros cuatro párrafos del archivo adjunto, incluyendo la imagen y los estilos, a un archivo nuevo.
Código: Seleccionar todo
Sub CopyAll
'seleccionar los parrafos
oText = ThisComponent.Text
oObj1 = oText.createTextCursor()
oObj1.gotoEndOfParagraph(True)
oObj1.gotoNextParagraph(True)
oObj1.gotoEndOfParagraph(True)
oObj1.gotoNextParagraph(True)
oObj1.gotoEndOfParagraph(True)
oObj1.gotoNextParagraph(True)
oObj1.gotoEndOfParagraph(True)
oCurrCntrl = ThisComponent.CurrentController
oCurrCntrl.select(oObj1)
'copiar todo
trans= oCurrCntrl.getTransferable()
'abrir un archivo nuevo
oDoc = StarDesktop.loadComponentFromURL( "private:factory/swriter", "_blank", 0, Array() )
'insertar el texto u imagen
oDoc.currentcontroller.insertTransferable(trans)
End Sub
- Adjuntos
-
- HeadingPicture.odt
- (19.33 KiB) Descargado 145 veces
-
- Mensajes: 10
- Registrado: Lun Oct 05, 2015 11:13 am
Re: Python - Copiar apartados de un documento a otro conservando los estilos
Muchas gracias por contestar tan pronto.
En cuanto tenga un momento lo pruebo.
Un saludo.
En cuanto tenga un momento lo pruebo.
Un saludo.
OpenOffice 4.1.1 - Windows 8.1 Pro x64
-
- Mensajes: 10
- Registrado: Lun Oct 05, 2015 11:13 am
Re: Python - Copiar apartados de un documento a otro conservando los estilos
Buenas noches.
Siento no haber contestado antes, he estado bastante liado.
Muchísimas gracias FJCC-ES por el ejemplo. Funciona perfectamente.
He intentado sin éxito migrarlo a Python, utilizando ZAZ EasyMacro, del genio Mauricio Baeza:
Quedando el código: (abro el documento desde donde se copian los párrafos desde una aplicación en PySyde6)
1. Se abre correctamente el fichero de origen.
2. Creo que se copia la selección del cursor.
3. Se crea un documento en blanco, pero no logro que se pegue nada en el nuevo documento.
He intentado seguir las pautas para Python del código de FJCC-ES, pero algo se me está escapando.
Si a alguien se le ocurre algo sería de gran ayuda. O bien si he de hacerlo sin la librería mencionada.
Desde ya muchas gracias a la gente del foro.
P.D: Diossss, que poca información hay sobre Python para Libre Office.
Saludos.
Siento no haber contestado antes, he estado bastante liado.
Muchísimas gracias FJCC-ES por el ejemplo. Funciona perfectamente.
He intentado sin éxito migrarlo a Python, utilizando ZAZ EasyMacro, del genio Mauricio Baeza:
- Documentación: https://git.cuates.net/elmau/zaz/wiki/tools
Quedando el código: (abro el documento desde donde se copian los párrafos desde una aplicación en PySyde6)
Código: Seleccionar todo
import external.easymacro.easymacro as easy
# Abrir fichero de origen
pathFolderDocs = 'C:/temp/test/'
nameFile = 'HeadingPicture.odt'
pathDoc = pathFolderDocs + nameFile
docCurrent = easy.get_document(nameFile)
if docCurrent is None:
easy.msgbox('El documento no está abierto. Se abrirá.')
docCurrent = easy.open_doc(pathDoc)
# Crear selección
cursor = docCurrent.cursor
cursor.gotoEndOfParagraph(True)
cursor.gotoNextParagraph(True)
cursor.gotoEndOfParagraph(True)
cursor.gotoNextParagraph(True)
cursor.gotoEndOfParagraph(True)
cursor.gotoNextParagraph(True)
cursor.gotoEndOfParagraph(True)
oCurrCntrl = docCurrent.obj.CurrentController
selection = docCurrent.obj.CurrentController.Selection
# Crear documento en blanco y pegar el contenido
trans = oCurrCntrl.getTransferable()
dc = easy.new_doc('writer')
dc.obj.CurrentController.insertTransferable(trans)
2. Creo que se copia la selección del cursor.
3. Se crea un documento en blanco, pero no logro que se pegue nada en el nuevo documento.
He intentado seguir las pautas para Python del código de FJCC-ES, pero algo se me está escapando.
Si a alguien se le ocurre algo sería de gran ayuda. O bien si he de hacerlo sin la librería mencionada.
Desde ya muchas gracias a la gente del foro.
P.D: Diossss, que poca información hay sobre Python para Libre Office.
Saludos.
OpenOffice 4.1.1 - Windows 8.1 Pro x64
Re: Python - Copiar apartados de un documento a otro conservando los estilos
Esta macro funciona bien en OpenOffice con el archivo HeadingPicture.odt.
Código: Seleccionar todo
def Copiar4Para():
ctx = XSCRIPTCONTEXT.getComponentContext()
smgr = ctx.ServiceManager
StarDesktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)
ThisComponent = StarDesktop.loadComponentFromURL("file:///C:/Users/fjcc/Desktop/HeadingPicture.odt", "_blank", 0, tuple() )
oText = ThisComponent.Text
oObj1 = oText.createTextCursor()
oObj1.gotoEndOfParagraph(True)
oObj1.gotoNextParagraph(True)
oObj1.gotoEndOfParagraph(True)
oObj1.gotoNextParagraph(True)
oObj1.gotoEndOfParagraph(True)
oObj1.gotoNextParagraph(True)
oObj1.gotoEndOfParagraph(True)
oCurrCntrl = ThisComponent.CurrentController
oCurrCntrl.select(oObj1)
#copiar todo
trans= oCurrCntrl.getTransferable()
#abrir un archivo nuevo
oDoc = StarDesktop.loadComponentFromURL( "private:factory/swriter", "_blank", 0, tuple() )
#insertar el texto u imagen
oDoc.CurrentController.insertTransferable(trans)
-
- Mensajes: 10
- Registrado: Lun Oct 05, 2015 11:13 am
Re: Python - Copiar apartados de un documento a otro conservando los estilos
Buenas.
De nuevo FJCC-ES, muchísimas gracias por tu ayuda, eres un crack. Siguiendo tu código ya funciona:
Mi escenario es el de intentar automatizar la generación/gestión de documentos Libre Office Writer, a partir ciertos apartados que ya se han hecho en su día, y que sirven como plantilla (simplemente copiando y pegando apartados a voluntad). El usuario selecciona los apartados que quiere de una lista y la aplicación genera el documento.
Cada vez que se genere un nuevo apartado, puede añadirse a la mencionada lista.
Es una aplicación PySide6, con un entorno virtual Python 3.11.3, pero se supone que la versión de Libre Office que tengo instalada hace uso de Python 3.8.16.
Si uso directamente las macros desde Libre Office funcionan correctamente, pero si las llamo de la aplicación me da problemas, como por ejemplo el uso de la línea:
ctx = XSCRIPTCONTEXT.getComponentContext()
Que me canta el error: com.sun.star.uno.RuntimeException: Error during invoking function main in module test.py (<class 'NameError'>: name 'XSCRIPTCONTEXT' is not defined
Por eso me decanté por la librería ZAZ EasyMacro, de Mauricio Baeza, que si me funciona sin problemas.
A ratitos iré evoluciinando el código.
Gracias de nuevo y un saludo.
De nuevo FJCC-ES, muchísimas gracias por tu ayuda, eres un crack. Siguiendo tu código ya funciona:
Código: Seleccionar todo
import external.easymacro.easymacro as easy
# Abrir fichero de origen y copiar párrafos
pathDoc = 'C:/temp/test/HeadingPicture.odt'
ThisComponent = easy.open_doc(pathDoc)
oText = ThisComponent.obj.Text
oObj1 = oText.createTextCursor()
oObj1.gotoEndOfParagraph(True)
oObj1.gotoNextParagraph(True)
oObj1.gotoEndOfParagraph(True)
oObj1.gotoNextParagraph(True)
oObj1.gotoEndOfParagraph(True)
oObj1.gotoNextParagraph(True)
oObj1.gotoEndOfParagraph(True)
oCurrCntrl = ThisComponent.obj.CurrentController
oCurrCntrl.select(oObj1)
trans= oCurrCntrl.getTransferable()
# Crear documento en blanco y pegar el contenido
dc = easy.new_doc('writer')
dc.obj.CurrentController.insertTransferable(trans)
Cada vez que se genere un nuevo apartado, puede añadirse a la mencionada lista.
Es una aplicación PySide6, con un entorno virtual Python 3.11.3, pero se supone que la versión de Libre Office que tengo instalada hace uso de Python 3.8.16.
Si uso directamente las macros desde Libre Office funcionan correctamente, pero si las llamo de la aplicación me da problemas, como por ejemplo el uso de la línea:
ctx = XSCRIPTCONTEXT.getComponentContext()
Que me canta el error: com.sun.star.uno.RuntimeException: Error during invoking function main in module test.py (<class 'NameError'>: name 'XSCRIPTCONTEXT' is not defined
Por eso me decanté por la librería ZAZ EasyMacro, de Mauricio Baeza, que si me funciona sin problemas.
A ratitos iré evoluciinando el código.
Gracias de nuevo y un saludo.
OpenOffice 4.1.1 - Windows 8.1 Pro x64