Notícias‎ > ‎

Incorporando o LibreOffice em um código VB.NET

postado em 21 de jan de 2013 09:25 por - Imprensa
postado em 17/01/2013 08:17 no blog de Gustavo Pacheco.

Incorporar o LibreOffice em um Form é uma alternativa interessante no desenvolvimento de sistemas onde é necessário manipular documentos no padrão ODF. É possível fazer isso em várias linguagens de programação e, dependendo da complexidade do código, o resultado pode ser muito bom.

Neste tutorial, apresentarei a incorporação do LibreOffice no Visual Basic.NET utilizando o controle EmbeddedOpenOffice em Microsoft Visual Basic 2010 Express e Windows XP. O controle EmbeddedOpenOffice foi desenvolvido pela Sun pelo desenvolvedor Lars Behrmann em meados de 2005. Desde então, o projeto foi hospedado em diversos lugares (SourceForge, Google Code e ODF Toolkit). Apesar do projeto, hoje, não fazer mais parte do ODFToolkit, o controle continua funcional no .NET (fiz testes similares no Microsoft Visual C# 2010 Express com resultados corretos). Caso necessário, o código está disponível integralmente para desenvolvimento. 

Verificando a configuração do LibreOffice

O componente EmbeddedOpenOffice depende do arquivo so_activex.dll no diretório indicado em EmbeddedOpenOffice1.OpenOfficePath (normalmente, C:\Arquivos de programas\LibreOffice 3.6\program).

 (clique na figura abaixo para aumentá-la)

Esse arquivo só é instalado através da instalação personalizada do LibreOffice (recomendamos a versão 3.6.4):

Configuração do controle EmbeddedOpenOffice

O primeiro passo é obter o controle EmbeddedOpenOffice em:
http://sourceforge.net/projects/aodl/files/Embedded%20OpenOffice/Embedded%20OpenOffice%20.net%20Control%201.0.0.5/ 

Depois, descompacte o arquivo EmbeddedOpenOffice_1_0_0_5.net.zip e, em ..\EmbeddedOpenOffice_1_0_0_5.net\Control\compiled, executar register.bat para registrar o componente.

A seguir, adicione as seguintes DLLs ao ambiente (no Visual Basic 2010 Express Edition, em Project... > Add reference...) e a Toolbox (botão direito do mouse sobre a Toolbox > Choose items... > .NET Framework Componentes > Browse...).

EmbeddedOpenOfficeStartHelper.dll
EmbeddedOpenOfficenet.dll 

Por fim, o componente estará disponível na Toolbox de controles:


No seu código VB.NET, o controle é iniciado com o seguinte trecho: 

'definição do caminho padrão do LibreOffice
EmbeddedOpenOffice1.OpenOfficePath = "C:\Arquivos de programas\LibreOffice 3.6\program" 

'definição de uma pasta temporária
EmbeddedOpenOffice1.TempFolder = "c:\TEMP" 

'definição do caminho do arquivo e da abertura como somente leitura (true) ou não (false).
EmbeddedOpenOffice1.LoadDocument("C:\teste2.odt", false)

Obtendo o controle do documento via código

O controle EmbeddedOpenOffice funciona apenas como um frame de exibição de uma janela componente do LibreOffice. Ou seja, o controle não fornece métodos e propriedades para o acesso ao conteúdo do documento. É, de fato, uma lacuna no desenvolvimento do controle. 

Há no entanto, um meio poderoso para obtermos o controle do documento. Fazemos isso através da conexão VB.NET com a instância local do LibreOffice. A partir da conexão (mais especificamente a partir do objeto objDesktop), é possível descobrir o frame do documento através do seu título:

Private Sub listarFrames_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click
'************************** 
'* Procedimento para a prova de conceito de uso do controle EmpeddedOpenOffice 
'* Gustavo Buzzatti Pacheco - gbpacheco@prodesk.com.br 
'* Projeto: ODF 
'* 3 de janeiro de 2013 
'************************** 
'
Dim objServiceManager As Object 
Dim objCoreReflection As Object 
Dim objDesktop As Object 
Dim vFrames As Object 'coleção dos frames 
Dim objModel As Object 'modelo do frame 
Dim i As Integer 'índice dos frames 
Dim s As String 'string com o título e o caminho do arquivo 

'Criação da conexão com a instância local do LibreOffice
objServiceManager = CreateObject("com.sun.star.ServiceManager") 
objCoreReflection = objServiceManager.createInstance("com.sun.star.reflection.CoreReflection") 
objDesktop = objServiceManager.createInstance("com.sun.star.frame.Desktop") 

REM queryFrames(4) da interface XFrames busca todos os frames filhos do desktop

s = ""

vFrames = objDesktop.getFrames().queryFrames(4) 'com.sun.star.frame.FrameSearchFlag.CHILDREN - http://www.openoffice.org/api/docs/common/ref/com/sun/star/frame/FrameSearchFlag.html#CHILDREN

For i = LBound(vFrames) To UBound(vFrames)
      objModel = vFrames(i).getController().getModel() 
       s = s & vFrames(i).Title & " " & objModel.getURL() & " " & Chr(10) 'coloca o título e a URL na variável s 
Next (i) 

MsgBox(s, 0, "Frame Titles") ' mostra o conteúdo da variável s

End Sub

Atenção para os detalhes...

Caso o código com o componente EmbeddedOpenOffice seja executado sem que o LibreOffice tenha sido inicializado antes (via manual ou via quickstart), é possível que você obtenha o seguinte erro:


O problema é derivado de algumas alterações na definição de opções de inicialização do LibreOffice. Já foi documentado no sistema de gerenciamento de bugs do LibreOffice e já está resolvido para a versão  3.6.5.2:

https://bugs.freedesktop.org/show_bug.cgi?id=57203

Como contingência (e, também como forma de melhorar o desempenho da inicialização do LibreOffice embutido no código VB.NET), podemos executar o quickstart do LibreOffice via código antes da inicialização do controle EmbeddedOpenOffice em:

C:\Arquivos de programas\LibreOffice 3.6\program\quickstart.exe

O quickstart é um pequeno aplicativo que roda no IconTray do Windows com o objetivo de abrir rapidamente documentos no LibreOffice. Ou seja, uma pré-execução do aplicativo. 

 Executar o quickstart (mesmo que seja via código) melhorará o desempenho do seu código e evitará a mensagem de erro em versões anteriores à 3.6.5. 

Conclusão

O resultado final de um projeto de sistema que incorpore o LibreOffice pode ser algo extremamente útil se considerarmos a grande quantidade de tarefas do usuário que é baseada em documentação (mesmo que seja para algo simples como, por exemplo, a exibição de um documento somente leitura). 

Utilizando o controle Ribbon (http://officeribbon.codeplex.com/) é possível, por exemplo, criar uma barra de acesso aos recursos do aplicativo similar à do Microsoft Office 2010. O trabalho mais simples seria associar cada botão da barra ao seu respectivo comando UNO da API do LibreOffice. O trabalho mais difícil seria gerenciar o acesso aos documentos através de uma estrutura de janelas MDI. 


O exemplo fica, então, apenas como uma curiosidade. Se o objetivo é deixar o seu LibreOffice mais bonito, eu sugiro esperar um pouco mais pela versão 4.0, que permitirá a personalização da interface com o Firefox Personas. Curioso? Leia mais em: http://blog.pt-br.libreoffice.org/2013/01/11/tatuagens-e-ringtones/ .

Para comentários e sugestões, utilize twitter ou e-mail.
Comments