Page 1 of 1

[Solved] Changing Header with Python (?)

Posted: Wed Jul 23, 2014 5:24 pm
by SilvaCarlosG
Hi everyone,
I working with python with 2 pieces of RTF validated content.

I can put the content on body, but I don't know how change the Header programmaticaly by python.


Somebody can help me with this?

Thanks in advance.
Gabriel

Code: Select all

import uno
import unohelper
import string
import sys
import StringIO
import os
from com.sun.star.beans import PropertyValue
from unohelper import Base
from com.sun.star.io import IOException, XOutputStream, XInputStream, XSeekable

currDir = os.path.dirname( os.path.realpath(__file__) )

# Se obtiene el documento por stdin.
input = ""
input_pie = ""
input_nada = ""
input_cuerpo = ""
input_cabecera = ""
comenzo_cuerpo=0


input = ""
for line in sys.stdin:
  input = input + line


paso=1
lista = input.split("SEPARADOR")
for parte in lista:
  if paso==1:
    input_nada = parte
  if paso==2:
    input_cabecera =  input_nada+parte+'}'
  if paso==3:
    input_cuerpo = '{\\rtf1\\ansi\\ansicpg1252\\deff0{\\fonttbl{\\f0\\fswiss\\fcharset0 Calibri;}}{\\*\\generator Msftedit 5.41.21.2509;}'+parte+''

  if paso==4:
    input_pie = parte
  paso=paso+1


input_Stream = StringIO.StringIO(input)

input_nada_Stream = StringIO.StringIO(input_nada)
input_cabecera_Stream = StringIO.StringIO(input_cabecera)
input_cuerpo_Stream = StringIO.StringIO(input_cuerpo)
input_pie_Stream = StringIO.StringIO(input_pie)


#Setup config
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
				"com.sun.star.bridge.UnoUrlResolver", localContext )
