Buscar

Delphi e OpenOffice(BROffice) - Parte 3

nome

Exio

Colunista ainda sem descrição. Caro colunista, por favor envie-nos sua descrição.

Continuação - Delphi e OpenOffice(BROffice) - Parte 3

ALCANÇANDO AS CÉLULAS NO CALC

I – REQUISITOS

É necessário ter acompanhado os dois módulo anteriores já que apresentam o conteúdo introdutório do assunto.

II – INTRODUÇÃO

Como pudemos observar na segunda parte desse artigo, acessamos planilhas, salvamos com os nomes desejados, excluímos e inserimos planilhas. A idéia básica é sempre abordarmos as partes mais externas e assim, ir avançando para as "entranhas". Bem, chegamos numa das partes mais importantes de nosso artigo – cito como mais importante, porque sempre fazemos a parte da formatação quando exportamos os dados para uma planilha ou para um documento de texto. Nossos clientes adoram, mas muitas vezes não tem noção da complexidade existente para que a tarefa seja executada.

O que veremos nesse momento de nosso artigo? Faremos acesso as células e adiconaremos as respectivas formatações: fonte, cor da célula, tamanho da célula, alinhamento, quebra de texto, borda e angulo de inclinação de nosso texto. Será necessário iniciarmos tudo do zero sendo que a parte prinicpal das chamadas OLE podem ser devidamente copiadas dos módulos anteriores.

As células no BrOffice seguem o mesmo padrão de nomenclatura do Excel, isto é, nome da Coluna e nome da Linha. Na parte da programação, você pode fazer referência ao nome da célula ou aos índices da Coluna e Linha; deixando mais claro, poderemos tanto usar a referência da célula pelo processo normal (A2, B5, C6, AJ38) ou ainda por índices (0,0 = A1, 4,2 = E3). Porém um detalhe importante deve ser posto: as referências de nome (A2, B5 e etc) são facilmente acessadas com o módulo UNO, sem ele, o acesso se dá facilmente usando o método getCellByPosition(Col, Row).

O Nosso exercício quando finalizado deverá estar parecido mais ou menos com a tela apresentada abaixo:


III – CODIFICANDO

O que faremos a partir de agora, será adicionarmos conteúdo a nossa planilha. O que estou fazendo de diferente, é somente declarar as variáveis do tipo variant como públicas, devido a facilidade de executar as coisas mais facilmente. Até porque o escopo de visualização de variáveis, funções e métodos não estão sendo avaliadas nesse momento. Isso caberá exclusivamente a você.

Na parte inicial de nosso sistema, defini as seguintes variáveis:

var
  Form1: TForm1;

  BrOffice, Desktop, Documento : Variant;
  Planilha, Celula             : Variant;

Declaramos também as unit ComObj e ShellAPI. A justificativa se dá que a unit ComObj nos dá o acesso aos objetos OLE, já a ShellAPI simplesmente foi adicionada com a intenção de capturar os nomes das fontes do sistema, para que a partir dai, pudéssemos aplicar na formatação de nossa planilha. Nada de mais até agora.

Em nossa pequena aplicação temos somente um botão, ele aplicará a mesma formatação a todos os valores das células e bordas que forem utilizados. Veja a primeira parte do evento onClick do botão:

procedure TForm1.Button1Click(Sender: TObject);
var
  X, Y : SHORT;
  Valor : String;
begin
  BrOffice  := CreateOleObject('com.sun.star.ServiceManager');
  Desktop   := BrOffice.CreateInstance('com.sun.star.frame.Desktop');
  Documento := Desktop.LoadComponentFromURL('private:factory/scalc',
                  '_blank', 0, VarArrayCreate([0,-1], varVariant));

  Planilha := Documento.getSheets.getByName('Planilha1');
           : Variant;

Desta vez modificamos um pouco a chamada a forma como capituramos o nome da planilha, usamos um método chamado getByName(Nome da Planilha), o pressuposto é que o desenvolvedor saberá quais planilhas estão presentes em sua pasta. Informamos então que estaremos trabalhando com a primeira folha chamada Planilha1. Um pouco mais abaixo, como aparece no código seguinte, declaramos dois laços For, porém no segundo laço, encontramos a seguinte atribuição – Célula := Planilha.getCellByPosition(X, Y), onde: X representa a coluna e Y a linha. Preste a atenção para esse método, pois através dele, poderemos obter ou atribuir valores, funções e formatação para as células. Um outro ponto importante a ressaltar é que, você não usará o método dessa forma getCellByPosition('A', 1) isso está errado, sempre deverá utilizar getCellByPosition(0, 0); essa referência diz que estamos trabalhando com a célula A1.

