Delphi e OpenOffice (BrOffice)

Delphi

31/10/2006

Saudações gente,
eu sei que muita gente já falou sobre isso e antes de postar eu dei uma verificada na pesquisa mas não consegui encontrar algo concreto sobre o assunto. Como posso fazer com que o OpenOffice (ou BrOffice) abra uma arquivo xls ou como abrir uma planilha sem possuir o Excel utilizando uma destas duas suítes?
Achei e já utilizo uma função que exporta para OpenOffice mas não consigo achar uma maneira de fazer o inverso. Será que alguém pode me ajudar nisto?
Ah! para este caso estou usando o Delphi 5.0 Pro, MySql 5.0 e Paleta MySqlDAC. É porque estou trabalhando em dois projetos e existem mensagens minhas com Delphi 7 e PostGreSql...
Muito obrigado.


Zooropa

Zooropa

Curtidas 1

Melhor post

Zooropa

Zooropa

01/11/2006

Olá Motta,
obrigado pela dica. Quanto à função, que na verdade é uma procedure, vou colocá-la aqui para que possa ajudar quem tb precisa. Achei-a catando pelo google (algumas coisas precisei implementar - para a verificação do tipo e do comteúdo do campo):
procedure TfmFunction.SendToOpenOffice(aDataSet: TDataSet);
var
   OpenDesktop, Calc, Sheets, Sheet: Variant;
   Connect, OpenOffice : Variant;
   i : Integer; // Coluna
   j : Integer; // Linha
   teste : string;
