Вставьте текст RTF в документ Word - PullRequest
2 голосов
/ 16 ноября 2011

Я использую OLE Search Replace, чтобы заменить «метки-заполнители» содержимым, хранящимся в полях БД, в документ Word.Я использую технику, похожую на то, что здесь рассмотрено .

Это работает, но, конечно, не для полей rtf.У меня есть поля БД, содержащие данные RTF, и если поиск заменяет, я получу полный код RTF, поэтому вместо просмотра

Hello World

Я вижу что-то вроде

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

Кто-нибудь уже решил проблему?В поисках StackOverflow я обнаружил трюк, использующий буфер обмена .Примечание: я не использую закладки, в этом примере используются закладки, у меня просто есть теги, определенные как простой текст, такие как '', и когда я нахожу '' в цикле поиска и замены, я заменяю текст.

ОБНОВЛЕНИЕ: Вы видите какую-либо проблему в этом трюке с буфером обмена?

У вас есть другие идеи и вы можете предложить другие решения?

Ответы [ 2 ]

0 голосов
/ 17 ноября 2011

Вот пост, который я сохранил много лет назад.Он был опубликован доктором Питером Белоу из TeamB в старых новостных группах Borland Delphi, но он все еще применим сегодня.В нем показано, как использовать сообщения EM_STREAMIN и EM_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;
0 голосов
/ 17 ноября 2011

Я бы предложил вместо этого использовать 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; 
...