transposar una cel·la

Un “truc” ràpid:

Com passar de
Una cel·la amb a/b/c/d/e
A una cel·la amb
a
b
c
d
e

És dir, com “transposar” una cel·la?

1. OpenOffice.org / LibreOffice
amb aquesta fòrmula: =SUBSTITUEIX(A1;”/”;CARAC(10))

Amb OOoBasic

Sub Transposa()
    Dim s1 As String
    Dim s2 As String

    s1 = ThisComponent.Sheets.getByName(“Full1”).GetCellByPosition(0,0).String
    s2 = Replace(s1, “/”, Chr(10))
    ThisComponent.Sheets.getByName(“Full1”).GetCellByPosition(0,1).String = s2
End Sub

2. Excel
Una fórmula pràcticament idèntica: =SUSTITUIR(A1;”/”;CARACTER(10))

Amb VisualBasic:

Sub Transposa()
    Dim s1 As String
    Dim s2 As String


    s1 = Hoja1.Cells(1, 1)
    s2 = Replace(s1, “/”, Chr(10))
    Hoja1.Cells(2, 1) = s2
End Sub

L’única diferència en el BASIC és la forma d’accedir a les cel·les.

Anuncis

Obrir, reemplaçar, desar i tancar amb OpenOffice.org Basic i amb VisualBasic

Aquesta setmana passada un conegut em va demanar el següent: en un full d’excel tenia, en la primera columna un prefix, i en la segona un nom. Es tractava de, per a cada prefix de la primera columna, fer una copia d’un document word a una carpeta de destinació  donant-li de nom, el prefix corresponent, més una part fixa. A continuació, calia substituir dins del document, un text determinat pel nom respectiu de la segona columna.

De fet, això no és més que la combinació d’un text amb una taula i no és res que no es vingui fent des de temps immemorials. Poc o molt tots els  processadors de text disposen d’una opció de combinació per a fer, per exemple, emailings.

En tot cas el conegut aquest partia d’un full Excel i d’un fitxer Word i no semblava disposat a investigar en els misteris de la combinació de documents. Així que em va demanar si el podia ajudar. Realment, el problema no acabava d’adaptar-se exactament a la  combinació de documents per a correspondència, així que em va semblar que era una bona ocasió per a exercitar-me amb les macros d’Excel i Word.

Doncs bé, vet aquí l’esquema general de la solució que li vaig donar. Vaig fer una macro amb excel. Va ser necessari incloure les referències als documents de MSWord per a poder utilitzar-ne els objectes. El procés general era executar primer la creació dels documents i, a continuació, la substitució.
També hauria pogut fer-ho tot d’una tacada.

Suposarem aquest full excel:

Prefix
Nom
pre1 Substitut 1
pre2 Substitut 2
pre3 Substitut 3
pre4 Substitut 4
pre5 Substitut 5

i el següent doc. word: plantilla.doc

Això és un experiment.
Es tracta de substituir #NOM# per un text que tinc al Calc
I fer-ne un munt de còpies.

A continuació, les macros d’Excel en Visual Basic. Primer de tot, ubico la plantilla.doc a la carpeta C:\fitxers\
També creo la carpeta de destinació C:\fitxers\copies

‘ Generar els fitxers
Sub generarFitxers()
Dim sFitxer As String
Dim i As Integer
Dim fs As Object
Dim sPathBase As String
Dim sPrefix As String


‘ crea un objecte FileSystemObject
Set fs = CreateObject(“Scripting.FileSystemObject”)
sPathBase = “C:\fitxers\”


For i = 3 To 22
sPrefix = Hoja1.Cells(i, 1)
Debug.Print sPrefix
fs.CopyFile sPathBase & “plantilla.doc”, sPathBase & “copies\” & sPrefix & “copia.doc”
Next
End Sub




‘ A cada un dels fitxers generats, fa la substitució de #NOM# pel text de la columna 2
Sub Substitucio1()
Dim sFitxer As String
Dim i As Integer
Dim wrdApp As Word.Application ‘Object
Dim wrdDoc As Word.Document
Dim wrdContent As Word.Range
Dim wrdSelection As Word.Selection
Dim sPathBase As String
Dim sPrefix As String
Dim sSubstitucio As String


sPathBase = “C:\fitxers\”


For i = 3 To 7
sPrefix = Hoja1.Cells(i, 1)
sSubstitucio = Hoja1.Cells(i, 2)
Debug.Print sPrefix
Set wrdApp = New Word.Application
wrdApp.Visible = True
Set wrdDoc = wrdApp.Documents.Open(sPathBase & “copies\” & sPrefix & “copia.doc”)
Set wrdContent = wrdDoc.Content
FindReplace wrdContent, “#NOM#”, sSubstitucio
wrdDoc.Save
Set wrdContent = Nothing
Set wrdDoc = Nothing
wrdApp.Quit
Set wrdApp = Nothing
Next


Debug.Print “fet!”


Set wrdApp = Nothing
End Sub


Sub FindReplace(wrdContent As Word.Range, sOriginal As String, sSubstitut As String)
‘- FIND & REPLACE
wrdContent.Find.ClearFormatting
wrdContent.Find.Replacement.ClearFormatting
With wrdContent.Find
.Text = sOriginal
.Replacement.Text = sSubstitut
.Forward = True
.Wrap = wdFindContinue
.Format = Falsei
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
End With
wrdContent.Find.Execute Replace:=wdReplaceAll
End Sub

Doncs bé, això mateix es pot fer amb OpenOffice.org (o LibreOffice, si ja heu fet el canvi). El plantejament és molt similar. Creo una macro a OpenOffice.org Calc (el full de càlcul) que copiarà un document d’OpenOffice.org Writer a una carpeta de destinació per cada fila de la columna de prefixes. Per a cada copia, l’obrirà, reemplaçarà #NOM# pel valor corresponent de la columna 2, desarà els canvis i tancarà. Vet aquí el codi:

Sub Main
    Dim sPathBase as String


    sPathBase = “/home/albert/fitxers/”


    generarFitxers(sPathBase)
    msgbox “Creats els fitxers”
    Substitucio(sPathBase) d’
    msgbox “Substitució realitzada”
End Sub