begin
   Screen.Cursor      := crSQLWait;
   aDataset.Open;
   aDataset.Last;

   // Cria o link OLE com o OpenOffice
   if VarIsEmpty(OpenOffice) then
      OpenOffice := CreateOleObject(´com.sun.star.ServiceManager´);
   Connect := not (VarIsEmpty(OpenOffice) or VarIsNull(OpenOffice));

   // Inicia o Calc
   OpenDesktop := OpenOffice.CreateInstance(´com.sun.star.frame.Desktop´);
   Calc        := OpenDesktop.LoadComponentFromURL(´private:factory/scalc´, ´_blank´, 0, VarArrayCreate([0, - 1], varVariant));
   Sheets      := Calc.Sheets;
   Sheet       := Sheets.getByIndex(0);

   // Cria linha de cabeçalho
   i := 0;
   while i <= aDataset.FieldCount - 1 do begin
         Sheet.getCellByPosition(i,0).setString(aDataset.Fields[i].FieldName);
         i := i + 1;
   end;

   // Preenche a planilha
   j := 1;
   aDataset.First;
   while not aDataset.Eof do
   begin
         i := 0;
         while i <= aDataset.FieldCount - 1 do
         begin
              if aDataset.Fields[i].DataType in [ftDate, ftTime, ftDateTime] then
              begin
                 if ((DateToStr(aDataset.Fields[i].Value) <> Null) and (DateToStr(aDataset.Fields[i].Value) <> ´´)) then
                    Sheet.getCellByPosition(i,j).SetString(aDataset.Fields[i].Value);
              end
              else if aDataset.Fields[i].DataType in [ftSmallint, ftInteger, ftLargeint] then
              begin
                 if ((IntToStr(aDataset.Fields[i].Value) <> Null) and (IntToStr(aDataset.Fields[i].Value) <> ´´)) then
                    Sheet.getCellByPosition(i,j).SetValue(aDataset.Fie0A   Sheets      := Calc.Sheets;
   Sheet       := Sheets.getByIndex(0);

   // Cria linha de cabeçalho
   i := 0;
   while i <= aDataset.FieldCount - 1 do begin
         Sheet.getCellByPosition(i,0).setString(aDataset.Fields[i].FieldName);
         i := i + 1;
   end;

   // Preenche a planilha
   j := 1;
   aDataset.First;
   while not aDataset.Eof do
   begin
         i := 0;
         while i <= aDataset.FieldCount - 1 do
         begin
              if aDataset.Fields[i].DataType in [ftDate, ftTime, ftDateTime] then
              begin
                 if ((DateToStr(aDataset.Fields[i].Value) <> Null) and (DateToStr(aDataset.Fields[i].Value) <> ´´)) then
                    Sheet.getCellByPosition(i,j).SetString(aDataset.Fields[i].Value);
              end
              else if aDataset.Fields[i].DataType in [ftSmallint, ftInteger, ftLargeint] then
              begin
                 if ((IntToStr(aDataset.Fields[i].Value) <> Null) and (IntToStr(aDataset.Fields[i].Value) <> ´´)) then
                    Sheet.getCellByPosition(i,j).SetValue(aDataset.Fields[i].Value);
              end
              else if aDataset.Fields[i].DataType in [ftFloat, ftCurrency] then
              begin
                 if ((FloatToStr(aDataset.Fields[i].Value) <> Null) and (FloatToStr(aDataset.Fields[i].Value) <> ´´)) then
                    Sheet.getCellByPosition(i,j).SetValue(aDataset.Fields[i].Value);
              end
              else begin
                 if ((aDataset.Fields[i].Value <> Null) and (aDataset.Fields[i].Value <> ´´)) then
                 begin
                    teste := ´´;
                    teste := aDataset.Fields[i].Value;
                    Sheet.getCellByPosition(i,j).SetString(teste);
                 end;   
              end;

               i := i + 1;
         end;
         aDataset.Next;
         j := j + 1;
   end;
   Screen.Cursor      := crArrow;
   // Desconecta o OpenOffice
   OpenOffice         := Unassigned;
   ShowMessage(´Planilha Gerada´);
end;



GOSTEI 2

Mais Respostas

Motta

Motta

31/10/2006

Qual esta function que exporta para Open ?

No site da Open tem um lugar para este tipo de projeto, procure pleo Developer´s Guide.


GOSTEI 0
Zooropa

Zooropa

31/10/2006

Putz, escrevi conteúdo com m.... :-P


GOSTEI 0
Freitas.atdl

Freitas.atdl

31/10/2006

Bom dia a todos
O codigo acima converte perfeitamente a tabela.
Mas Convertendo uma tabela do banco de dados me deparei com um problema.
Uma planilha do broffice tem 65.536 linhas, tenho algumas tabelas com 100 mil ou mais registros, estive pensando se tem como eu abrir uma nova guia para que eu possa inserir esses geristros na proxima aba de planilha. (planilha1, planilha2, planilha3)
Fico no aguardo.


GOSTEI 0
Júlio Cesar

Júlio Cesar

31/10/2006

segue minha funçao toda. mudando de planilha caso o numero de linhas seja maior que 65536



CriaPlanilhaBrOffice(aDataSet: TDataSet);
var
OpenDesktop, Calc, Sheets, Sheet: Variant;
Connect, OpenOffice: Variant;
i: Integer; // Coluna
j: Integer; // Linha
NumSheet: Integer;
teste: string;
begin
// Screen.Cursor := crSQLWait;
aDataset.Open;
aDataset.Last;
try
// Cria o link OLE com o OpenOffice
if VarIsEmpty(OpenOffice) then
OpenOffice := CreateOleObject(com.sun.star.ServiceManager);
Connect := not (VarIsEmpty(OpenOffice) or VarIsNull(OpenOffice));
// Inicia o Calc
OpenDesktop := OpenOffice.CreateInstance(com.sun.star.frame.Desktop);
Calc := OpenDesktop.LoadComponentFromURL(private:factory/scalc, _blank, 0, VarArrayCreate([0, -1], varVariant));
Sheets := Calc.Sheets;
Sheet := Sheets.getByIndex(0);
// Cria linha de cabeçalho
i := 0;
while i
GOSTEI 0
Júlio Cesar

Júlio Cesar

31/10/2006

com o "minha" não quis dizer q desenvolvi mas a forma que adaptei para funcionar sengudo minhas necessidades.
que não é muito diferente a original que esta logo acima no forum.

segue minha funçao toda. mudando de planilha caso o numero de linhas seja maior que 65536



CriaPlanilhaBrOffice(aDataSet: TDataSet);
var
OpenDesktop, Calc, Sheets, Sheet: Variant;
Connect, OpenOffice: Variant;
i: Integer; // Coluna
j: Integer; // Linha
NumSheet: Integer;
teste: string;
begin
// Screen.Cursor := crSQLWait;
aDataset.Open;
aDataset.Last;
try
// Cria o link OLE com o OpenOffice
if VarIsEmpty(OpenOffice) then
OpenOffice := CreateOleObject(com.sun.star.ServiceManager);
Connect := not (VarIsEmpty(OpenOffice) or VarIsNull(OpenOffice));
// Inicia o Calc
OpenDesktop := OpenOffice.CreateInstance(com.sun.star.frame.Desktop);
Calc := OpenDesktop.LoadComponentFromURL(private:factory/scalc, _blank, 0, VarArrayCreate([0, -1], varVariant));
Sheets := Calc.Sheets;
Sheet := Sheets.getByIndex(0);
// Cria linha de cabeçalho
i := 0;
while i
GOSTEI 0
Júlio Cesar

Júlio Cesar

31/10/2006

freitas.atdl
Conhecidentemente estava trabalhando nessa função e percebi que só mudar de aba não era o suficiente voce poderia ter um resultado que ultrapasse as 3 planilhas padrão. entao adicionei o codigo para criar as planilhas caso ultrapasse o padrao das 3


if j = 65536 then
begin
inc(NumSheet);

if NumSheet > 2 then
Sheets.insertNewByName(Planilha+IntToStr(NumSheet + 1),NumSheet + 1);

Sheet := Sheets.getByIndex(NumSheet);

J := 0;
end;
GOSTEI 0
Julyemerson Leonizio

Julyemerson Leonizio

31/10/2006

No meu codigo ta dando erro na linha:
Sheet.getCellByPosition(i,j).SetValue(aDataset.Fie0A Sheets := Calc.Sheets;



alguem pode me ajudar não faço ideia do que seja...
GOSTEI 0
Bruno Leandro

Bruno Leandro

31/10/2006

Me parece que acabou apagando parte do codigo, confirma ai. mas parece que seria mais ou menos assim

Sheet.getCellByPosition(i,j).SetValue(aDataset.Fields[i].AsFloat);
Sheets := Calc.Sheets;
GOSTEI 0
Julyemerson Leonizio

Julyemerson Leonizio

31/10/2006

obg deu certo!
GOSTEI 0
Claudio

Claudio

31/10/2006

Olá amigos !
Modifiquei o código para transferir o conteúdo do dbgrid, assim vc pode fazer as suas pesquisas e pode transferir para o OpenOffice (SCalc).

--> Título : Função exportar DBGrid para o OpenOffice.

- Tenha o OpenOffice, BrOffice ou StarOffice instalado no computador é claro !
- Feito no Delphi 7 com Zeos 6.0 (Utilize o Dataset que quiser)

Código :

//funcao para exportar para openoffice o DBGrid

procedure TFBradesco.SendToOpenOffice(aGrid: TDBGrid);
var
OpenDesktop, Calc, Sheets, Sheet, wProperties : Variant;
Connect, OpenOffice : Variant;
i : Integer; // Coluna
j : Integer; // Linha
teste : string;
begin

//o segredo de pegar a dbgrid inteira é ir para primeira linha e coluna do DBGrid
ZTableAgencias.FindFirst; //Minha tabela no Zeos
aGrid.SelectedField := aGrid.Columns[0].Field;
aGrid.SelectedIndex:=0;
aGrid.SetFocus;

Screen.Cursor := crSQLWait;
//aGrid.DataSource.DataSet.Open;
//aGrid.DataSource.DataSet.Last;

aGrid.SelectedRows.CurrentRowSelected := True;

// Cria o link OLE com o OpenOffice
if VarIsEmpty(OpenOffice) then
OpenOffice := CreateOleObject('com.sun.star.ServiceManager');
Connect := not (VarIsEmpty(OpenOffice) or VarIsNull(OpenOffice));

// Inicia o Calc
OpenDesktop := OpenOffice.CreateInstance('com.sun.star.frame.Desktop');
wProperties := VarArrayCreate([0, - 1], varVariant);
Calc := OpenDesktop.LoadComponentFromURL('private:factory/scalc', '_blank', 0, wProperties);
sheets := Calc.Sheets;
Sheet := Sheets.getByIndex(0);

// Calc.ConvertFromUrl(calc);

// Cria linha de cabeçalho
i := 0;
while i <= aGrid.FieldCount - 1 do begin
//Sheet.getCellByPosition(i,0).setString(aGrid.Fields [i].FieldName);
Sheet.getCellByPosition(i,0).setString(aGrid.Columns.Items[i].Title.Caption); //aqui resolvi pegar o titulo do DBGrid
i := i + 1;
end;

// Preenche a planilha
//j := 1;
//aGrid.First;

while not aGrid.DataSource.DataSet.Eof do
begin
i := 0;
while i <= aGrid.FieldCount - 1 do
begin
if aGrid.Fields[i].DataType in [ftDate, ftTime, ftDateTime] then
begin
if ((DateToStr(aGrid.Fields[i].Value) <> Null) and (DateToStr(aGrid.Fields[i].Value) <> '')) then
Sheet.getCellByPosition(i,j).SetString(aGrid.Fields[i].Value);
end
else if aGrid.Fields[i].DataType in [ftSmallint, ftInteger, ftLargeint] then
begin
if ((IntToStr(aGrid.Fields[i].Value) <> Null) and (IntToStr(aGrid.Fields[i].Value) <> '')) then
Sheet.getCellByPosition(i,j).SetValue(aGrid.Fields[i].Value);
Sheets := Calc.Sheets;
Sheet := Sheets.getByIndex(0);

// Cria linha de cabeçalho
i := 0;
while i <= aGrid.FieldCount - 1 do begin
//Sheet.getCellByPosition(i,0).setString(aGrid.Fields[i].FieldName);
Sheet.getCellByPosition(i,0).setString(aGrid.Columns.Items[i].Title.Caption); //aqui resolvi pegar o titulo do DBGrid
i := i + 1;
end;

// Preenche a planilha
j := 1;
aGrid.DataSource.DataSet.First;
while not aGrid.DataSource.DataSet.Eof do
begin
i := 0;
while i <= aGrid.FieldCount - 1 do
begin
if aGrid.Fields[i].DataType in [ftDate, ftTime, ftDateTime] then
begin
if ((DateToStr(aGrid.Fields[i].Value) <> Null) and (DateToStr(aGrid.Fields[i].Value) <> '')) then
Sheet.getCellByPosition(i,j).SetString(aGrid.Fields[i].Value);
end
else if aGrid.Fields[i].DataType in [ftSmallint, ftInteger, ftLargeint] then
begin
if ((IntToStr(aGrid.Fields[i].Value) <> Null) and (IntToStr(aGrid.Fields[i].Value) <> '')) then
Sheet.getCellByPosition(i,j).SetValue(aGrid.Fields[i].Value);
end
else if aGrid.Fields[i].DataType in [ftFloat, ftCurrency] then
begin
if ((FloatToStr(aGrid.Fields[i].Value) <> Null) and (FloatToStr(aGrid.Fields[i].Value) <> '')) then
Sheet.getCellByPosition(i,j).SetValue(aGrid.Fields[i].Value);
end
else begin
if ((aGrid.Fields[i].Value <> Null) and (aGrid.Fields[i].Value <> '')) then
begin
teste := '';
teste := aGrid.Fields[i].Value;
Sheet.getCellByPosition(i,j).SetString(teste);
end;
end;

i := i + 1;
end;
aGrid.DataSource.DataSet.Next;
j := j + 1;
end;
Screen.Cursor := crArrow;
// Desconecta o OpenOffice
OpenOffice := Unassigned;
ShowMessage('Planilha Gerada');

//o segredo de pegar a dbgrid inteira é ir para primeira linha e coluna do DBGrid
ZTableAgencias.FindFirst; //Minha tabela no Zeos
aGrid.SelectedField := aGrid.Columns[0].Field;
aGrid.SelectedIndex:=0;
aGrid.SetFocus;

exit;
end;
end;
end;
end;
//fim

Agradeço o código que encontrei aqui, pq através dele pude modificar para meu uso.
Espero ter ajudado aqueles que precisam transferir apenas o DBGrid para o OpenOffice (SCalc)

Att. Claudio
GOSTEI 0
Claudio

Claudio

31/10/2006

Valeu mesmo
GOSTEI 0
Ismael Liborio

Ismael Liborio

31/10/2006

Boas,

Em relação ao tema, e depois de alguma pesquisa, encontro muita matéria sobre como exportar dados do Delphi para calc utilizando o OpenOffice. Mas questão mantém-se, como consigo importar um ficheiro .xls ou .ods ou .xlsx para uma StringGrid só tendo o OpenOffice ou LibreOffice instalado? Alguém pode ajudar por favor. Utilizo o Delphi 10 Seattle.
Muito obrigado.
GOSTEI 0
Flavio Silva

Flavio Silva

31/10/2006

Estou lançando a versão que funcionou aqui no windows XP com o Libre Office 5.4


procedure TForm1.geraRelatorioLibreOffice(ADataSet: TClientDataSet);
var
OpenDesktop, Calc, Sheets, Sheet: Variant;
Connect, OpenOffice : Variant;
i : Integer; // Coluna
j : Integer; // Linha
teste : string;
campo : TField;
begin


Screen.Cursor := crSQLWait;
//aDataset.Open;
//aDataset.Last;

// Cria o link OLE com o OpenOffice
if VarIsEmpty(OpenOffice) then
OpenOffice := CreateOleObject('com.sun.star.ServiceManager');
Connect := not (VarIsEmpty(OpenOffice) or VarIsNull(OpenOffice));

// Inicia o Calc
OpenDesktop := OpenOffice.CreateInstance('com.sun.star.frame.Desktop');
Calc := OpenDesktop.LoadComponentFromURL('private:factory/scalc', '_blank', 0, VarArrayCreate([0, - 1], varVariant));

Sheets := Calc.Sheets;
Sheet := Sheets.getByIndex(0);

// Cria linha de cabeçalho
i := 0;
while i <= aDataset.FieldCount - 1 do begin
Sheet.getCellByPosition(i,0).setString(aDataset.Fields[i].FieldName);
i := i + 1;
end;

// Preenche a planilha
j := 1;
aDataset.First;
while not aDataset.Eof do
begin
i := 0;
while i <= aDataset.FieldCount - 1 do
begin
//sheet.getCellByPosition(i,j).SetString(aDataset.Fields[i].Value);
//Continue;
if aDataset.Fields[i].DataType in [ftDate, ftTime, ftDateTime] then
begin
if ((DateToStr(aDataset.Fields[i].Value) <> Null) and (DateToStr(aDataset.Fields[i].Value) <> '')) then
Sheet.getCellByPosition(i,j).SetString(aDataset.Fields[i].Value);
end
else if aDataset.Fields[i].DataType in [ftSmallint, ftInteger, ftLargeint] then
begin
if ((IntToStr(aDataset.Fields[i].Value) <> Null) and (IntToStr(aDataset.Fields[i].Value) <> '')) then
Sheet.getCellByPosition(i,j).SetValue(aDataset.Fields[i].AsFloat);
end;
inc(i);
end;
AdataSet.Next;
end;
Sheets := Calc.Sheets;
Sheet := Sheets.getByIndex(0);

// Cria linha de cabeçalho
i := 0;
while i <= aDataset.FieldCount - 1 do begin
Sheet.getCellByPosition(i,0).setString(aDataset.Fields[i].FieldName);
i := i + 1;
end;

// Preenche a planilha
j := 1;
aDataset.First;
while not aDataset.Eof do
begin
i := 0;
while i <= aDataset.FieldCount - 1 do
begin
if aDataset.Fields[i].DataType in [ftDate, ftTime, ftDateTime] then
begin
if ((DateToStr(aDataset.Fields[i].Value) <> Null) and (DateToStr(aDataset.Fields[i].Value) <> '')) then
Sheet.getCellByPosition(i,j).SetString(aDataset.Fields[i].Value);
end
else if aDataset.Fields[i].DataType in [ftSmallint, ftInteger, ftLargeint] then
begin
if ((IntToStr(aDataset.Fields[i].Value) <> Null) and (IntToStr(aDataset.Fields[i].Value) <> '')) then
Sheet.getCellByPosition(i,j).SetValue(aDataset.Fields[i].Value);
end
else if aDataset.Fields[i].DataType in [ftFloat, ftCurrency] then
begin
if ((FloatToStr(aDataset.Fields[i].Value) <> Null) and (FloatToStr(aDataset.Fields[i].Value) <> '')) then
Sheet.getCellByPosition(i,j).SetValue(aDataset.Fields[i].Value);
end
else begin
if ((aDataset.Fields[i].Value <> Null) and (aDataset.Fields[i].Value <> '')) then
begin
teste := '';
teste := aDataset.Fields[i].Value;
Sheet.getCellByPosition(i,j).SetString(teste);
end;
end;

i := i + 1;
end;
aDataset.Next;
j := j + 1;
end;
Screen.Cursor := crArrow;
OpenOffice := Unassigned;
ShowMessage('Planilha Gerada');

end;

procedure TForm1.Button1Click(Sender: TObject);
var
cds: TClientDataSet;

begin
cds := TClientDataSet.Create(Self);
cds.Close;
cds.FieldDefs.Clear;
cds.FieldDefs.add('CODIGO', ftInteger);
cds.FieldDefs.add('NOME', ftString, 50);
cds.CreateDataSet;
cds.Append;
cds.Fields[0].AsInteger := 1;
cds.Fields[1].AsString := 'FLAVIO';
cds.Post;
cds.Append;

cds.Fields[0].AsInteger := 2;
cds.Fields[1].AsString := 'LEONARDO';
cds.Post;
cds.Append;

cds.Fields[0].AsInteger := 3;
cds.Fields[1].AsString := 'BLUMENAU';
cds.Post;

geraRelatorioLibreOffice(cds);
end;

GOSTEI 0
Daniel Fernandes

Daniel Fernandes

31/10/2006

Saudações gente,
eu sei que muita gente já falou sobre isso e antes de postar eu dei uma verificada na pesquisa mas não consegui encontrar algo concreto sobre o assunto. Como posso fazer com que o OpenOffice (ou BrOffice) abra uma arquivo xls ou como abrir uma planilha sem possuir o Excel utilizando uma destas duas suítes?
Achei e já utilizo uma função que exporta para OpenOffice mas não consigo achar uma maneira de fazer o inverso. Será que alguém pode me ajudar nisto?
Ah! para este caso estou usando o Delphi 5.0 Pro, MySql 5.0 e Paleta MySqlDAC. É porque estou trabalhando em dois projetos e existem mensagens minhas com Delphi 7 e PostGreSql...
Muito obrigado.




Olá bom dia, eu desenvolvi um componente para trabalhar com o OpenOffice (LibreOffice...) que resolve o que precisa, segue meu projeto no github, tem um demo de documentação.
https://github.com/Daniel09Fernandes/Component_OpenOffice_Calc
GOSTEI 0
POSTAR