就OLE了吧,看到以前读表格的代码大概: ... WordApp: TWordApplication; WordDoc: TWordDocument; 一堆OleVariant变量。。。 ... WordApp:= TWordApplication.Create(nil); WordDoc:= TWordDocument.Create(nil); WordApp.Documents.open(FileName,EmptyParam,true,EmptyParam,EmptyParam,...); WordDoc.ConnectTo(WordApp.Documents.Item(1)); For i := 1 To WordDoc.Tables.Count do begin myRow:=WordDoc.Tables.Item(i).Rows.Item(1); ... For j:= 1 To myRow.Cells.Count do begin myCell:=WordDoc.Tables.Item(i).Cell(1,j); ... end; end; ...
----------------------------------------------
Bye bye DDRFAN...
procedure TForm1.sButton1Click(Sender: TObject); var Run: TgtRun; DOCDocument: TgtxDOCDocument; Section: TgtSection; Paragraph: TgtParagraph; RunItem, ParaItem, TextItemItem: TgtDocItem; TextItem: TgtTextItem; PageElements: TObjectList<TgtDocItem>; begin DOCDocument := TgtxDOCDocument.Create; DOCDocument.LoadFromFile(sFilenameEdit1.Text); for Section in DOCDocument.DOCHandler.Sections do begin for ParaItem in Section.Items do begin Paragraph := ParaItem as TgtParagraph; for RunItem in Paragraph.Items do begin if RunItem Is TgtRun then begin Run := RunItem as TgtRun; for TextItemItem in Run.Items do begin if TextItemItem is TgtTextItem then begin TextItem := TextItemItem as TgtTextItem; Showmessage(TextItem.Text); end; end; // } end; end; end; end; DOCDocument.Free; end; XtremeDocumentStudio Delphi解析类可以处理,但对doc中文文档有兼容性问题.
----------------------------------------------
正在尝试自己解析doc文本,在对类Free时产生错误,实在找不到原因,请教各位: 原码如下: constructor TDocFile.Create(filename: string); begin FOK:=false; FIsdoc := false; try FStream := TFileStream.Create(filename, fmOpenRead or fmShareDenyNone); if FStream.Size>512 then GetDocheader else raise Exception.Create('Doc文件打开失败:' + filename); except raise Exception.Create('Doc文件打开失败:' + filename); end; end;
destructor TDocFile.Destroy; begin if Assigned(FStream) then FreeAndNil(FStream); inherited; end;// 就是在执行到这里时,会跳到system单元的这个函数 //procedure TMonitor.Destroy; //begin // if (MonitorSupport <> nil) and (FLockEvent <> nil) then 在这句里出错 // MonitorSupport.FreeSyncObject(FLockEvent); // SysFreeMem(@Self); //end;
procedure TDocFile.free; begin if self<>nil then Destroy; end;
function TDocFile.GetDirectory: TDOC_Directory; begin // end;
function TDocFile.GetDocheader: TDocHeader; begin if Assigned(FStream) then begin FStream.Position := 0; if FStream.Read(FHeaderinfo, SizeOf(TDocHeader)) <> 512 then raise Exception.Create('Doc文件头信息获取失败。') else begin FOk:=true; setisdoc; if fisdoc then GetFirstDirectory; end; end; end;
function TDocFile.GetFirstDirectory: TDOC_Directory; function IntPower(Base: integer; const Exponent: LongWord):Int64; var I: Integer; begin if Expon_ent=0 then result:=1 else if Expon_ent=1 then result:=base else begin result:=Base; for I := 2 to Exponent do result:=result*base; end; end;
begin Fstream.Position:=512+IntPower(2,fheaderinfo.sectorSize)*fheaderinfo.startDirectory; FStream.Read(FFirstDirectory,128); end;
function TDocFile.loadfromfile(filename: string): boolean; begin FreeAndNil(FStream); Fstream:=TFileStream.Create(filename,fmOpenRead or fmShareDenyNone); if FStream.Size>512 then GetDocheader else raise Exception.Create('Doc文件打开失败:' + filename); end;
function TDocFile.loadfromstream(stream: tstream): boolean; begin Fstream.CopyFrom(stream); if FStream.Size>512 then GetDocheader else raise Exception.Create('Doc文件打开失败'); end;
procedure TDocFile.setisdoc; begin if FOk then begin if (FHeaderinfo.doctag[0] = $D0) and (FHeaderinfo.doctag[1] = $CF) and (FHeaderinfo.doctag[2] = $11) and (FHeaderinfo.doctag[3] = $E0) and (FHeaderinfo.doctag[4] = $A1) and (FHeaderinfo.doctag[5] = $B1) and (FHeaderinfo.doctag[6] = $1A) and (FHeaderinfo.doctag[7] = $E1) then FIsdoc := True end else FIsdoc:=false; end;
你的 TDocFile 有没有用到 OLE 去处理 WORD 文档?如果使用 OLE 的话,同时又是在多线程中使用的话,可能会有很多问题。至少需要考虑执行 ActiveX.CoInitialization 这样的代码来使得多线程中调用 OLE (实际上是 COM 或者 DCOM)满足多线程调用 COM 的基本要求。
----------------------------------------------
-
而且:如果字数多的话,下面过程也是错误: if OfficeFileToStr(PwideChar(od.FileName),@Ptext) then //Ptext不能是局部变量 begin memo1.Lines.Text:='abc';//这句也是出错 LocalFree(HLOCAL(pText)); end;
----------------------------------------------
tuao
function OfficeFileToStr(pwszFileName: PWideChar; ppText: PPWideChar): BOOL; stdcall; var wstrText: WideString; nLen:Integer; begin Result := False; wstrText := OfficeFileToTxt(pwszFileName); if wstrText = '' then Exit;
nLen:=Length(wstrText)*2;
ppText^:= Pointer(LocalAlloc(LPTR,nLen+2)); if ppText^=nil then Exit; Move(wstrText[1],ppText^^,nLen);//原来写成了ppText^,这里应该是指针的指针 Result:=True; end;
我安装了delphi7,自己封装了一个dll,可以正常在D7和10.4下使用,直接使用Widestring作为参数和返回值,代码就一句,简单明了,对于其他语言可能不能兼容,但我仅仅用在delphi上,没有任何问题: function OfficeFileToStr(FileName: Widestring): widestring; stdcall; begin Result := OfficeFileToTxt(FileName); end;
----------------------------------------------
tuao