For X := cbIni.ItemIndex to CbFim.ItemIndex do
begin
  For Y := 0 to Pred(SpinEdit1.Value) do
  begin
    Celula := Planilha.getCellByPosition(X, Y);

Ótimo, já sabemos como podemos trabalhar com as linhas e colunas, fica mais fácil ainda iniciar o processo de inserção de valores em nossas células. Veja a sequência de código e encontramos a seguinte declaração: Celula.setString(' Aqui vai uma String'). Por padrão, quando digitamos uma String em uma célula tanto no Excel como no Scalc, os valores ficam alinhados a esquerda. Para que possamos inserir valores numéricos por exemplo, usaremos quase o mesmo método, somente trocando de setString para setValue. Tudo igual, somente muda os valores que está sendo inserido.

if rbTipo1.Checked then
begin
  Valor := cbIni.Items.Strings[X] + IntToStr(Y + 1);
  Celula.setString(Valor);
end else begin
  Valor := IntToStr(RandomRange(-123456789, 123456789));
  Celula.setValue(Valor);
end;

Nesse momento entramos nos demais elementos de formatação de Células. A propriedade CharFonteName é onde definimos o nome da fonte que iremos trabalhar para a célula, ela recebe um valor do tipo String. Em nossa aplicação, criamos duas pequenas funções, para justamente adicionar no ComboBox2 os nomes da fontes encontrada em nosso sistema. Você poderia usar um FontDialog para obter as propriedades de nome, tamanho, cor e estilo; isso poderia lhe trazer um certo problema, principalmente relacionados a cor, sublinhado e Estilo. A propriedade CharHeight recebe um valor inteiro e define o tamanho da fonte. As duas funções que adicionam os nomes de fontes dentro do ComboBox2 são:

function EnumFontsProc(var LogFont: TLogFont; var TextMetric: TTextMetric;
 FontType: Integer; Data: Pointer): Integer; stdcall;
begin
 TStrings(Data).Add(LogFont.lfFaceName);
 Result := 1;
end;

procedure TForm1.CapturarNomesDeFontes;
var
 DC: HDC;
begin
 DC := GetDC(0);
 EnumFonts(DC, nil, @EnumFontsProc, Pointer(ComboBox2.Items));
 ReleaseDC(0, DC);
 ComboBox2.Sorted := True;
 ComboBox2.ItemIndex := 0;
end;

Essas funções estão presentes no exemplo do arquivo de ajuda do Delphi – nome: RichEdit.

//Nome da Fonte
Celula.CharFontName := ComboBox2.Text;

//Tamanho da Fonte
Celula.CharHeight   := StrToInt(Edit1.Text);

A parte do alinhamento, tanto o horizontal como o vertical, podem ser definidos através das propriedades HoriJustify e VertJustify. Atente que elas apresentam diferenças de constates de uma para outra. Para HoriJustify, temos:

  • STANDARD : é o alinhamento padrão tanto para números como para textos, sendo a esqueda para as strings e a direita para os números;
  • LEFT : o conteúdo é alinhado no lado esquerdo da célula;
  • CENTER : o conteúdo é alinhado no centro da célula;
  • RIGHT : o conteúdo é alinhado no lado direito da célula;
  • BLOCK : o conteúdo é alinhando em relação ao comprimento da célula;
  • REPEAT : o conteúdo é repetido dentro da célula para preenchê-la.

Para VertJustify, temos:

  • STANDARD : é o valor usado como padrão;
  • TOP : o conteúdo da célula é alinhado pelo topo;
  • CENTER : o conteúdo da célula é alinhado pelo centro;
  • BOTTOM : o conteúdo da célula é alinhado pela base.

Como poderá observar no código fonte dessa aplicação, verá que para HoriJustify estamos usando respectivamente os seguintes valores: 0, 1, 2, 3, 4 e 5. Já para as definições de VertJustify estou usando os valores: 0, 1, 2 e 3. Se a programação se der dentro do ambiente de macros do BrOffice, deveremos usar as constantes sendo obedecidos os módulos em que são declarados. Diferentemente do que fazemos aqui onde emitimos os valores da indexação dos valores.

//Alinhamento Horizontal
Celula.HoriJustify  := RetornaValorDoCombobox('-', ComboBox3);

//Alinhamento Vertical
Celula.VertJustify  := RetornaValorDoCombobox('-', ComboBox4);