‘ genera els fitxers de plantilla
Sub generarFitxers(sPathBase as String )
    Dim sFitxer As String
    Dim i As Integer
    Dim sPrefix As String


    sPrefix = “”


    For i = 2 To 6
        sPrefix = ThisComponent.Sheets.getByName(“Full1”).GetCellByPosition(0,i).String
        if Not FileExists(“file://” & sPathBase & “prova”) then
        MkDir( sPathBase & “prova”)
        end if
        FileCopy sPathBase & “plantilla.odt”, sPathBase & “copies/” & sPrefix & “copia.odt”
    Next


End Sub


‘ A cada un dels fitxers generats, fer una substitució total
Sub Substitucio(sPathBase as String)
    Dim sFitxer As String
    Dim i As Integer
    Dim sPrefix As String
    Dim sNomFitxer as String
    Dim sUrlNomFitxer as String
    Dim sNomNou As String
    Dim docWriter as Object


    For i = 2 To 6
        sPrefix = ThisComponent.Sheets.getByName(“Full1”).GetCellByPosition(0,i).String
        sNomNou = ThisComponent.Sheets.getByName(“Full1”).GetCellByPosition(1,i).String
        sNomFitxer = sPathBase & “prova/” & sPrefix & “copiaplantilla.odt”
        sUrlNomFitxer = convertToUrl(sNomFitxer)
        docWriter = starDeskTop.loadComponentFromUrl (sUrlNomFitxer, “_blank”, 0, Array())
        FindReplace docWriter, “#NOM#”,sNomNou
        docWriter.storeAsURL(sUrlNomFitxer, Array())
        docWriter.Close (True)storeAsURL
    Next
End Sub


‘ cerca i substitueix text
Sub FindReplace(objDoc as Object, sOriginal As String, sSubstitut As String)
    dim objReplace as Object


    objReplace = objDoc.createReplaceDescriptor
    objReplace.SearchRegularExpression = True
    objReplace.SearchString = sOriginal
    objReplace.ReplaceString = sSubstitut


    objDoc.replaceAll(objReplace)
End Sub


Destacaria com en OOoBasic, el tractament de fitxers està incorporat al llenguatge, a diferència del VBA en el que cal invocar un objecte FileSystemObject.
També, el diferent accés a les cel·les en OOoBAsic (GetCellByPosition) i en VBA (Cells).
Molt important: en OOoBasic, degut a que es tracta d’un aplicatiu multiplataforma,  és necessari convertir el nom dels fitxers a una forma d’URL neutral. Això es fa amb ConvertToURL.
La càrrega del fitxer, en OOoBasic es fa amb StarDesktop.LoadComponentFromURL. En canvi, a VBA faig new Word.Application
La cerca i substitució dins del fitxer de text és sensiblement diferent entre  OOoBAsic i VBA.
Finalment, guardar i sortir , en OOoBAsic es fa a partir de mètodes de l’objecte Document (StoreAsURL, per desar, i Close, per tancar. A VBA, en canvi, desar es fa amb un mètode de l’objecdte del document, Save, i sortir, de l’objecte de d’aplicació, Quit.

Com migrar de MSOffice a OpenOffice.org (i 2)

En la darrera blocada presentava el pla general de migració de MS Office (en endavant MSO) a OpenOffice.org (en endavant OOo), segons l’esquema que proposa Sun en els seus WhitePapers (WP).

Fer d’ODF el format per defecte a l’organització 
Seguint la recomanació del WP cal establir la política de que el format per defecte dels documents a partir d’haver completat la migració sigui el nadiu d’OpenOffice.org, és dir, el format ODF (OpenDocument format) que és un format estàndar ISO i que, això és molt important, també està suportat des del Service Pack 2 de  MSO 2007. Per a versions més antigues Oracle-Sun proporciona un plugin ODF que afegeix aquest suport.

ODF és un format adequat, doncs, per a la comunicació amb  empreses externes. Tanmateix, per a organitzacions que no siguin capaces de llegir ODF, l’OOo permet enviar correus amb formats PDF i formats de MSO.

Compartir i convertir documents
Els filtres d’importació i exportació de l’OOo seran suficients per a l’amplia majoria de documents de MSO. L’intercanvi de documents amb usuaris de MSO  funciona normalment sense problemes, ara bé, els documents poden mostrar-se lleugerament diferents després de la conversió. Les macros d’Excel no funcionaran a l’OOo Calc; en general, les macros de Word i d’Excel probablement no funcionaran. Serà necessari un reajustament manual

Les característiques de l’MSO que caldrà vigilar són:

Word: Objectes OLE, índexos.
Excel:  Objectes OLE, Taules pivot, alguns diagrames
Power Point: Objectes OLE, alguns efectes multimèdia

Compartir documents amb usuaris de MSO 2007 (i posteriors)
Les  noves versions de MSO introdueixen característiques noves que no són compatibles amb l’OOo i que, de fet, no són compatibles ni amb versions antigues de MSO.
Per tant cal tenir en compte que la probabilitat de trobar-se amb aquestes característiques quan es comparteixen documents amb usuaris de versions recents de MSO és elevada.

Tanmateix, l’MSO implementa el que es coneix com a mode de compatibilitat que avisa als usuaris de que les característiques noves no estan suportades i els permet desar els documents en els formats de MSO97  o MSO2003.

Desant els documents en aquests formats soluciona molts dels problemes de compatibilitat. Tanmateix el mode de compatibilitat a l’MSO no està activat per defecte.

Escenaris i casos d’estudi


Escenari 1. Migrar tota l’empresa de cop.


Aquest escenari és escaient a PIMES. Una planificació i fites possibles per a la migració podrien ser les següents:

1. Començar a experimentar amb OOo. Encetar  un  programa pilot d’us del l’OOo. Definir un grup d’usuaris que participi en el pilot.

2. Iniciar l’anàlisi dels documents i de l’entorn tecnològic.
2.1 Determinar quins són els documents que necessiten ser convertits, en quin grau. Determinar les dificultats que apareixeran al fer la conversió dels documents.
2.2 Fer servir qüestionaris per a identificar les aplicacions que depenen de, o que proporcionen, interfícies cap l’MSO.

3. Kick Off. Punt de partida oficial del procés de migració. Aquesta fita ve caracteritzada per:
3.1 Instal·lació als clients i els servidors que calguin de l’OOo. OOo i MSO conviuran en  aquests sistemes fins la retirada definitiva de l’MSO.
3.2 Organitzar els empleats en equips i formar-los en l’ús de l’OOo, i en com verificar i corregir les lleugeres diferències que provocarà la conversió de plantilles i documents. La formació haurà de tenir en compte que es treballarà en un entorn mixt

4. Iniciar la conversió del documents pertanyents al negoci i als diferents departaments. En encetar aquest punt l’OOo haurà d’estar instal·lat a tots els ordinadors clau de l’empresa.

5. Iniciar l’auditoria dels documents convertits. En aquest punt els documents ja han estat convertits i els usuaris ja estan formats. Els usuaris han d’estar capacitats per verificar la fidelitat dels documents dels documents convertits. Els usuaris que no estiguin participant directament en el procés de migració poden començar a convertir els seus propis documents

6. Iniciar l’ús de l’OOo per a la creació de nous documents. En aquest punt tots els documents crítics ja han estat convertits, auditats i , si ha estat necessari, corregits. Els usuaris poden crear nous documents en el format nadiu i estàndar ISO, l’OpenDocument Format (ODF) fent servir l’OOo. Des d’aquest moment, el MSO només es farà servir per imprimir o editar documents prèviament existents de MSO.

7. Confirmar la data de caducitat definitiva de l’MSO. En aquest punt, tota l’empresa  i els diferents grups de treball haurien d’haver estat convertits a ODF. Tots els sistemes de missió crítica haurien d’estar funcionant sobre OOo i tots els usuaris haurien de tenir un bon grau de competència i de productivitat amb l’OOo. Tanmateix, es bo recordar als usuaris que l’MSO serà retirat dels seus escriptoris en breu, de forma que tinguin una idea clara de quant temps els resta per a convertir i revisar els seus propis documents si és que encara els cal fer-ho.

8. Retirar l’MSO. En assolir aquesta fita tothom a l’organització fa servir OOo. I la migració dels documents i solucions de negoci ja hauria d’haver estat completada. És el moment de retirar l’MSO de la xarxa de l’empresa i dels escriptoris dels empleats.
Tanmateix, si s’ha incorregut en retards en la conversió o cal fer la re-enginyeria de fitxers de missió crítica, aleshores cal mantenir almenys una instal·lació d’MSO.

Escenari 2. Migració de l’organització per departaments.

Aquest escenari difereix de l’anterior en que les fites són per als diferents departaments i no per a l’organització. La clau és determinar l’ordre en que migren els diferents departaments.:
– Cal minimitzar els reptes que planteja treballar en un entorn mixt.  Començar pels departaments que no els cal intercanviar documents amb altres departaments

–  Continuar amb els departaments que només han de visualitzar o imprimir documents d’altres departaments. Aquests departaments hauran de fer servir els filtres d’importació i conversió per a poder visualitzar els documents de MSO.

– Finalment, migra els departaments que han d’intercanviar informació basada en documents amb altres departaments.

Escenari 3. Entorns mixts  OOo / MSO

Els entorns mixts són aquells en els que coexisteixen OOo i MSO. Ens aquests entorns hi han dues formes principals de compartir documents: la compartició passiva de documents, i la compartició de documents editables.pr

Compartició passiva de documents
En aquest escenari, els documents compartits s’utilitzen per a distribuir informació i no es requereix cap altre acció. Per exemple, els documents es fan servir per distribuir informació als empleats sobre les noves polítiques corporatives. Un altre exemple:  la distribució dels estàndards de condicions contractuals per als clients o per als col·laboradors.

La millor aproximació per a aquest escenari és la distribució dels documents en el format PDF. PDF és fàcil de crear (encara més amb OOo) i és ideal per a catàlegs, cartes, factures i formularis.

Amb l’OOo existeix la possibilitat de descarregar-se l’extensió Sun PDF Import Extension de Sun que permet crear un fitxer híbrid. Aquest plugin permet exportar el document com un fitxer .pdf que conté dos formats de fitxer: PDF i ODF. EL fitxer té l’extensió pdf i és visualitzable amb els visors estàndard de PDF i, a més, pot ser carregat i editat des de l’OOo.

Compartició de documents editables
En aquest escenari els destinataris poden editar els continguts dels documents compartits, per exemple per a proporcionar un feedback, o per afegir continguts abans que els documents passi a terceres parts. El problema més gros d’aquest escenari és que no es poden fer assumpcions sobre la capacitat de llegir documents en format ODF per la tercera part. Majoritàriament, doncs, el format de fitxer comú en un entorn mixt és el format propietari de MSO.

Una aproximació és fer de ODF el format per defecte de l’organització. L’estandarització facilitarà l’intercanvi, el seguiment i el suport als documents. Per a aquesta solució caldrà que els usuaris de MSO disposin d’una instal·lació paralel·la d’OOo, o bé la instal·lació del plugin ODF de MSO. Com s’ha dit anteiorment, el plugin ODF de l’MSO permet obrir, editar i desar en format ODF.

Una altre aproximació és distribuir els documents compartits en format de MSO, especialment si només hi ha un petit percentatge d’usuari treballant amb OOo a l’organització.

Un parell de suggeriments que poden ajudar a millorar la inter-operabilitat en un entorn mixt:
– Fer d’OOo la suite ofimàtica per defecte i ODF el format per defecte en aquells grups on els empleats treballen intensament en col·laboraciço, fins i to encara que  part dels membres del grup no formin part de l’organització. Com s’ha dit, el plugin d’ODF de l’MSO ha permet a aquests usuaris llegir i escriure documents ODF.

– Introduir dues fases en la compartició d’un document. Una fase de col·laboració i una fase d’edició. En la fase de col·laboració un document es comparteix un document inicial entre els diferents usuaris de l’entorn mixt. Per a aquesta fase es pot utilitzar el format que d’MSO o d’ODF, però si es tria ODF aleshores cal desplegar el plugin ODF en les instal·lacions dels usuaris de MSO. La decisió de quin format és el que finalment es tria depèn de la suite dels autors. Si la majoria d’autor del document utilitzen OOo aleshores aquest hauria de ser el format de document utilitzat; si no és així, aleshores hauria de ser el de l’MSO.

Un cas d’estudi
Una gran empresa industrial va migrar el 90% de la seva plantilla a StarOffice (la versió d’OOo de pagament de Sun) mitjançant el seu propi departament d’informàtica. Després de la migració van mantenir  unes poques instal·lacions d’MSO per a permetre al departament de finances de poder seguir fent servir  macros i eines basades  en Excel i per a poder assegurar la compatibilitat amb terceres parts com clients o empreses col·laboradores.

Despres de la migració, el format oficial dels documents és ODF per a documents editables i PDF per distribució de informació en documents només de lectura.

Internament,la majoria dels empleats fan servir ODF. Els empleats que encara fan servir els formats de MSO ho fan perquè pertanyen a equips on la documentació circula en aquest format.

Per a la col·laboració entre equips que fan servir formats diferents, es fa servir el format de MSO. Els equips que treballen amb StarOffice fan servir els filtres d’importació i exportació de l’StarOffice per a convertir els documents.

Per a les comunicacions externes es fa servir el format PDF. Si els destinataris externs han d’editar els documents, aleshores han d’instal·lar-se el plugin d’ODF per a poder editar els documents des de l’MSO.

Sumari
La migració a OOo es pot assolir fàcilment amb una bona planificació, recursos suficients i una bona gestió del projecte. L’estalvi que s’obté de migrar a OOo és substancial: El 100% dels costos de llicències. Sense despeses de manteniment,  ni l’obligació contractual d’adquirir les actualitzacions. Aquesta llibertat i flexibilitat  juntament amb l’estalvi de despesa fa molt interessant iniciar una prova pilot d’avaluació de l’OpenOffice.org.

Documentació i enllaços útils

La documentació Online de l’OpenOffice.org   http://documentation.openoffice.org/

Documentació descarregable:

    Com migrar de MSOffice a OpenOffice.org

    La utilització de programari lliure proporciona avantatges evidents. Sens dubte que la més llaminera és la de no haver de pagar per obtenir les llicències per ús.

    Parlo de llicències d’ús i no de preu de les aplicacions perquè, de fet, no es compren les aplicacions, sinó llicències per a fer-les servir.

    Les llicències d’ús no són pas pocs diners. És un esforç que cal amortitzar. Això porta a que quan es fa una despesa en ofimática, o en aplicacions informàtiques en general, aquell software haurà de ser utilitzat durant un periode de temps prou gran que, al menys, permeti considerar que ha retornat la inversió.

    N’hi ha prou amb fer la despesa inicial? No. És necessari un manteniment. En el millor dels casos, amb la llicència també s’obté el dret a actualitzacions automàtiques.

    Ara bé, el mecanisme d’actualitzacions automàtiques pot no estar sempre present. Pot ser també que la llicència d’ús adquirida no es correspongui amb la utilització que es doni a l’aplicació i que, per tant, no es pugui actualitzar tot el programari. En el límit, es pot estar usant l’aplicació sense llicència; pot ser també que el suport a l’aplicació quedi discontinuat. En definitiva, no és impensable que abans d’hora calgui fer una despesa adicional per a obtenir llicències per a una nova versió i per al seu manteniment.

    El programari lliure senzillament no pateix la servitud de les llicències. En patirà d’altres, per descomptat, i potser la més greu és la dificultat de trobar bons serveis tècnics de manteniment especialitzats en el programari lliure. Tanmateix, aquesta dificultat també es dona amb el programari privatiu.

    Una aposta empresarial intel·ligent és la de tractar de reduir la despesa en llicències i manteniment, pel que té de despesa fixa, però també pel risc que representa de despesa imprevista davant la necessitat de renovar el programari instal·lat.

    Aquesta aposta implicarà en la majoria d’ocasions una migració. De forma general será migrar des d’una plataforma o des d’aplicacions de pagament a una plataforma o aplicacions de programari lliure.

    Aquesta migració total o parcial del sistema d’informació corporatiu és un projecte estratègic en si mateix, i crític degut a que representa canvis en les eines que processen els fluxos de treball i de documents. És necessari garantir que aquests fluxos, si més no, es mantenen i, opcionalment, s’optimitzen. Cal preparar els usuaris per a les noves eines. Cal adaptar la documentació existent als nous formats o assegurar que els formats existents són reconeguts i són útils amb el nou programari.

    La migració completa del sistema d’informació corporatiu a programari lliure es pot plantejar com un projecte per fases. Un enfocament posible és plantejar projectes de migració específics per als diferents servidors i aplicacions corporatius: d’intranet, de base de dades, d’ERP, de CRM, d’Intel·ligència de Negoci. I també dels clients d’aquests servidors: l’escriptori dels usuaris, o l’ofimàtica corporativa.

    Em concentraré en aquest últim punt: la migració de l’ofimàtica corporativa.

    L’ofimàtica corporativa basada en programari lliure té un nom estrella: OpenOffice.org (en endavant OOo). Al seu torn, l’ofimàtica corporativa de pagament té un nom indiscutible: Microsoft Office (en endavant MSO).

    Hi han altres opcions d’ofimàtica lliure, en escriptoris Linux basats en KDE es pot trobar el KOffice. En escriptoris del tipus Gnome, es diposa del Gnome Office que és un mix de diverses aplicacions com Abiword (processador de textos), GNUMeric (full de càlcul), Thunderbird (client de correu)…

    Però OOo és una opció molt interessant perquè és una suite ofimática completa que és disponible tant en plataformes Windows com en Linux. La migració de MSO a OOo és posible, doncs, sense necessitat de canviar de sistema operatiu. La tria de OOo permet fer un canvi gradual i introduir el programari lliure en un lloc tan visible, i a l’hora, tan crític, com és l’escriptori dels usuaris. La introducció del programari i formats lliures en l’escriptori facilitaran el canvi a la implantació de sistemes operatius lliures en els clients.

    L’escenari que es planteja és, doncs la migració de l’ofimàtica del client de MSO a OOo.

    Sun (actualment propietat d’Oracle) ha elaborat diversos White Papers (en endavant WP) en el que proposa una metodologia i diferents escenaris per a projectes de migració de MSO a OOo (o a Oracle OpenOffice, l’antic StarOffice, la versió de pagamanet d’OOo propietat de Sun; i cal pensar que el model que plantegen també servirá per al IBM Lotus Symphony, la suite ofimática basada en l’OOo realitzada per IBM i que recupera el nom d’una suite ofimàtica per MSDOS que va ser  popular als 80).

    A continuació em referiré a la metodología descrita en aquests WP.

    Com ja he dit abans, l’ofimàtica de l’usuari és una part fonamental i integrada en els fluxos de treball corporatius de cada dia de la majoria dels treballadors. Per tant, és crític planificar i executar la migració de forma rigurosa.

    El WP de SUN proposa sis fases per a la migració:

    1. Implementació d’una fase pilot

    2. Elaboració d’un catàleg de les eines i solucions que depenen del MSO

    3. Identificació dels documents i les macros d’MSO que s’estiguin utilitzant

    4. Organització de l’equip de migració

    5. Conversió de macros, plantilles i documents crítics dels fluxos de treball

    6. Formació i suport post-migració

    1. Implementació d’una fase pilot

    L’objectiu d’aquesta fase és identificar els problemes que podrien afectar a la migració i que es comprenen els fluxos de treball i els intercanvis de documents.

    Per a aquesta fase és necessària la participación d’empleats que siguin representatius funcionalment, amb la preparació adequada per a les tasques i que permetin abastar la major part o, millor, a tots els fluxos de treball.

    Aquests usuaris hauran de tenir formació en l’OpenOffice.org o, si més no, disposar del suport de companys formats o d’un helpdesk.

    Pot ser interessant comptar amb la col·laboració estratégica d’un “Migration Partner” per a prestar aquest support.

    El HelpDesk haurà de prestar suport en qüestions del tipus “Com es fa?”. Cal reportar el errors i els problemes per a poder analitzar-los posteriorment.

    Una segona aproximació és prestar aquest suport via correu electrònic.

    Per a grans corporacions es pot aprofitar el pilot per a implementar una eina de gestió de HelpDesk, obviament de programari lliure i, preferiblement, amb interfase web, de forma que els mateixos usuaris puguin crear des dels seus navegadors els tickets de les incidències. Aquesta mena d’eines permeten fer un seguiment de la resolució de les incidències trobades i se’n poden obtenir informes i estadístiques.

    2. Elaboració d’un catàleg de les eines i solucions que depenen del MSO
    Hi han diversos tipus d’aplicacions ERP, CRM i d’altres que depenen o proporcionen interfícies amb l’MSO. Aquestes aplicacions han de ser identificades aviat perquè cal preveure que serà on caldrà posar més esforç per a fer-les treballar amb l’OpenOffice.org.

    Els caps d’equip i els gestors de la informàtica corporativa necessiten disposar d’aquesta informació, per tant, és una bona idea demanar-se-la mitjançant qüestionaris. Els qüestionaris poden proporcionar una bona explicació sobre com estan interaccionant aquestes aplicacions personalitzades amb l’MSO.

    3. Identificació dels documents i les macros d’MSO que s’estiguin utilitzant
    Cal demanar als usuaris que, per una banda, identifiquin els arxius que són importants per al seu treball i, per l’altra, que identifiquin els arxius que ja no es fan servir.

    Cal assegurar que tothom fa servir els mateixos criteris per distingir el que es fa servir del que no es fa servir, per això caldrà proporcionar aquests criteris als usuaris:

    Arxius que es fan servir: són aquells documents o plantilles que es modifiquen o s’apliquen almenys un cop al mes.
    Arxius que no es fan servir: els arxius, documents o plantilles que no es fan servir aleshores es poden classificar com arxivat definitiu, que serien tots aquells que ni es fan servir ni es faran servir en el futur; o com històric que serien aquells fitxers que ocasionalment es poden haver d’imprimir o consultar.
    Una solució per a aquests fitxers és algun sistema d’emmagatzematge massiu extern (per distingir-lo de l’emmagatzematge online que seria tenir-los al disc dur.) com podria ser DVD. També es pot plantejar una sol·lució d’escanejat a PDF per a poder-los guardar en un format accessible en el futur.

    Els documents que més probablement caldrà arxivar seran la correspondència, factures, calendaris i planificacions, informes de diferents tipus i documents legals. Els documents que tinguin validesa legal no han de ser convertits, doncs, en principi, perdrien la seva validesa si es canvia el seu format.
    En l’emmagatzematge de la informació històrica, si s’escau caldrà tenir en compte a Llei Orgànica de Protecció de Dades (LORTAD) .

    A més caldrà identificar aquells arxius que es comparteixen entre departaments dins de l’empresa o amb empreses externes que també facin servir l’MSO. Els fitxers compartits que incloguin macros hauran de ser rigorosament monitoritzats per tal de controlar-ne els canvis  que pateixin a mida que es van movent entre  els diferents ambients del negoci.

    4. Organització de l’equip de migració
    La dimensió i perfils de l’equip de migració variaran depenent de la mida i estructura de l’organització a migrar. El rol principal és el del gestor de projecte, que preferiblement hauria de ser un perfil sènior del departament d’informàtica.

    El gestor de projecte ha de preveure l’entorn post-migració, incloent les adaptacions que calguin per a estabilitzar el funcionament global, tenint en compte  als objectius de la corporació, les necessitats dels empleats i la disponibilitat de recursos.

    La substitució de  l’MSO per l’OOo no és directa, perquè es tracta d’eines diferents. Cal preveure que hi hauran fluxos de treball que caldrà modificar, compensar o adaptar a la nova eina.
    El gestor de projecte també determinarà l’abast de la migració a partir de la informació sobre els entorns i els documents  recopilada pel seu equip.

    A partir d’aquesta informació, el gestor de projecte determinarà un marc temporal (una planificació d’alt nivell) per a la conversió dels documents i solucions personalitzades i una data límit de finalització de l’utilització de l’MSO en la companyia.

    L’equip de migració podria incloure també administradors de sistemes i altres personal com facilitadors, desenvolupadors o administratius.

    Els administradors de sistemes haurien de ser els responsables de configurar i fer el manteniment dels esquemes  de configuració de l’OOo en l’escenari post-migració.

    Els tècnics informàtics, adequadament formats, serien els responsables de prestar el suport als usuaris després de la migració. És importants, doncs caldrà prestar algun suport als usuaris per a que esdevinguin productius ràpidament.

    Els caps de projecte hauran de gestionar les tasques de migració en els nivells de departaments corporatius. Aquestes tasques de migració inclouen la documentació dels sistemes informàtics departamentals, la identificació de l’efecte de la migració en els workflows d’usuari i de negoci, com impacta la migració en arxius  i en dades, i la comunicació i coordinació amb les diferents parts interessades en el procés de migració.

    5. Conversió de macros, plantilles i documents crítics dels fluxos de treball
    La forma més senzilla de convertir els fitxers Word, Excel i PowerPoint a fitxers en format OpenDocument és fer servir el mateix OOo per obrir-los i desar-los en el nou format.

    Una opció és desenvolupar macros que facin això mateix: obrir (importar) successivament els fitxers d’una carpeta i anar-los desant en el format OpenDocumet corresponent.

    Per descomptat que s’imposa una revisió manual per part dels propietaris dels fitxers per tal de verificar-ne la validesa de la transformació.

    Les macros de MSO no es poden executar directament en OOo perquè els models d’objectes dels documents són del tot diferents. Cal preveure, doncs una tasca de transformació manual de les macros.
    Aquesta tasca pot ser una bona oportunitat per a millorar l’eficiència dels processos que les involucren. POt ser un bon moment per a determinar, per exemple, quines són les macros que encara són necessàries i descartar-ne les que ja no ho siguin. També pot ser el moment per a fer una re-enginyeria de les macros existents per a reconvertir-les en objectes de negoci Java o C++ implementats com components UNO (Universal Network Objects, la tecnologia de components subjacent a OOo). Els nous components seran més eficients que les macros en Visual Basic.

    Una altre aproximació possible seria reconvertir-les per usar aplicacions basades en web i en java de servidor. Els components de servidor proporcionaran més seguretat en temps d’execució i millor gestió d’errors que les corresponents macros originals en Visual Basic.

    6. Formació i suport post-migració
    Els usuaris es trobaran amb una experiència d’usuari diferent a la que estaven acostumats. Trobaran els documents transformats i macros diferents. Per tot això, el pla de migració necessàriament a d’incloure un període de formació que ajudi als usuaris a sentir-se còmodes amb la seva nova suite ofimàtica.
    Per exemple, es podria mostrar als usuaris la forma de solucionar problemes típics després d’haver convertit un document al nou format OpenDocument.

    La formació ha de familiaritzar als usuaris amb la nova interfície d’usuari  i  seran capaços de dominar ràpidament  la seva nova eina.

    per tal de minimitzar el nombre peticions de suport i maximitzar la productivitat des d’un bon començament, és recomanable preparar un “Welcome Pack” pels usuaris amb informació sobre el nou entorn d’escriptori. Aquest “Welcome Pack” podria incloure una guia ràpida d’usuari que destaqui les semblances i les diferències entre MSO i OOo. També es podria incloure un manual de programació del llenguatge Basic de l’OpenOffice.org que estaria destinat als usuaris que vulguin crear les seves pròpies macros.

    A més, pot ser adequat fer una formació de més alt nivell per a usuaris avançats.

    De cara facilitar aquesta etapa de la migració caldria determinar prèviament el nivell dels usuaris (basic, mig,  avançat…)  aleshores es pot  fer una llista dels empleats amb més nivell que poden prestar suport als usuaris menys avançats que requereixin suport.

    Finalment, una darrera opció és fer una formació online. La formació online, amb una etapa tutoritzada i suport per xat, pot significar una reducció del cost de formació al no requerir desplaçaments de persones ni sales de formació condicionades i és més flexible per a l’usuari que pot realitzar els cursos en els horaris que més li convinguin.

    Migració de solucions basades en MSO
    Una suite ofimàtica sovint agrega informació provinent de fons diverses. Aquestes fonts són, en la majoria d’ocasions,  altres aplicacions que proporcionen dades que s’afegeixen als documents. MSO proporciona un conjunt de protocols de comunicació per al diàleg amb aquestes aplicacions externes. OOo, per la seva banda, suporta aquests  protocols de comunicació, però la diferència entre els models d’objectes de documentes de MSO i OOo fan que la comunicació entre OOo i les aplicacions externes, a priori, no sigui compatible amb la de MSO.

    El primer pas és determinar com les diferents aplicacions externes intercanvien la informació amb MSO. Hi han tres mètodes principals:

    El més senzill, fent servir fitxers i documents. Aquesta solució crea documents o fitxers de MSO que poden ser carregats per l’MSO. En principi, això ha de continuar funcionant correctament un cop migrat a OOo, perquè OOo és capaç d’importar els formats de MSO.

    El segon mètode és fer servir el porta papers per a intercanviar informació entre l’aplicació externa i MSO. Aquesta opció també hauria de funcionar correctament amb l’OOo.

    El tercer mètode és quan l’aplicació externa invoca directament el model d’objectes de l’OpenOffice (el mecanisme d’automatització de MSO). Això ni funciona amb OOo.

    Tanmateix encara es pot fer alguna cosa. Cal distingir entre interfases fetes a ma entre les aplicacions externes i l’MSO i les aplicacions que “out of the box” ja proporcionen la interfase amb MSO.

    En el cas de les aplicacions amb interfase MSO “out of the box” les opcions de migració depenen de la compatibilitat de la solució amb OOo.

    En cas de no disposar d’aquesta compatibilitat cal considerar la realització d’un desenvolupament a mida. Ara bé, és millor no reinventar la roda:

    Primer de tot, cal demanar al proveïdor de l’aplicació si tenen prevista una versió compatible amb OOo, o si en podria desenvolupar una per al nostre cas. Suposant que el proveïdor ens respon afirmativament a alguna de les qüestions, cal preveure que la versió compatible no serà immediata i que caldrà proporcionar una solució de contingència: per exemple, pot caldre disposar d’una o més instàncies de MSO fins que la versió compatible amb OOo estigui disponible.

    Pot resultar que el proveidor no estigui disposat a col·laborar i aleshores serà necessari trobar solucions alternatives. Les solucions alternatives  podrien ser desenvolupar una solució  a mida des de zero, o canviar l’aplicació externa per una de competidora que sí que sigui compatible amb OOo.

    Migració de bases de dades Access
    OOo Base és l’aplicació de base de dades de la suite ofimàtica OOo . OOoBase proporciona assistents per a la creació de taules, consultes, formularis i informes.
    BAse treballa amb un motor java de base de dades del tipys HyperSonic DataBase Engine, ara bé, OOoBase és capaç de llegir i escriure dades des de MySQL, base de dades JDBC, connexions ODBC (a UNIX també fent servir ODBCUnix), MSAccess, fitxers de text csv, llegeix fulls de càlcul excel, dBase…)
    Ara bé, OOo Base no és capaç de reconèixer  els formularis, informes i consultes de MSAccess.
    La migració d’aplicacions basades en formularis, informes i consultes de MSAccess és també un bon moment per a la reenginyeria  i decidir si es migra cap a una solució basada en OOoBase i components UNO, o bé si es marxa cap a una solució basada en web.

    Migració de l’Outlook
    OOo reconeix l’Outlook com a client de correu per defecte. En general, per tant, no caldrà migrar de client de correu. Tanmateix pot ser interessant migrar d’Outlook a un altre client de correu basat en programari lliure perquè, per exemple, es vol canviar el  sistema operatiu d’escriptori de Windows a Linux. I no es disposa d’Outlook a Linux.

    En aquest cas, una bona opció es migrar a Mozilla Thunderbird. Mozilla Thunderbird és el client de correu de programari lliure més popular i està basat en el mateix framework del navegador Firefox. Existeixen versions en plataformes Windows i Linux i està disponible en molts llenguatges, en particular, també en català.

    Thunderbird diposa d’un assistent d’importació de comptes des d’outlook express que pot fer senzilla la migració. Migrar Thunderbird de Windows a Linux és tan senzill com copiar la carpeta de configuració de l’usuari, que conté les definicions dels comptes, les carpetes i  las mailboxes amb els correus enviats i rebuts.

    Finalment, Mozilla Lightning és una extensió de Mozilla Thunderbird que li afegeix calendari amb vista diària, setmanal i mensual. Lightning també és programari lliure.

    L’enregistrador de macros de l’OpenOffice.org

    Aquest article està basat en http://wiki.services.openoffice.org/wiki/The_OpenOffice.org_recorder_and_UNO_dispatch_calls

    Des del punt de vista d’un desenvolupador, fer una macro és “escriure” una macro, o programar una macro.

    Tanmateix, des del punt de vista de l’usuari, una macro es pot fer de forma molt senzilla sense més que enregistrar-la:  Eines – Macros – Enregistra una macro. Amb aquesta eina l’OpenOffice.org guarda la sequència d’accions que realitzem a la interfase de l’aplicació fins que li en diem que aturi l’enregistrament, moment en que ens demana que li donem un nom  a la macro.

    Doncs bé, la macro es guarda com una seqüència d’accions d’OpenOffice.org Basic.

    Ara bé, el codi que trobarem potser ens sorprendrà. Es tractarà d’una seqüència comandes UNO, és dir, d’invocacions a URL de tipus UNO mitjançant el servei DispatchHelper. Bàsicament carregarà un array de paràmetres i invocarà la URL que correspongui passant-li l’array.

    En general, a cada acció que es pot realitzar des de la interfase de l’aplicació, ja sigui per menú o per barra d’eines, li correspon una URL UNO del tipus “.uno:AccioDeLaInterfase”

    En aquest punt, el desenvolupador pot tornar a entrar en acció. És un exercici interessant analitzar les macros en Basic que ha generat automàticament l’OpenOffice.org.

    Per exemple, poso el següent text de prova al Writer:

    “A continuació escric un petit text de prova
    Ara formataré el text de diverses formes.
    El que faré serà enregistrar una macro per veure com es fa l’acció amb OooBasic
    D’aquesta forma el mateix OpenOffice.org em fa de “mestre” de programació.
    Som-hi”
    Comencem, busco “text” i el reemplaço per “escrit”.
    Això es tradueix en aquesta macro:
    sub Replace
    rem ———————————————————————-
    rem define variables
    dim document   as object
    dim dispatchersub Replace
    rem ———————————————————————-
    rem define variables
    dim document   as object
    dim dispatcher as object
    rem ———————————————————————-
    rem get access to the document
    document   = ThisComponent.CurrentController.Frame
    dispatcher = createUnoService(“com.sun.star.frame.DispatchHelper”)
    rem ———————————————————————-
    dim args1(18) as new com.sun.star.beans.PropertyValue
    args1(0).Name = “SearchItem.StyleFamily”
    args1(0).Value = 2
    args1(1).Name = “SearchItem.CellType”
    args1(1).Value = 0
    args1(2).Name = “SearchItem.RowDirection”
    args1(2).Value = true
    args1(3).Name = “SearchItem.AllTables”
    args1(3).Value = false
    args1(4).Name = “SearchItem.Backward”
    args1(4).Value = false
    args1(5).Name = “SearchItem.Pattern”
    args1(5).Value = false
    args1(6).Name = “SearchItem.Content”
    args1(6).Value = false
    args1(7).Name = “SearchItem.AsianOptions”
    args1(7).Value = false
    args1(8).Name = “SearchItem.AlgorithmType”
    args1(8).Value = 0
    args1(9).Name = “SearchItem.SearchFlags”
    args1(9).Value = 65536
    args1(10).Name = “SearchItem.SearchString”
    args1(10).Value = “text”
    args1(11).Name = “SearchItem.ReplaceString”
    args1(11).Value = “escrit”
    args1(12).Name = “SearchItem.Locale”
    args1(12).Value = 255
    args1(13).Name = “SearchItem.ChangedChars”
    args1(13).Value = 2
    args1(14).Name = “SearchItem.DeletedChars”
    args1(14).Value = 2
    args1(15).Name = “SearchItem.InsertedChars”
    args1(15).Value = 2
    args1(16).Name = “SearchItem.TransliterateFlags”
    args1(16).Value = 1280
    args1(17).Name = “SearchItem.Command”
    args1(17).Value = 3
    args1(18).Name = “Quiet”
    args1(18).Value = true
    dispatcher.executeDispatch(document, “.uno:ExecuteSearch”, “”, 0, args1())
    end sub

    Ja es veu que aquesta aproximació no és tan eficient com invocar els objectes i els components del document mitjançant la API de UNO, però pot ser útil en algunes ocasions. El que caldria fer és provar les diferents comandes a veure com les enregistra el gravador de macros.

    La llista de comandes és prou llarga. Una llista de les comandes UNO la podem trobar en aquest enllaç.

    Com executar una macro de l’OpenOffice des d’una shell

    Aquest és un truc que obre un ampli ventall de possibilitats.  Per a més info. mireu aquest fil del fòrum de l’OpenOffice.org.

    Per a invocar una macro de l’openOffice.org, n’hi ha prou amb indicar el mètode de macro que vull executar amb una URL del tipus macro.

    Per exemple, per obrir el wrapper del tesseract OCR del post anterior.

    soffice macro:///tesseract.Module1.ObrirDialeg

    Si la macro estigués en un document, caldria indicar el document

    soffice document  macro:///mètode


    Es poden passar paràmetres a la macro:

    Suposem el mètode Concatena al Module1 de la llibreria Standard,

    Sub Concatena(sVar1 as String, sVar2 as String)
        MsgBox sVar1 & ” + ” sVar2
    end sub

    Aleshores el podria invocar com:


    soffice “macro:///Standard.Module1.Concatena(\”hola\”,\”adeu\”)”


    El resultat és l’esperat:

    Per evitar trobar-se amb un munt d’instàncies de l’OpenOffice.org obertes i consumint recursos, és una bona precaució que les macros que soguin invocades des de la línia d’ordres tanquin explícitament el document des del que és invocat, si cal,  i també la instància de l’OpenOffice.org. Això es pot aconseguir amb aquest codi:

    thisComponent.close(true)   ‘ tanca el document
    Stardesktop.terminate()    ‘ tanca l’OOo

    Desplegament de llibreries de macros a l’OpenOffice.org amb un add-on

    Una opció per a fer el desplegament “professional” de llibreries, components o extensions per a l’OpenOffice.org són els add-on. Esl add-on són extensions a l’OOo que presenten algun tipus d’integració amb la interfase d’usuari de l’OOo, per exemple menús o barra d’eines.

    Per a explicar aquest mecanisme, desenvoluparé un wrapper per a l’aplicació de consola tesseract-ocr amb OOobasic i el desplegaré com un add-on.

    Tesseract-ocr és un (antic però eficient) motor d’OCR (reconeixement òptic de caràcters) desenvolupat inicialment per HP i que actualment és mantingut per Google.

    Primer de tot, per tant, cal instal·lar el tesseract-ocr. En Ubuntu Lucid Lynx es pot fer des del “Centre de Programari de l’Ubuntu” i s’obté la versió 2, i s’hi poden afegir els idiomes anglès i castellà. A Windows, es pot descarregar la versió 3 des de la mateixa web de Tesseract-ocr. En la versió 3, a més del castellà i l’anglès, també es pot afegir el català.

    El cas és que Tesseract-ocr és una aplicació de consola a la que cal passar-li arguments per a fer-lo treballar.

    albert@atenea:~$ tesseract
    tesseract:Error:Usage:tesseract imagename outputbase [-l lang] [configfile [[+|-]varfile]…]

    Per a facilitar l’ús del tesseract, doncs, faré una UI que permeti construir la invocació de línia d’ordres del tesseract i l’executaré en una shell. Com que el que es pretén és obtenir un text a partir d’una imatge per a treballar amb ell, sembla que una bona idea és crear un menú nou “OCR” al Writer de l’OpenOffice.org que en fer-hi click ens obri una GUI que analitzi la imatge i que un cop obtingut el text, l’importi al processador de texts.

    A més, per a facilitar-ne la distribució, el que faré serà empaquetar la macro i el diàleg en un .oxt, un add-on, de forma que per a instal·lar-lo n’hi haurà prou amb obrir el fitxer .oxt amb l’OpenOffice.org Writer (o també directament amb la utilitat unopkg, o amb el gestor d’extensions).

    Dit i fet. A “Les meves macros”, creo una llibreria que anomeno “tesseract” i en el “Module1” hi afegeixo el següent codi.

    REM ***** BASIC *****
    REM basat en codi de http://www.oooforum.org/forum/viewtopic.phtml?t=9797


    Dim sCarpeta as String
    Dim sCarpetaImatges as String
    Dim sImatge as String
    Dim sNomFitxerText as String
    Dim oDialeg1 as Object


    ‘ util per a depuració
    sub main
    ObrirDialeg
    end sub


    function EsLinux as Boolean
    Dim sHome
    EsLinux = false
    sHome = Environ(“HOME”)
    if left(sHome,1) = “/” then
    EsLinux = true
    end if
    end function


    ‘ aquest és el mètode que cal invocar des del menú
    Sub ObrirDialeg
    ‘ carrega la llibraria de diàlegs estandard
    GlobalScope.DialogLibraries.LoadLibrary(“tesseract”)


    ‘ carrega el Diàleg “Dialog1”
    oDialeg1 = CreateUnoDialog(DialogLibraries.tesseract.TesseractWrapperDialog)
    oDialeg1.Execute()
    end sub


    ‘ tria la carpeta on guardarà el text obtingut
    ‘ fent servir un diàleg del tipus FolderPicker
    Sub TriaCarpeta( )
    Dim oFolderPickerDlg as Object
    Dim sCarpetaTriada as String


    ‘ carrega el diàleg
    oFolderPickerDlg = createUnoService( “com.sun.star.ui.dialogs.FolderPicker” )


    ‘ estableix valors inicials si els té
    If Len( sCarpeta ) > 0 Then
    oFolderPickerDlg.setDisplayDirectory( ConvertToURL( sCarpeta ) )
    EndIf


    ‘ executa el diàleg
    oFolderPickerDlg.execute()


    ‘ guarda el valor
    sCarpeta = ConvertFromURL(oFolderPickerDlg.getDirectory())


    oDialeg1.getControl(“txtCarpeta”).text = sCarpeta
    End sub


    ‘ tria la imatge a analitzar fent servir un diàleg del tipus FilePicker
    Sub TriaImatge()
    Dim oFilePickerDlg as Object
    Dim sFitxers() as String


    ‘ XRayTool és una eina imprescindible per al desenvolupador d’OOo!!!
    ‘ GlobalScope.BasicLibraries.loadLibrary(“XrayTool”)


    ‘ carrega paràmetres incials al diàleg
    oFilePickerDlg = createUnoService( “com.sun.star.ui.dTriaImatgeialogs.FilePicker” )
    oFilePickerDlg.setMultiSelectionMode( False )


    If Len( sCarpetaImatges ) > 0 Then
    oFilePickerDlg.setDisplayDirectory( ConvertToURL( sCarpetaImatges ) )
    End If


    If Len( sImatge ) > 0 Then
    oFilePickerDlg.setDefaultName( sImatge )
    End If


    ‘ executa el diàleg
    oFilePickerDlg.execute()


    ‘ obté la carpeta d’imatges
    sCarpetaImatges = ConvertFromURL(oFilePickerDlg.getDisplayDirectory())


    ‘ obté la imatge triada
    sFitxers = oFilePickerDlg.getFiles()
    If UBound( sFitxers ) – LBound( sFitxers ) + 1 > 0 Then
    sImatge = ConvertFromURL( sFitxers(0) )
    Else
    sImatge = “”
    EndIf


    ‘ ajusta el camp de text
    oDialeg1.getControl(“txtImatge”).text = sImatge
    end sub


    ‘ Fa l’anàlisi OCR
    Sub OCR
    Dim sParametres as String
    Dim sFitxerSortida as String


    ‘ obtè els paràmetres des dels camps de text
    ‘ per si l’usuari els ha modificat a ma
    sNomFitxerText = oDialeg1.getControl(“txtFitxerText”).text
    sImatge = oDialeg1.getControl(“txtImatge”).text
    sCarpeta = oDialeg1.getControl(“txtCarpeta”).text


    ‘ missatge indicant el que va a fer
    msgbox “Va a analitzar la imatge ” & sImatge & ” de la carpeta ” & chr(13) & chr(10) & _
    “i guardarà l’anàlisi a ” & sCarpeta & ” en el fitxer ” & sNomFitxerText


    ‘ de l’OpenOffice.org Wiki:
    ‘ Shell(Pathname, Windowstyle, Param, bSync) de la Wiki OooBasic RTL d’OpenOffice
    ‘ Pathname
    ‘ the path of the program to be executed.


    ‘ In MS-Windows, use ConvertToURL(Pathname) otherwise the command will not work
    ‘ if Pathname contains spaces or national characters.

    ‘ Windowstyle
    ‘ the window in which the program is started.
    ‘ The following values are possible:

    ‘ * 0 – program receives the focus and is started in a concealed window.
    ‘ * 1 – program receives the focus and is started in a normal-sized window.
    ‘ * 2 – program receives the focus and is started in a minimized window.
    ‘ * 3 – program receives the focus and is started in a maximized window.
    ‘ * 4 – program is started in a normal-sized window, without receiving the focus.
    ‘ * 6 – program is started in a minimized window, the focus remains in the current window.
    ‘ * 10 – program is started in full screen mode.

    ‘ Param
    ‘ command line parameters to be transferred to the program to be started.

    ‘ bSync
    ‘ wait for shell command to finish flag

    ‘ * true – wait for shell command to finish
    ‘ * false – don’t wait for shell command to finish


    ‘ Tesseract
    ‘ Usage:tesseract imagename outputbase [-l lang] [configfile [[+|-]varfile]…]


    ‘ posa els paràmetres corresponents a paths de fitxers entre cometes
    ‘ una millora seria afegir el llenguatge de l’anàlisi
    ‘ ara només considera el castellà (paràmetre -l spa)
    sFitxerSortida = chr(34) & sCarpeta & “/” & sNomFitxerText & chr(34)
    sParametres = chr(34) & sImatge & chr(34) & ” ” & sFitxerSortida & ” -l spa”


    ‘ depenent de si és Linux o Windows invoca per una banda o altre
    ‘ en el cas de windows, cal que tesseract.exe estigui instal·lat
    ‘ a la carpeta c:\tesseract-ocr
    if EsLinux() then
    Shell(“/usr/bin/tesseract”, 6, sParametres, true)
    else
    Shell(“c:\tesseract-ocr\tesseract.exe”, 6, sParametres, true)
    end if


    ‘ cal concatenar el .txt
    If FileExists(sCarpeta & “/” & sNomFitxerText & “.txt”) Then
    MsgBox(“Fet”)
    ‘ importa el fitxer
    ImportaFitxer(sCarpeta & “/” & sNomFitxerText & “.txt”)
    else
    MsgBox(“No s’ha generat el fitxer de sortida”)
    End If
    End Sub


    ‘ El fitxer generat és text pla amb encoding UTF8
    ‘ per tant, cal activar aquest filtre d’importació
    sub ImportaFitxer(sFitxerSortida as String)
    Dim oMediaDescriptor(1) as new com.sun.star.beans.PropertyValue
    sFileUrl = convertToUrl(sFitxerSortida)
    oMediaDescriptor(0).name = “FilterName”
    oMediaDescriptor(0).value = “Text (encoded)”
    oMediaDescriptor(1).name = “FilterOptions”
    oMediaDescriptor(1).value = “UTF8”
    oDoc = StarDesktop.loadComponentFromURL(sFileURL, “_blank”, 0, oMediaDescriptor)
    end sub


    ‘ tanca el diàleg
    Sub Sortir
    oDialeg1.endExecute()
    End sub

    La interfase gràfica serà el següent formulari. faig un nou diàleg dins de la llibreria tesseract, i l’anomeno TesseractWrapperDialog.

    De dalt a baix, els camps de text els anomeno: txtImatge, txtCarpeta i txtFitxerText

    I associo els botons als procediments de la macro:

    Botó “imatge a analitzar”, al procediment TriaImatge.
    Botó “carpeta on guardarà el fitxer de text”, al procediment TriaCarpeta.
    Botó “Fer l’OCR”, al procediment OCR.
    Botó “Sortir”, al procediment Sortir.

    Si ara executo directament el procediment ObrirDialeg, per exemple, des del menú de macros, ja podré provar el wrapper (tesseract en la versió 2 i sense llibreries addicionals no reconeix gaires formats, proveu amb BMP o amb TIFF NO comprimit)

    Però el que de debò interessa en aquest exemple és preparar un add-on per a poder desplegar el wrapper.

    El procediment general està explicat en el capítol Extensions de la Developer’s guide.

    Crear una carpeta en la que construiré el projecte d’add-on, dins d’aquesta carpeta creo una subcarpeta “tesseract”. En aquesta subcarpeta hi copio els fitxers continguts a la carpeta $HOME/.openoffice.org/3/user/basic/tesseract

    Hi trobo quatre fitxers: dialog.xlb, script.xlb, Module1.xba i TesseractWrapperDialog.xdl

    Module1.xba i TesseractWrapperDialog.xdl corresponen respectivament al codi de la macro i a la definició en format xml del formulari del diàleg

    script.xlb és la llista, en format xml, dels mòduls de la llibreria.
    dialog.xlb és,. al seu torn, la llista dels diàlegs de la llibreria.

    Em situo de nou a la carpeta superior, al mateix nivell que la carpeta tesseract creo una carpeta META-INF. En aquesta carpeta hi poso el manifest.xml que conté la llista de fitxers que s’estan desplegant:

    <manifest:manifest>
    <manifest:file-entry manifest:full-path=”tesseract/” manifest:media-type=”application/vnd.sun.star.basic-library”>
    <manifest:file-entry manifest:full-path=”addon.xcu” manifest:media-type=”application/vnd.sun.star.configuration-data”>
    </manifest:file-entry></manifest:file-entry>
    </manifest:manifest>

    En aquest manifest estic declarant que la carpeta tesseract conté una llibreria de macros i diàlegs d’OOoBasic. També estic declarant que hi ha un fitxer addon.xcu que conté la configuració de l’aplicació.

    Addon.xcu s’ubica en l’arrel de la carpeta de projecte, és dir al mateix nivell que les carpetes teseract i META-INF.

    El fitxer addon.xcu descriu que cal modificar la interfase gràfica del context de l’OpenOffice.org Writer per afegir-hi una entrada de menú “OCR” amb un item “Wrapper Tesseract OCR” que invoca la macro que obre el diàleg (amb la URL: macro:tesseract.Module1.ObrirDialeg).

    <oor:component-data oor:name=”Addons” oor:package=”org.openoffice.Office” xmlns:oor=”http://openoffice.org/2001/registry&#8221; xmlns:xs=”http://www.w3.org/2001/XMLSchema”&gt;
    <node oor:name=”AddonUI”>
    <node oor:name=”OfficeMenuBar”>
    <node oor:name=”com.serveisticiprogramarilliure.openoffice.ocr” oor:op=”replace”>
    <prop oor:name=”Title” oor:type=”xs:string”>
    <value>OCR</value>
    </prop>


    <prop oor:name=”Target” oor:type=”xs:string”>
    <value>_self</value>
    </prop>


    <node oor:name=”Submenu”>
    <node oor:name=”m1″ oor:op=”replace”>


    <prop oor:name=”URL” oor:type=”xs:string”>
    <value>macro:tesseract.Module1.ObrirDialeg</value>
    </prop>


    <prop oor:name=”Title” oor:type=”xs:string”>
    <value>Wrapper Tesseract OCR</value>
    </prop>


    <prop oor:name=”Target” oor:type=”xs:string”>
    <value>_self</value>
    </prop>


    <prop oor:name=”Context” oor:type=”xs:string”>
    <value>com.sun.star.text.TextDocument</value>
    </prop>


    </node>
    </node>
    </node>
    </node>
    </node>
    </oor:component-data>

    Addicionalment, podríem afegir un fitxer de descripció description.xml

    És dir

    temporal-projecte (carpeta)
        addon.xcu
        META-INF (carpeta)
            manifest.xml
        tesseract (carpeta)
            dialog.xlb
            script.xlb
            Module1.xba
            TesseractWrapperDialog.xdl

    Practicament ja està, ara només cal fer un zip amb el contingut de la carpeta temporal-projecte i renombrar aquest zip a .oxt

    per provar que el .oxt es deplega correctament he d’eliminar primer la macro i el diàleg que he creat. Això puc fer-ho amb l’organitzador de macros.

    Un cop eliminat els rastres, aleshores només cal obrir el fitxer .oxt amb l’OpenOffice.org. Al fer-ho s’activa el gestor d’extensions. També podria desplegar el .oxt directament des del gestor d’extensions i també des de la línia d’ordres amb l’eina unopkg.

    Albert Baranguer
    21/11/2010 – Barcelona 

    Com fer un component UNO amb java

    El capítol clau del Developer’s Guide (DG) és http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Writing_UNO_Components
    En particular: http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Simple_Component_in_Java

    El procés general queda descrit en aquesta esquema extret de JavaEclipse tutorial i que ja hem presentat en un post anterior

    El que faré serà seguir aquest esquema aplicant-lo al codi d’exemple inclòs a l’SDK de l’OpenOffice.org.

    Desenvoluparé aquest experiment sobre un Ubuntu 10.04 Lucid Lynx amb un OpenOffice.org 3.2.

    En altres plataformes i versions les ubicacions poden ser diferents.

    El codi d’exemple és el MinimalComponent que es troba a /opt/openoffice.org/basis3.2/sdk/examples/java/MinimalComponent/

    El contingut de la carpeta és el següent:

    BuildMinimalComponent.xml: un fitxer build d’ant per a generar el component. Lamentablement les ubicacions corresponen a les d’OpenOffice.org sobre Windows i cal corregir les adreces.

    Makefile: un makefile per a generar el component fent servir el tradicional make.

    MinimalComponent.idl: El primer pas per a crear un component és definir-ne la seva interfase. Tots els components han d’implementar certes interfases. El que es fa en l’exemple és crear un component que implementa una d’aquestes interfases obligatòries: la com/sun/star/lang/XServiceInfo.idl la qual proporciona mètodes que informen sobre les serveis que implementa el component.

    Un component útil tindria una interfase específica que es definiria al fitxer .idl i, a més, també implementarà les interfases obligatòries (XServiceInfo, XInitialize i XTypeProvider).

    El llenguatge de deficició de interfases idl de UNO, el UNOIDL, es descriu en el capítol del DG: http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Using_UNOIDL_to_Specify_New_Components.
    També és interessant consultar http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Generating_Source_Code_from_UNOIDL_Definitions

    MinimalComponent.java: La implementació del component. He dit abans que tots els components han d’implementar obligatòriament XServiceInfo, XInitialize i XTypeProvider. El que es fa en aquesta classe és heredar de WeakBase que ja implementa XTypeProvider, de forma que només resta per implementar XServiceinfo i XInitialize. WeakBase és una de les classes que es poden fer servir de base per a implementar components (Al DG les en diuen Helper Classes).

    TestMinimalComponent.java: Finalment, una classe conductora per a provar  el component que hem creat. Hi trobem codi per a instanciar el nou component i executar-ne els mètodes de la seva interfase.

    El que faré serà seguir pas a pas el diagrama. Així doncs, el primer de tot és compilar la descripció de la interfase. Això es fa amb la utilitat idlc (IDL compiler) de l’SDK de l’OpenOffice.org.

    En el meu cas, he creat un projecte de java nou amb l’Eclipse i hi he copiat la carpeta MinimalComponent sencera.

    Observant amb atenció l’esquema, s’observa que té dues entrades possibles.
    – a partir del .idl
    – a partir del .java

    compilar .idl (especificació)

    La primera cadena, a partir de l’idl,

    Em situo en aquesta carpeta i invoco l’idlc tenint en compte que em caldrà incloure la definició (amb opció -I) de la XServiceInfo.

    Això últim es fa evident sense més que examinar MinimalComponent.idl

    #ifndef _org_openoffice_MinimalComponent_idl_ 
    #define _org_openoffice_MinimalComponent_idl_ 


    #include <com/sun/star/lang/XServiceInfo.idl> 


    // org
    module org {
        // openoffice
        module openoffice {
            // example service, XServiceInfo is implemented here for demonstration
            // issues. XServiceInfo must be implemented by all components. But
            // here it is used to show the new code generation feature for services.
            // See the TestMinimalComponent.java how it can be used!
            service MinimalComponent: ::com::sun::star::lang::XServiceInfo;
        };
    };


    #endif 

    Per compilar l’idl, doncs, faig servir la següent instrucció

    /opt/openoffice.org/basis3.2/sdk/bin/idlc -I /opt/openoffice.org/basis3.2/sdk/idl MinimalComponent.idl

    El resultat és el fitxer MinimalComponent.urd  que hauria de contenir la definició del nou tipus descrit per la interfase. Cal incloure aquesta nova definició a un Registre de tipus per a que es pugui invocar i sigui utilitzable. (per a més detalls sobre el registre, consulteu  la DG, http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/WritingUNO/Running_and_Debugging_Java_Components)

    Això ho faig amb el programa regmerge.

    /opt/openoffice.org/ure/bin/regmerge MinimalComponent.rdb /UCR MinimalComponent.ure

    Amb el que obtinc una base de dades de registre: el fitxer MinimalComponent.rdb.

    Ara bé, si observem el contingut d’aquesta base de dades de registre amb l’eina regview /opt/openoffice.org/ure/bin/regview ./MinimalComponent.rdb (suposant que estic a la mateixa carpeta que el .rdb), obtinc:

    /
     / UCR
       / org
         / openoffice
           / MinimalComponent
             Value: Type = RG_VALUETYPE_BINARY
                    Size = 142
                    Data = version: 1
                           documentation: “”
                           file name: “”
                           type class: service
                           type name: “org/openoffice/MinimalComponent”
                           super type count: 1
                           super type name 0: “com/sun/star/lang/XServiceInfo”
                           field count: 0
                           method count: 1
                           method 0:
                               documentation: “”
                               flags: synchronous
                               name: “”
                               return type name: “void”
                               parameter count: 0
                               exception count: 0
                           reference count: 0


           Value: Type = RG_VALUETYPE_BINARY
                  Size = 57
                  Data = version: 0
                         documentation: “”
                         file name: “”
                         type class: module
                         type name: “org/openoffice”
                         super type count: 0
                         field count: 0
                         method count: 0
                         reference count: 0


         Value: Type = RG_VALUETYPE_BINARY
                Size = 46
                Data = version: 0
                       documentation: “”
                       file name: “”
                       type class: module
                       type name: “org”
                       super type count: 0
                       field count: 0
                       method count: 0
                       reference count: 0


    El pas següent és  invocar el javamaker per a obtindre els .class corresponents al nou servei (org.openoffice.MinimalComponent)

    La sintaxi d’us de javamaker és:

    /opt/openoffice.org/basis3.2/sdk/bin/javamaker -BUCR -Torg.openoffice.MinimalComponent -nD /opt/openoffice.org/ure/share/misc/types.rdb ./MinimalComponent.rdb

    I obtinc la classe

    org.openoffice.MinimalComponent

    He d’afegir la classe al classpath per a compilar la MinimalComponent de la implementació (és dir, la classe que està en Default Package) que és el segon camí d’entrada descrit en l’esquema.

    compilar .java (implementació)

    En el cas del MinimalComponent.java  n’hi ha prou amb afegir org.openoffice.MinimalComponent al build, compilar i empaquetar amb jar, indicant en el manifest del META-INF que la classe a registrar és MinimalComponent, això ho aconseguiré amb el següent build.xml per a l’ant. És interessant remarcar quines són les llibreries utilitzades en el classpath (en negreta): les mateixes que per a compilar una macro java  i les d’addcionals,  officebean.jar i unoloader.jar.

    <project name=”ComponentUNO” default=”jar” basedir=”.”>
      <description>
      genera el zip del component UNO per a l’OpenOffice
      </description>

      <!– estableix propietats globals –>
      <property name=”src” location=”src”/>
      <property name=”build” location=”build”/>
      <property name=”dist”  location=”jar”/>
      <property name=”zip.dir”  location=”ComponentUNO”/>
      <property name=”cp-java-OOo-1″ location=”/opt/openoffice.org/ure/share/java/” />
      <property name=”cp-java-OOo-2″ location=”/opt/openoffice.org/basis3.2/program/classes/” />
      <property name=”OOo-user-macros” location=”/home/albert/.openoffice.org/3/user/Scripts/java/” />
      <property name=”OOo-shared-macros” location=”/opt/openoffice.org/basis3.2/share/Scripts/java/” />



      <target name=”init”>
        <!– time stap –>
        <tstamp/>
        <!– Crea el directory build utilitzat en la compilació –>
        <mkdir dir=”${build}”/>
      </target>


      <target name=”compile” depends=”init” description=”compila els fitxers font” >
        <!– Compila les fonts java de ${src} en ${build} –>
        <javac srcdir=”${src}” destdir=”${build}”>
          <classpath>
           <pathelement location=”${cp-java-OOo-1}/juh.jar”/>
            <pathelement location=”${cp-java-OOo-1}/jurt.jar”/>
           <pathelement location=”${cp-java-OOo-1}/ridl.jar”/>
           <pathelement location=”${cp-java-OOo-1}/unoloader.jar”/>
           <pathelement location=”${cp-java-OOo-2}/unoil.jar”/>
           <pathelement location=”${cp-java-OOo-2}/officebean.jar”/>
          </classpath>
       </javac>
      </target>




      <target name=”jar” depends=”compile” description=”genera el jar”>
        <!– Crea el directori de distribució –>
        <mkdir dir=”${dist}”/>


        <jar jarfile=”${dist}/MinimalComponent.1.uno.jar” basedir=”${build}”> 
          <include name=”**/*.class”/>
          <manifest>
            <attribute name=”RegistrationClassName” value=”MinimalComponent”/>
          </manifest>
        </jar>
      </target>


    </project>

    En compilar amb ant, obtinc el jar MinimalComponent.1.one.jar
    En aquest punt, ja tinc el component. Com provar-lo? Primer cal fer-ne el desplegament. Un cop desplegat, escriuré una macro amb OOoBasic que n’invoqui un mètode.

    En aquest punt  deixaré de seguir l’esquema.

    L’eina per a registrar components des de les primeres versions de l’OpenOffice.org ha estat regcomp. Tanmateix, aquesta eina ha estat superada per eines posteriors i des de fa algunes versions el que es pot fer servir és l’eina unopkg.

    L’eina unopkg permet desplegar  components en java (.jar), en c++ (.so o .dll), add-ons (.oxt)…  A més, és una eina que es pot fer servir des de línia d’ordres, però també es pot usar com una GUI. De fet, la GUI que activa és la mateixa que la del gestor d’extensions  de l’OpenOffice.org. El capítol de la DG que parla d’això és el de les Extensions.

    Per tant,  executo ‘/opt/openoffice.org3/program/unopkg gui’ i puc registrar el meu component fàcilment. Recordar que el path fins unopkg ‘/opt/openoffice.org3/program/’ pot ser un de diferent a altres versions  d’Ubuntu i d’OpenOffice.org.

    Se m’obre el gestor d’extensions on puc veure les extensions que tinc instal·lades:

    Faig click a “Afegeix…”

    Trio el tipus de fitxer  “Component Java UNO”

    Obro i el meu component queda instal·lat

    Si el vull desinstal·lar, puc fer-ho des del mateix gestor d’extensions.
    Finalment, per acabar, provaré que el nou component es utilitzable. Creo una petita macro que l’invoca. 
    Primer de tot engego l’OpenOffice.org, vaig a l’editor de macros. La macro que escric utilitza la popular  XrayTool per analitzar l’objecte UNO que he creat. A continuació invoco el mètode getImplementationName().
    Sub Main
        provaComponentUNO
    End Sub

    sub provaComponentUNO
        Dim oMinimal as Object

        BasicLibraries.loadLibrary(“XrayTool”)

    oMinimal = CreateUnoService(“org.openoffice.MinimalComponent”)
    xray oMinimal
    msgbox oMinimal.getImplementationName()
    end sub

    A  MinimalComponent.java trobem l’explicació de l’argument de CreateUnoService:
    public class MinimalComponent {
        /** This class implements the component. At least the interfaces XServiceInfo,
         * XTypeProvider, and XInitialization should be provided by the service.
         */
        public static class _MinimalComponent extends WeakBase
            implements XInitialization, XServiceInfo {
            /** The service name, that must be used to get an instance of this service.
             */
            static private final String __serviceName =
            “org.openoffice.MinimalComponent”;
    El resultat de l’execució és:
    i, finalment:
    Albert Baranguer
    Barcelona, 08/11/2010

    Diagrames dels models dels documents de l’OpenOffice.org

    En el post d’avui, uns diagrames que cal tenir presents a l’hora de desenvolupar macros i aplicacions amb Java, BeanShell o amb JavaScript per a l’OpenOffice.org. Extrets de la imprescindible wiki de l’OpenOffice.org.

    Primer de tot: un diagrama extret de http://wiki.services.openoffice.org/wiki/JavaEclipseTuto en el que es descriu el procés per a compilar un component UNO des de la interfase fins el jar.
    Més, els diagrames que ens expliquen el model, l’estructura, interfases i serveis,  que caracteritzen els diferents tipus de documents de l’OpenOffice.org. 
    Model de document de full de càlcul:
    Model dels documents de dibuix
    Model dels documents de presentació
    No existeixen els documents de base de dades, més aviat cal dir que una base de dades d’OpenOffice.org és una col·lecció d’objectes: taules, consultes, formularis i informes que són documents en ells mateixos. Per exemple, un formulari de base de dades és un objecte odt, és dir, és un formulari del mateix tipus que els formularis de document de text, amb el mateix model.  El model de les bases de dades d’OpenOffice.org serà tema de post un altre dia.

    Com fer una aplicació java standalone que utilitzi l’OpenOffice.org per a modificar o crear un document

    Una tasca comú a l’ofimàtica és automatizar la generació de documents. En el cas de l’MS Office això s’aconsegueix amb l’automatització OLE i llenguatges com Visual Basic.


    Per exemple, suposem que cal documentar l’esquema d’una base de dades. Una forma de fer-ho seria escriure un programa que analitzes les meta-dades de la base de dades i generés un document de text. 

    O, per exemple, crear un document amb el resultat d’analitzar escenaris amb un full de càlcul. Es podria escriure un programa que provés els diferents escenaris i generés un informe  amb els resultats 

    En el món Linux es pot aconseguir tot això fent servir Java i OpenOffice.

    Aquest post és un exemple de programa java que agafa un document de text de OpenOffice.org Writer que està buit (prova.odt) i l’omple amb 100 línies de text.

    M’he basat en el codi disponible a http://weblogs.java.net/blog/2005/12/30/open-office-java-api i en l’OpenOffice.org Developers Guide (en PDF), capítol First Contact, per al build.xml de l’ant.




    Comencem: el codi de la classe java 



    package com.serveisticiprogramarilliure.standalone;


    import com.sun.star.uno.XComponentContext;
    import com.sun.star.frame.XComponentLoader;
    import com.sun.star.frame.XStorable;
    import com.sun.star.lang.XComponent;
    import com.sun.star.comp.helper.Bootstrap;
    import com.sun.star.beans.PropertyValue;
    import com.sun.star.lang.XMultiComponentFactory;
    import com.sun.star.uno.UnoRuntime;
    import com.sun.star.text.XTextDocument;
    import com.sun.star.ucb.XFileIdentifierConverter;
    import com.sun.star.util.XCloseable;
    import com.sun.star.frame.XDesktop;


    public class ProvaStandalone {
     
        public static void main(String[] args) {
    try {
       System.out.println(“Inici”);
       // engega l’OpenOffice.org
       // Bootstrap
       System.out.println(“Bootstrap”);
       XComponentContext xContext = Bootstrap.bootstrap();
       // MultiComponentFactory
       System.out.println(“MultiComponentFactory”);
         XMultiComponentFactory xMCF = xContext.getServiceManager();
         // Crea el Desktop
         System.out.println(“Raw Desktop”);
       Object oRawDesktop = xMCF.createInstanceWithContext(“com.sun.star.frame.Desktop”, xContext);
       System.out.println(“Desktop”);
       XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, oRawDesktop);
       // Obté el carregador de components
       System.out.println(“Component loader”);
       XComponentLoader xCompLoader = (XComponentLoader) 
                                       UnoRuntime.queryInterface(XComponentLoader.class, xDesktop);


       // URL del document a generar.
       System.out.println(“convert to URL”);
       String sUrl =  convertToURL(xContext, xMCF, null, “/home/albert/Documents/prova.odt”);
       System.out.println(“Fitxer: ” + sUrl);
       
       // carrega un component document nou / 
       System.out.println(“Document existent”);
       PropertyValue[] voidProps = new PropertyValue[0];
       
       XComponent xComp = xCompLoader.loadComponentFromURL(sUrl, “_blank”, 0, voidProps);
       // “private:factory/swriter”;  document nou
       // “_blank”:  frame on es crea
       // 0: FrameSearchFlag, 
                // http://api.openoffice.org/docs/common/ref/com/sun/star/frame/FrameSearchFlag.html
       // new PropertyValue[0], 
                // http://api.openoffice.org/docs/common/ref/com/sun/star/document/MediaDescriptor.html
       
       // si en comptes d’utilitzar un document ja existent, volgués crear un document nou
                // posaria “private:factory/swriter” en comptes de sUrl
       
       // obté la interfase XTextDocument el component document nou
       System.out.println(“Escriu línies”);
       XTextDocument xTextDocument = (XTextDocument)
                                              UnoRuntime.queryInterface(XTextDocument.class, xComp);
       for(int i=0; i<100; i++) {
    xTextDocument.getText().getEnd().setString( “Escriu 100 línies. Línia ” + i + “.\n” );
       }
       
       // el guarda en format PDF
       // http://www.oooforum.org/forum/viewtopic.phtml?t=71294
       // “Name”, “Type”, “UIName” 
       // “Rich Text Format”, “writer_Rich_Text_Format”, “Rich Text Format” 
       // “writer_pdf_Export”, “pdf_Portable_Document_Format”, “PDF – Portable Document Format” 
       // …
       System.out.println(“XStorable”);
       XStorable xStorable = (XStorable)UnoRuntime.queryInterface(XStorable.class, xTextDocument);
       // indica el filtre de PDF


       // i guarda el fitxer
       System.out.println(“StoreAsURL”);
       xStorable.storeAsURL(sUrl, voidProps);


       // tancar l’openoffice que ha obert
       System.out.println(“Tanca”);
       XCloseable xcloseable = (XCloseable) UnoRuntime.queryInterface(XCloseable.class, xTextDocument);
       xcloseable.close(false);
    System.out.println(“Fi”);
    } catch (java.lang.Exception e) {
       e.printStackTrace();
    } finally {
       System.exit(0);
    }
        }
        
        /**
         * Converts a system path into an URL using OOo API
         * @param sBase
         * @param sSystemPath
         * @return
         */
        private static String convertToURL(XComponentContext xContext, 
         XMultiComponentFactory xMCF, 
         String sBase, 
         String sSystemPath) {
            String sURL = null;
            try {
             System.out.println(“FileConverter”);
                XFileIdentifierConverter xFileConverter =
               (XFileIdentifierConverter) UnoRuntime.queryInterface(
                   XFileIdentifierConverter.class,
                   xMCF.createInstanceWithContext(“com.sun.star.ucb.FileContentProvider”, xContext));
                System.out.println(“getFileURLFromSystemPath”);
                sURL = xFileConverter.getFileURLFromSystemPath(sBase, sSystemPath );
            } catch (com.sun.star.uno.Exception e) {
                e.printStackTrace();
            } finally {
                return sURL;
            }
        }
        
        /**
         * Converts an URL into a system path using OOo API
         * @param sURLPath
         * @return
         */
        private static String convertFromURL( XComponentContext xContext,
         XMultiComponentFactory xMCF,
         String sURLPath) {
            String sSystemPath = null;
            try {
                // m_xMCF = getMultiComponentFactory();
                XFileIdentifierConverter xFileConverter =
               (XFileIdentifierConverter) UnoRuntime.queryInterface(
                   XFileIdentifierConverter.class,
                   xMCF.createInstanceWithContext(
                                “com.sun.star.ucb.FileContentProvider”, xContext));
                sSystemPath = xFileConverter.getSystemPathFromFileURL(sURLPath);

            } catch (com.sun.star.uno.Exception e) {
                e.printStackTrace(System.err);
            } finally {
                return sSystemPath;
            }
        }
    }


    A continuació el build.xml d’ant que he fet servir. Difereix del que es troba en la Developers Guide en els paths que aquí estan adaptats a un OpenOffice.org 3.2  sobre Linux.



    <?xml version=”1.0″ encoding=”UTF-8″?>
    <project basedir=”.” default=”all” name=”standalone01″>
      <property name=”OFFICE_ROOT” value=”/opt/openoffice.org” />
      <property name=”OFFICE_HOME” value=”${OFFICE_ROOT}/basis3.2″ />
      <property name=”OO_SDK_HOME” value=”${OFFICE_HOME}/sdk” />
      <property name=”OO_URE_HOME” value=”${OFFICE_ROOT}/ure” />

      <target name=”init”>
      <property name=”OUT_DIR” value=”${basedir}/build/” />
    <property name=”BIN_DIR” value=”${basedir}/bin/” />
      </target>

      <path id=”office.class.path”>
    <filelist dir=”${OFFICE_HOME}/program/classes” files=”unoil.jar” />
    <filelist dir=”${OO_URE_HOME}/share/java” files=”jurt.jar,ridl.jar,juh.jar” />
      </path>

      <fileset id=”bootstrap.glue.code” dir=”${OO_SDK_HOME}/classes”>
    <patternset>
    <include name=”com/sun/star/lib/loader/*.class” />
    </patternset>
      </fileset>

      <target name=”compile” depends=”init” unless=”eclipse.running”>
    <mkdir dir=”${BIN_DIR}” />
    <javac debug=”true” deprecation=”true” destdir=”${BIN_DIR}” srcdir=”.”>
    <classpath refid=”office.class.path” />
    </javac>
      </target>

      <target name=”jar” depends=”init,compile”>
    <mkdir dir=”${OUT_DIR}” />
    <jar basedir=”${BIN_DIR}” compress=”true” jarfile=”${OUT_DIR}/standalone01.jar”>
    <exclude name=”**/*.java” />
    <exclude name=”*.jar” />
    <fileset refid=”bootstrap.glue.code” />
    <manifest>
    <attribute name=”Main-Class” value=”com.sun.star.lib.loader.Loader” />
    <section name=”com/sun/star/lib/loader/Loader.class”>
    <attribute name=”Application-Class” 
    value=”com.serveisticiprogramarilliure.standalone.ProvaStandalone” />
    </section>
    </manifest>
    </jar>
      </target>

      <target name=”all” description=”compila i linka” depends=”init,compile,jar”>
    <echo message=”OK. standalone01.jar” />
      </target>

        <target name=”cleanbin” description=”neteja binaris” unless=”eclipse.running”>
    <delete>
    <fileset dir=”${BIN_DIR}”>
    <include name=”**/*.class” />
    </fileset>
    </delete>
      </target>

      <target name=”cleanall” description=”neteja tot” depends=”init,cleanbin”>
    <delete file=”${OUT_DIR}/standalone01.jar” />
      </target>
    </project>


    Finalment, el fitxer executa.sh amb el que llenço l’execució. Recordo que l’entorn amb el que treballo és un OpneOffice.org 3.2.1 (i SDK), sobre Linux Ubuntu Lucid Lynx 10.04. compilat amb JDK 1.6. Versions diferents de qualsevol d’aquests elements pot provocar que algun path no sigui el correcte i que l’aplicació no funcioni, compte amb això!



    OFFICE_ROOT=/opt/openoffice.org
    OFFICE_HOME=$OFFICE_ROOT/basis3.2
    OO_SDK_HOME=$OFFICE_HOME/sdk
    OO_URE_HOME=$OFFICE_ROOT/ure


    echo java -cp “$OFFICE_HOME/program/classes/unoil.jar”,”$OFFICE_HOME/program/classes/sandbox.jar”,”$OO_URE_HOME/share/java/jurt.jar”,”$OO_URE_HOME/share/java/ridl.jar”,”$OO_URE_HOME/share/java/juh.jar” -Djava.library.path=”/opt/openoffice.org/basis3.2/sdk/classes” -Dcom.sun.star.lib.loader.unopath=”/opt/openoffice.org3/program”  -jar standalone01.jar


    java -cp “$OFFICE_HOME/program/classes/unoil.jar”,”$OFFICE_HOME/program/classes/sandbox.jar”,”$OO_URE_HOME/share/java/jurt.jar”,”$OO_URE_HOME/share/java/ridl.jar”,”$OO_URE_HOME/share/java/juh.jar” -Djava.library.path=”/opt/openoffice.org/basis3.2/sdk/classes” -Dcom.sun.star.lib.loader.unopath=”/opt/openoffice.org3/program”  -jar standalone01.jar


    El resultat de l’execució és un document de text prova.odt amb 100 línies de text i els següents missatges a la consola:



    albert@atenea:/media/Nuevo vol/wk-java/OOo-standalone-01/build$ ./executa.sh 
    java -cp /opt/openoffice.org/basis3.2/program/classes/unoil.jar,/opt/openoffice.org/basis3.2/program/classes/sandbox.jar,/opt/openoffice.org/ure/share/java/jurt.jar,/opt/openoffice.org/ure/share/java/ridl.jar,/opt/openoffice.org/ure/share/java/juh.jar -Djava.library.path=/opt/openoffice.org/basis3.2/sdk/classes -Dcom.sun.star.lib.loader.unopath=/opt/openoffice.org3/program -jar standalone01.jar
    Inici
    Bootstrap
    MultiComponentFactory
    Raw Desktop
    Desktop
    Component loader
    convert to URL
    FileConverter
    getFileURLFromSystemPath
    Fitxer: file:///home/albert/Documents/prova.odt
    Document existent
    Escriu línies
    XStorable
    StoreAsURL
    Tanca
    Fi
    albert@atenea:/media/Nuevo vol/wk-java/OOo-standalone-01/build$ 
      

    Albert Baranguer
    Barcelona 2010