3

我正在使用 OLE 搜索替换将“占位符标签”替换为存储在 db 字段中的内容到 Word 文档中。我使用类似于这里讨论的技术。

这有效,但当然不适用于 rtf 字段。我有包含 rtf 数据的 db 字段,如果进行搜索替换,我将获得完整的 rtf 代码,因此不会看到

你好世界

我看到类似的东西

{\rtf1\ansi\ansicpg1252\deff0\deflang1040\viewkind4\uc1\pard\sa200\sl276\slmult1\lang16\b\f0\fs22 Hello \i World\b0\i0\par }

有没有人已经解决了这个问题?在 StackOverflow 上搜索我发现了一个使用剪贴板的技巧。注意:我不使用书签,此示例使用书签,我只是将我的标签定义为纯文本,如 '',当我在搜索和替换循环中找到 '' 时,我会替换文本。

更新:你在这个剪贴板技巧中看到任何问题吗?

您有其他想法并可以提出其他解决方案吗?

4

2 回答 2

1

我建议改用 Selection.InsertFile。这是一个应该做你想做的事的例子,它找到“占位符”并插入一个 rtf 文件。在...之前将您的 rtf 保存到临时文件中

 procedure TForm1.Button1Click(Sender: TObject);
var
  Fword,FDocument,FFindObject:OleVariant;
  Filename:String;

begin
   Filename := 'C:\temp\test.doc';
   Fword := CreateOleObject('Word.Application');
   FDocument := Fword.Documents.Add(Filename);
   FFindObject := FDocument.ActiveWindow.Selection.Find;
   Fword.visible := true;
   FFindObject.ClearFormatting;
   FFindObject.Replacement.ClearFormatting;
   FFindObject.Text := 'placeholder';
   FFindObject.Forward := True;
   FFindObject.Replacement.Text := '';
   FFindObject.Wrap := 1;
   FFindObject.MatchCase := False;
   FFindObject.MatchWholeWord := False;
   FFindObject.MatchWildcards := False;
   FFindObject.MatchSoundsLike := False;
   FFindObject.MatchAllWordForms := False;

   if FFindObject.Execute() then Fword.selection.InsertFile('C:\temp\test.rtf')   
end; 
于 2011-11-17T13:07:48.740 回答
0

这是我很久以前保存的帖子。它是由 TeamB 的 Peter Above 博士发布到旧的 Borland Delphi 新闻组,但它今天仍然适用。它展示了如何使用EM_STREAMINandEM_STREAMOUT消息和相关回调将 RTF 文本放入和复制出TRichEdit.

Uses RichEdit;

Type
  TEditStreamCallBack = function (dwCookie: Longint; pbBuff: PByte;
    cb: Longint; var pcb: Longint): DWORD; stdcall;

  TEditStream = record
    dwCookie: Longint;
    dwError: Longint;
    pfnCallback: TEditStreamCallBack;
  end;

function EditStreamInCallback(dwCookie: Longint; pbBuff: PByte;
 cb: Longint; var pcb: Longint): DWORD; Stdcall;
var
  theStream: TStream;
  dataAvail: LongInt;
begin
  theStream := TStream(dwCookie);
  with theStream do begin
    dataAvail := Size - Position;
    Result := 0; {assume everything is ok}
    if dataAvail <= cb then begin 
      pcb := Read(pbBuff^, dataAvail); 
      if pcb <> dataAvail then  //couldn't read req. amount of bytes
        result := E_FAIL; 
    end 
    else begin
      pcb := Read(pbBuff^, cb); 
      if pcb <> cb then 
        result := E_FAIL; 
    end;
  end;
end;


Function EditStreamOutCallback(dwCookie: Longint; pbBuff: PByte;
    cb: Longint; var pcb: Longint): DWORD; stdcall;
 var
   theStream: TStream;
 begin
   theStream := TStream(dwCookie);

   with theStream do begin
     If cb > 0 Then 
       pcb := Write(pbBuff^, cb);
     Result := 0;
   end;
 end;

Procedure GetRTFSelection( aRichEdit: TRichEdit; intoStream: TStream );
Var
  editstream: TEditStream;
Begin
  With editstream Do Begin
    dwCookie:= Longint(intoStream);
    dwError:= 0;
    pfnCallback:= EditStreamOutCallBack;
  end;
  aRichedit.Perform( EM_STREAMOUT, SF_RTF or SFF_SELECTION, longint(@editstream));
End;

Procedure PutRTFSelection( aRichEdit: TRichEdit; sourceStream: TStream );
Var
  editstream: TEditStream;
Begin
  With editstream Do Begin
    dwCookie:= Longint(sourceStream);
    dwError:= 0;
    pfnCallback:= EditStreamInCallBack;
  end;
  aRichedit.Perform( EM_STREAMIN, SF_RTF or SFF_SELECTION, longint(@editstream));
End;
于 2011-11-17T14:31:43.813 回答