Para os sublinhados, temos 18 (dezoito) tipos diferentes, e podem ser definidos como:

  • 0 - None // Sem sublinhado.
  • 1 - Single // linha simples.
  • 2 - Double // linha dupla.
  • 3 - Dotted // linha pontilhada.
  • 4 - DontKnow // Sublinhado desconhecido.
  • 5 - Dash // linha tracejada.
  • 6 - LongDash // traços longos.
  • 7 - DashDot // traço e ponto sequenciados.
  • 8 - DashDotDot // traço, ponto, ponto sequencia.
  • 9 - SmallWave // Ondas pequenas.
  • 10 - Wave // Em onda.
  • 11 - DoubleWave // Em ondas duplas.
  • 12 - Bold // linha em negrito.
  • 13 - BoldDotted // pontos em negrito.
  • 14 - BoldDash // traços em negrito.
  • 15 - BoldLongDash // Traços longo em negrito.
  • 16 - BoldDashDot // Traço, ponto e sequencia em negrito.
  • 17 - BoldDashDotDot // Traço, ponto, ponto, sequencia em negrito.
  • 18 - BoldWave // onda Negritada....

Para atribuir um tipo de sublinhado a sua fonte, use a propriedade CharUnderline, atribuindo um dos valores apresentados acima.

//Tipo de Sublinhado
Celula.CharUnderline:= RetornaValorDoCombobox('-', ComboBox5);

Para atribuirmos itálico, usamos a propriedade CharWeight e estão disponíveis as seguintes contantes, conforme a lista abaixo:

  • 0 - Dontknow = Camera / desconhecido.
  • 50 - Thin = 50% do peso da fonte.
  • 60 - UltraLight = 60% do peso da fonte.
  • 75 - Light = 75% do peso da fonte.
  • 90 - SemiLight = 90% do peso da fonte.
  • 100 - Normal = 100% peso da fonte normal (100%).
  • 110 - SemiBold = 110% do peso da fonte.
  • 150 - Bold = 150% do peso da fonte.
  • 175 - UltraBold = 175% do peso da fonte.
  • 200 - Negro = 200% do peso da fonte

//Tipo de Itálico
Celula.CharWeight   := RetornaValorDoCombobox('-', ComboBox6);

Até esse momento de nossa codificação, tudo vai de "vento em popa", porém quando falamos de cores, tanto para background das células, como para bordas e o conteúdo, a coisa muda um pouco. Podemos definir cores usando uma função no Delphi definida como RGB(Red, Green, Blue), podendo em cada parâmetro, receber um valor Short de 0 a 255. Porém, se executarmos a seguinte atribuição a uma cor no BrOffice, algo do tipo – RGB(123, 066, 222), é bem provável que a cor apresentada, não seja aquela esperada. Porque isso acontece? Aqui vai uma explicação simples: porque o valor utilizado para representar uma cor no BrOffice é compreendido como um único número inteiro. Em código pascal, poderíamos dar como exemplo, o seguinte:

Var
 vRed : Short; //Valor entre 0 e 255
 vGree: Short; //Valor entre 0 e 255
 vBlue: Short; //Valor entre 0 e 255
 vColorBR : Integer; //Valores podem variar em 16, 577 e 320

Então, para facilitar ainda mais sua vida, você poderá usar uma das seguintes cores indexadas e conforme são apresentadas em nossa aplicação num pequeno grid de 10 X 11. Utilizando os valores aqui listados, não há erro. O Excel também trabalha com uma indexação de cores, porém se você usar o RGB as cores sairão dentro do que você estava prevendo. Não podemos dizer o mesmo para o BrOffice.


Para atribuir uma cor de fonte use a propriedade CharColor, e para o Background utilize a propriedade CellBackColor , para ambos, atribua um dos valores da tabela acima.

//Cor da Fonte
Celula.CharColor    := RetornaValorDoCombobox('-', ComboBox7);

//Cor do Background da Célula
Celula.CellBackColor:= RetornaValorDoCombobox('-', ComboBox1);

Entendido os problemas relacionados as cores e obviamente que sanadas as dúvidas, voltemos a parte light da coisa. Se estiver interessado em rotacionar o texto dentro de uma célula, utilize as propriedades RotateReference e RotateAngle. A propriedade mais importante é realmente RotateAngle. Você pode fazer a atribuição como o exemplo do código nessa sequência. Onde multiplicamos o valor por 100. A propriedade aceita valores iguais ou maiores a 0,01. Eis o motivo de eu fazer a multiplicação por 100. Para um ângulo de 45, ficaria a seguinte definição por exemplo: Celula.RotateAngle := 4500; // 45 * 100. A propriedade RotateReference é utilizada como referência para a partida da rotação do conteúdo. Pode ser o valor 0 (ZERO) para a partir da base, 1 para partir do topo e 2 para partir do centro da célula.