ctx = resolver.resolve( "uno:socket,host=127.0.0.1,port=8100;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)

document = desktop.loadComponentFromURL("file://" + currDir + "/plantilla-original.ott", "_blank", 0, ())


text = document.Text
cursor = text.createTextCursor()


class InputStream(unohelper.Base, XInputStream, XSeekable):
    """ Minimal Implementation of XInputStream """
    def __init__(self, inStream):
        self.stream = inStream
        self.stream.seek(0, os.SEEK_END)
        self.size = self.stream.tell()
       
    def readBytes(self, retSeq, nByteCount):
        retSeq = self.stream.read(nByteCount)
        return (len(retSeq), uno.ByteSequence(retSeq))
   
    def readSomeBytes(self, foo, n):
        return self.readBytes(foo, n)

    def skipBytes(self, n):
        self.stream.seek (n, 1)

    def available(self):
        return self.size - self.stream.tell();

    def closeInput(self):
        self.stream.close()

    def seek(self, posn):
        self.stream.seek(int(posn))

    def getPosition(self):
        return long(self.stream.tell())

    def getLength(self):
        return long(self.size)



cursor.gotoHeader(False)

inPropsc = (
    PropertyValue( "FilterName" , 0, "Rich Text Format" , 0 ),
    PropertyValue( "InputStream", 0, InputStream(input_cabecera_Stream), 0)
    )

cursor.insertDocumentFromURL("private:stream", inPropsc)
cursor.gotoEnd(True)


inProps1 = (
    PropertyValue( "FilterName" , 0, "Rich Text Format" , 0 ),
    PropertyValue( "InputStream", 0, InputStream(input_cuerpo_Stream), 0)
    )

cursor.insertDocumentFromURL("private:stream", inProps1)
cursor.gotoEnd(False)



cursor.gotoStart(False)
replace = document.createReplaceDescriptor()
def search(aReplace, _from, _to ):
   aReplace.SearchString = _from
   aReplace.ReplaceString = _to
   document.replaceAll(aReplace)
   return None


class OutputStream( Base, XOutputStream ):
    def __init__( self ):
        self.closed = 0
    def closeOutput(self):
        self.closed = 1
    def writeBytes( self, seq ):
        sys.stdout.write( seq.value )
    def flush( self ):
        pass

filterName = "writer_pdf_Export"

outProps = (
    PropertyValue( "FilterName" , 0, filterName , 0 ),
    PropertyValue( "Overwrite" , 0, True , 0 ),
    PropertyValue( "OutputStream", 0, OutputStream(), 0)
    )
	   
try:
  document.storeToURL("private:stream", outProps)
except IOException, e:
    sys.stderr.write("Error: " + e.Message)

document.dispose()


Re: Changing Header with Python (?)

Posted: Wed Jul 23, 2014 6:13 pm
by John_Ha
Welcome to the forum ... but you have come to the wrong one.

You are probably better searching and posting in OpenOffice Basic, Python, BeanShell, JavaScript

Re: Changing Header with Python (?)

Posted: Wed Jul 23, 2014 7:48 pm
by FJCC
Here is some Python code recorded with MRI to access the header of the Default page style and change the text manually. At the end of the code I created a text cursor which has an insertDocumentFromURL() method in case you want to use that route.

Code: Select all

 oText = oInitialTarget.getText()
obj1 = oText.createTextCursor()
oStyleFamilies = oInitialTarget.getStyleFamilies()
        
obj2 = oStyleFamilies.getByName("PageStyles")
obj3 = obj2.getByName("Standard")
oHeaderText = obj3.HeaderText
        
oHeaderText.setString("New text for header")
obj4 = oHeaderText.createTextCursor()
oInitialTarget is the document itself, as you would get from loadComponentFromURL().

Re: Changing Header with Python (?)

Posted: Wed Jul 23, 2014 8:42 pm
by acknak
[Moved topic]

Re: Changing Header with Python (?)

Posted: Wed Jul 23, 2014 10:56 pm
by SilvaCarlosG
Thanks a lot, it works fine!!!!
now, My question is: How I can set a RTF content ?

Re: Changing Header with Python (?)

Posted: Thu Jul 24, 2014 12:00 am
by Villeroy
SilvaCarlosG wrote:Thanks a lot, it works fine!!!!
now, My question is: How I can set a RTF content ?
You must not use RTF with OpenOffice. ODF is the new RTF.

Re: Changing Header with Python (?)

Posted: Thu Jul 24, 2014 2:28 pm
by SilvaCarlosG
Hi Villeroy, in fact on body I'm using a RTF content, if I plus a valid RTF header and save the content, is a valid RTF file.

The problem that I have is I can't put the RTF content in the header. Thank's a FJCC I could put a string content in header. (Thank's a lot FJCC!)

I'm using the next code for insert the RTF content:

Code: Select all

...
input_cuerpo_Stream = StringIO.StringIO(input_cuerpo)
...
inProps1 = (
    PropertyValue( "FilterName" , 0, "Rich Text Format" , 0 ),
    PropertyValue( "InputStream", 0, InputStream(input_cuerpo_Stream), 0)
    )

cursor.insertDocumentFromURL("private:stream", inProps1)
...
Regards,
Gabriel

Re: Changing Header with Python (?)

Posted: Thu Jul 24, 2014 8:09 pm
by SilvaCarlosG
Plus information:

scenary 1:
when I insert the first document (ODT or OTT file) , this document has a header , and after I put the RTF content on body , and it works.

scenary 2:
when I insert the first document (ODT or OTT file), this document has a header , and after I insert the second document (ODT or OTT file) and after I put the RTF content on body , and it works. Document 1 and 2, both has tag "header" "$MYPERSONALHEADER_HEADERFILE$ and "$MYPERSONALHEADER_BODYFILE$

In scenary 1 an 2, I still haven't found the way for replace the header using a tag called "$MYPERSONALHEADER$" with the RTF content.

I mean, how can I do it programmaticaly?

Re: Changing Header with Python (?)

Posted: Thu Jul 24, 2014 8:20 pm
by Villeroy
This is an ODF suite which supports RTF very poorly. Write your own program to open the file and insert the tags you need.

Re: Changing Header with Python (?)

Posted: Fri Jul 25, 2014 4:38 am
by FJCC
I don't understand how you mean to use the tags you mention, which is just my own ignorance. If you want to insert text from an RTF file into the header of an odt document that uses the Default page style, you can do it like this in OO Basic

Code: Select all

oText = ThisComponent.getText()
obj1 = oText.createTextCursor()
oStyleFamilies = ThisComponent.getStyleFamilies()
       
obj2 = oStyleFamilies.getByName("PageStyles")
obj3 = obj2.getByName("Standard")
oHeaderText = obj3.HeaderText
       
filePath = "c:\users\fjcc\desktop\Header text from RTF.rtf"
fileURL = convertToURL(filePath)
obj4 = oHeaderText.createTextCursor()
obj4.insertDocumentFromURL(fileURL, Array())
The Array() is an empty array. In my test, OpenOffice did not need to receive the FilterName property value in order to open the RTF file. ThisComponent is just Basic's special variable that refers to the document that called the macro. You will need to replace it with your document variable.

Re: Changing Header with Python (?)

Posted: Fri Jul 25, 2014 3:44 pm
by SilvaCarlosG
Thanks FJCC! it works fine, I changed a few lines of code for us purposes, and it works !!!



Code: Select all

# Se utilizara una plantilla de libreoffice, la cual debera tener si o si activado dentro de las propiedades del header autofit en true.
# Format -> Page -> Header -> AutoFit = checked

import uno
import unohelper
import string
import sys
import StringIO
import os
from com.sun.star.beans import PropertyValue
from unohelper import Base
from com.sun.star.io import IOException, XOutputStream, XInputStream, XSeekable

currDir = os.path.dirname( os.path.realpath(__file__) )

# Se obtiene el documento por stdin.
input = ""
input_pie = ""
input_nada = ""
input_cuerpo = ""
input_cabecera = ""
comenzo_cuerpo=0

# Se desglosa el stdin en un unico texto 
input = ""
for line in sys.stdin:
  input = input + line




# El documento provisto debe tener un tag denominado SEPARADOR, el cual nos ayudara a descomponer el texto de entrada en diferentes segmentos.
# Los cuales son input_nada (no utilizado), input_cabecera, input_cuerpo, input_pie. Para poder ser utilizado los segmentos, deben ser RTF validos,
# es decir poder grabar un archivo rtf con el contenido de la variable y ser asi mismo un RTF valido.

paso=1
lista = input.split("SEPARADOR")
for parte in lista:
  if paso==1:
    input_nada = parte
  if paso==2:
    input_cabecera =  '{'+parte+'}'
  if paso==3:
    input_cuerpo = '{\\rtf1\\ansi\\ansicpg1252\\deff0{\\fonttbl{\\f0\\fswiss\\fcharset0 Calibri;}}{\\*\\generator Msftedit 5.41.21.2509;}'+parte+''
  if paso==4:
    input_pie = parte
  paso=paso+1

# convertimos el string a un stream
input_Stream = StringIO.StringIO(input)

input_nada_Stream = StringIO.StringIO(input_nada)
input_cabecera_Stream = StringIO.StringIO(input_cabecera)
input_cuerpo_Stream = StringIO.StringIO(input_cuerpo)
input_pie_Stream = StringIO.StringIO(input_pie)




#Nos conectamos a libreoffice 
localContext = uno.getComponentContext()
resolver = localContext.ServiceManager.createInstanceWithContext(
				"com.sun.star.bridge.UnoUrlResolver", localContext )
ctx = resolver.resolve( "uno:socket,host=127.0.0.1,port=8100;urp;StarOffice.ComponentContext" )
smgr = ctx.ServiceManager
desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop",ctx)

# plantilla-original.ott, es un documento de libreoffice que se encuentra en blanco, para el proposito especifico posee solo encabezado (no requeria el uso de pie). 
document = desktop.loadComponentFromURL("file://" + currDir + "/plantilla-original.ott", "_blank", 0, ())

class InputStream(unohelper.Base, XInputStream, XSeekable):
    """ Minimal Implementation of XInputStream """
    def __init__(self, inStream):
        self.stream = inStream
        self.stream.seek(0, os.SEEK_END)
        self.size = self.stream.tell()
       
    def readBytes(self, retSeq, nByteCount):
        retSeq = self.stream.read(nByteCount)
        return (len(retSeq), uno.ByteSequence(retSeq))
   
    def readSomeBytes(self, foo, n):
        return self.readBytes(foo, n)

    def skipBytes(self, n):
        self.stream.seek (n, 1)

    def available(self):
        return self.size - self.stream.tell();

    def closeInput(self):
        self.stream.close()

    def seek(self, posn):
        self.stream.seek(int(posn))

    def getPosition(self):
        return long(self.stream.tell())

    def getLength(self):
        return long(self.size)


# Insertamos el contenido de input_cabecera_Stream, que es la cabecera en formato RTF.
oText = document.getText()
obj1 = oText.createTextCursor()
oStyleFamilies = document.getStyleFamilies()
        
obj2 = oStyleFamilies.getByName("PageStyles")
obj3 = obj2.getByName("Standard")
oHeaderText = obj3.HeaderText
obj4 = oHeaderText.createTextCursor()

inPropsce = (
    PropertyValue( "FilterName" , 0, "Rich Text Format" , 0 ),
    PropertyValue( "InputStream", 0, InputStream(input_cabecera_Stream), 0)
    )

obj4.insertDocumentFromURL("private:stream", inPropsce)


text = document.Text
cursor = text.createTextCursor()


# Insertamos el cuerpo del documento en formato RTF

inProps1 = (
    PropertyValue( "FilterName" , 0, "Rich Text Format" , 0 ),
    PropertyValue( "InputStream", 0, InputStream(input_cuerpo_Stream), 0)
    )

cursor.insertDocumentFromURL("private:stream", inProps1)
cursor.gotoEnd(False)

class OutputStream( Base, XOutputStream ):
    def __init__( self ):
        self.closed = 0
    def closeOutput(self):
        self.closed = 1
    def writeBytes( self, seq ):
        sys.stdout.write( seq.value )
    def flush( self ):
        pass

filterName = "writer_pdf_Export"

outProps = (
    PropertyValue( "FilterName" , 0, filterName , 0 ),
    PropertyValue( "Overwrite" , 0, True , 0 ),
    PropertyValue( "OutputStream", 0, OutputStream(), 0)
    )
	   
try:
  document.storeToURL("private:stream", outProps)
except IOException, e:
    sys.stderr.write("Error: " + e.Message)

document.dispose()

Regards,
Gabriel