Como ler um .doc (MS Word) sem ter o Word instalado.
23/06/2008
0
Mkoch
Posts
24/06/2008
Mkoch
24/06/2008
Massuda
De qualquer forma, algumas opções:[list:7b721ae97f][*:7b721ae97f]usar o OpenOffice para ler ou converter o arquivo (não sei como se faz isso via programa)[*:7b721ae97f]usar o :arrow: [url=http://www.abisource.com/]AbiWord[/url] (um clone do Word) para ler ou converter o arquivo (tb não sei como se faz isso via programa)[*:7b721ae97f]estudar a especificação do formato .DOC (em inglês, :arrow: [url=http://www.microsoft.com/interop/docs/OfficeBinaryFormats.mspx]nesta página[/url]) e tentar ler o arquivo[/list:u:7b721ae97f]
24/06/2008
Mkoch
uses ComObj, ActiveX, AxCtrls; procedure TForm1.OpenWord(const aFileName: WideString); var Root: IStorage; EnumStat: IEnumStatStg; Stat: TStatStg; iStm: IStream; Stream: TOleStream; DocTextString: String; xText: String; i: Integer; begin if not FileExists(aFileName) then Exit; // Check to see if it´s a structured storage file if StgIsStorageFile(PWideChar(aFileName)) <> S_OK then Exit; // Open the file OleCheck(StgOpenStorage(PWideChar(aFileName), nil, STGM_READ or STGM_SHARE_EXCLUSIVE, nil, 0, Root)); // Enumerate the storage and stream objects contained within this file OleCheck(Root.EnumElements(0, nil, 0, EnumStat)); // Check all objects in the storage while EnumStat.Next(1, Stat, nil) = S_OK do // Is it a stream with Word data if Stat.pwcsName = ´WordDocument´ then //if Stat.pwcsName <> ´mk´ then // Try to get the stream "WordDocument" if Succeeded(Root.OpenStream(Stat.pwcsName, nil, STGM_READ or STGM_SHARE_EXCLUSIVE, 0, iStm)) then begin Stream:=TOleStream.Create(iStm); try if Stream.Size > 0 then begin // Move text data to string variable SetLength(xText, Stream.Size); Stream.Seek(0, soFromBeginning); Stream.Read(PChar(xText)^, Stream.Size); if xText <> ´´ then begin end; // Find a necessary text // Memo1.Lines.Append(String(DocTextString)); i := Pos(´Teste´, xText); //COMO PODE ACHAR (E ACHA), VEM CHEIO DE "SUJEIRA???". if i > 0 then begin ShowMessage(´Achou!!!´); end; end; finally Stream.Free; end; //Exit; end; end;
26/06/2008
Massuda
Tenho um sistema que depende da conversão de DOC para TXT. Sinceramente, esse caminho que você está seguindo tem complicações relacionadas com o modo que o texto foi digitado e com a versão do Word que foi utilizada.
A solução inicial foi usar o pacote :arrow: [url=http://wvware.sourceforge.net/]wvWare[/url] para fazer a conversão (vc precisa do MinGW ou do Cygwin para compilar um executável para Windows). Mas com frequencia o conversor travava ou perdia parte do texto devido ao documento Word conter algo diferente do padrão (por exemplo, uma imagem ou uma formatação mais complexa).
Para evitar isso, hj usamos um Word 2008 para converter os DOC para DOCX, que é um formato documentado pela MS e normatizado pela especificação OpenXML, de modo que hoje tenho um programa Delphi capaz de processar diretamente os DOCX. No futuro, espero não precisar mais do Word pois a MS está providenciando um conversor DOC para DOCX como parte do esforço para estabelecer o padrão OpenXML.
01/07/2008
Mkoch
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, StdCtrls, OleServer, ComCtrls;
implementation
uses
ComObj, ActiveX, AxCtrls;
procedure TForm1.OpenWord(const aFileName: WideString);
const
cFib = 1472;
var
Root: IStorage;
EnumStat: IEnumStatStg;
Stat: TStatStg;
iStm: IStream;
Stream: TOleStream;
DocText, xText: String;
xFib: String;
xFC, xLCB: Integer;
xFlag1Table: Boolean;
xTableStreamName: String;
fcMin, ccpText, fcClx, lcbClx: Integer;
begin
if not FileExists(aFileName) then Exit;
// Check to see if it´s a structured storage file
if StgIsStorageFile(PWideChar(aFileName)) <> S_OK then Exit;
// Open the file
OleCheck(StgOpenStorage(PWideChar(aFileName), nil, STGM_READ or STGM_SHARE_EXCLUSIVE, nil, 0, Root));
// Enumerate the storage and stream objects contained within this file
OleCheck(Root.EnumElements(0, nil, 0, EnumStat));
// Check all objects in the storage
while EnumStat.Next(1, Stat, nil) = S_OK do
// Try to get the stream ´WordDocument´
if Succeeded(Root.OpenStream(Stat.pwcsName, nil,
STGM_READ or STGM_SHARE_EXCLUSIVE, 0, iStm)) then
begin
Stream:=TOleStream.Create(iStm);
try
if Stream.Size > 0 then
begin
if Stat.pwcsName = ´WordDocument´ then
begin
Stream.Seek(24, soFromBeginning);
Stream.ReadBuffer(fcMin, SizeOf(Integer));
Stream.Seek(76, soFromBeginning);
Stream.ReadBuffer(ccpText, SizeOf(Integer));
Stream.Seek(418, soFromBeginning);
Stream.ReadBuffer(fcClx, SizeOf(Integer));
Stream.Seek(422, soFromBeginning);
Stream.ReadBuffer(lcbClx, SizeOf(Integer));
if (fcMin > 0) and (ccpText > 0) then
begin
SetLength(xText, ccpText);
Stream.Seek(fcMin + 512, soFromBeginning);
Stream.ReadBuffer(PChar(xText)^, ccpText);
RichEdit1.Text := xText;
end;
end;
end;
finally
Stream.Free;
end;
end;
end;
Clique aqui para fazer login e interagir na Comunidade :)