//Permite rotacionar o conteúdo da célula
if Rotacionar.Checked then
begin
  Celula.RotateReference := RadioGroup1.ItemIndex;
  Celula.RotateAngle := StrToInt(Edit2.Text) * 100;
end;

Para quebrar o conteúdo do texto, defina a propriedade IsTextWarapped para True. É uma propriedade booleana, portanto, aceitará somete true ou false.

//Quebrar o conteúdo da Célula
if cbQuebrar.Checked then
  Celula.IsTextWrapped := True;

As bordas da células podem conter formatações diferentes, isto é, podemos formatar a borda superior com espessura e cor diferente da borda inferior, assim como a borda da esquerda totalmente diferente da direita. O processo de formatação da borda tem muito mais recursos quando trabalhamos com as estruturas UNO, como veremos mais adiante. A atribuição da formatação das bordas usa na verdade, uma estrutura do módulo table e que por consequência, utiliza uma outra tabela onde definimos as especificações para cor, espessura da borda interna e externa e a distância entre elas. Para que você possa formatar as bordas de suas células, será necessário usar a função AtribuirBordas, Essa função é parecida com aquela que criamos nas segunda parte para podermos salvar nossos arquivos.

function TForm1.AtribuirBordas(Cor, EspLinInter, EspLinExter,
		DistLinha : Variant): Variant;
var
 otherRef : Variant;
begin
 otherRef := BrOffice.createInstance('com.sun.star.reflection.CoreReflection');
 otherRef.forName('com.sun.star.table.BorderLine').createObject(result);
 result.Color           := Cor;
 result.InnerLineWidth  := EspLinInter ;
 result.OuterLineWidth  := EspLinExter;
 result.LineDistance    := DistLinha;
end;

Como pode ser visto, estamos utilizando o módulo BorderLine. É o que fazemos então atribuindo a propriedade relativa a cada célula. Veja que atribuimos a Celula.TopBorder := AtribuirBordas(...... Estamos dizendo que a borda superior terá a configuração passada em seus parâmetros. Esses parâmetros podem ser diferentes para cada borda desejada. Se você quiser somente que as bordas superiores e inferiores apareçam, atribuia as propriedades somente a essas duas bordas e esqueça as demais.

//Formatação das bordas das Células
      if bSup.Checked then
         Celula.TopBorder := AtribuirBordas(RetornaValorDoCombobox('-', ComboBox8),
                        StrToInt(Edit4.Text),
                        StrToInt(Edit5.Text),
                        StrToInt(Edit6.Text));
      if bEsq.Checked then
         Celula.LeftBorder := AtribuirBordas(RetornaValorDoCombobox('-', ComboBox8),
                        StrToInt(Edit4.Text),
                        StrToInt(Edit5.Text),
                        StrToInt(Edit6.Text));
      if bDir.Checked then
         Celula.RightBorder := AtribuirBordas(RetornaValorDoCombobox('-', ComboBox8),
                        StrToInt(Edit4.Text),
                        StrToInt(Edit5.Text),
                        StrToInt(Edit6.Text));
      if bInf.Checked then
         Celula.BottomBorder := AtribuirBordas(RetornaValorDoCombobox('-', ComboBox8),
                        StrToInt(Edit4.Text),
                        StrToInt(Edit5.Text),
                        StrToInt(Edit6.Text));

    end;
  end;
end;

Estimados amigos, na sequência vamos nos aprofundar ainda mais em nossas planilhas. Novamente volto a frizar que se erros ou inconscistências ocorrerem, enviem-me um printscreen da tela e se possível o código fonte para que possa analisar e buscar as respecitvas soluções. Gostaria também de acrescentar que isso tudo é fruto de testes e mais testes, portanto podem haver outras variantes de código que realizam a mesma tarefa de forma mais complexa ou mais simples.

Código fonte acompanha este exercício.

Delphi e BrOffice - Parte 3.zip

Publicidade

Vote no artigo




Quantidade de votos: 1 voto
Aceitação: 20%


Detalhes do artigo

Categoria: Windows
Adicionado dia: 11/01/10
Por: Exio
Visualizado: 25872 vezes

Planeta Delphi - Tudo sobre programação Delphi Planeta Delphi - www.planetadelphi.com.br - Todos os direitos reservados | Copyright 2001-2009