Page 1 of 1

[Example] Saving additional information in RTF files (and in DocX too)

Posted: Tue Sep 06, 2005 5:47 pm
by Sergey Tkachenko
Use OnSaveRTFExtra event:

Saving margins

Code: Select all

procedure TForm3.RichViewEdit1SaveRTFExtra(Sender: TCustomRichView;
  Area: TRVRTFSaveArea; Obj: TObject; Index1, Index2: Integer;
  InStyleSheet: Boolean; var RTFCode: TRVUnicodeString);

  function MMToTwips(mm: Integer): Integer;
  begin
    Result := Round(mm*1440*5/127);
  end;

begin
  // uncomment "AnsiStrings." if you use Delphi 2009+
  if Area=rv_rtfs_Doc then
    RTFCode := {AnsiStrings.}Format('\margl%d\margt%d\margr%d\margb%d',
      [MMToTwips(RVPrint1.LeftMarginMM),
       MMToTwips(RVPrint1.TopMarginMM),
       MMToTwips(RVPrint1.RightMarginMM),
       MMToTwips(RVPrint1.BottomMarginMM)]);
end;
Note: since TRichView v10, you can save and load margins specified in DocParameters.

Saving plain text header and footer

Code: Select all

procedure TForm3.RichViewEdit1SaveRTFExtra(Sender: TCustomRichView;
  Area: TRVRTFSaveArea; Obj: TObject; Index1, Index2: Integer;
  InStyleSheet: Boolean; var RTFCode: TRVUnicodeString);
begin
  if Area=rv_rtfs_Doc then
    RTFCode :=
     '{\header\pard\plain\posxc THIS IS HEADER WITH PAGENUMBER: {\field{\*\fldinst PAGE}{\fldrslt 1}}\par}'+
     '{\footer\pard\plain\posxr THIS IS FOOTER\par}';
end;
In this example:
\posxc - keyword for aligning header/footer to center
\posxr - keyword for aligning header/footer to right
{\field{\*\fldinst PAGE}{\fldrslt 1}} - code for inserting page number
Note: since TRichView v11, you can save and load header and footer in other richviews, see rvrtfSaveHeaderFooter in RTFOptions

[+] History of updates
2018-Apr-9: for compatibility with TRichView 17.3 (the type of RTFCode parameter is changed from TRVAnsiString to TRVUnicodeString)

Posted: Sat Nov 25, 2006 4:52 pm
by Sergey Tkachenko
How to save several documents in on RTF file so that page numbers restarted on each subdocument.

Assuming that subdocuments are stored in RVF files.

The main procedure:

Code: Select all

procedure CreateRTFWithSections(const RVFFiles: array of String;
  const RTFFile: String; rv: TCustomRichView);
var i: Integer;
    Stream: TFileStream;
begin
  rv.Clear;
  with rv.Style do begin
    TextStyles.Clear;
    TextStyles.Add;
    with TextStyles.Add do
      Options := [rvteoRTFCode];
    ParaStyles.Clear;
    ParaStyles.Add;
    ListStyles.Clear;
  end;
  for i := Low(RVFFiles) to High(RVFFiles) do
    try
      Stream := TFileStream.Create(RVFFiles[i], fmOpenRead);
      try
        rv.InsertRVFFromStream(Stream, rv.ItemCount);
        if i<>High(RVFFiles) then
          rv.AddNL('\sect\pgnrestart', 1, 0);
      finally
        Stream.Free;
      end;
    except
      rv.AddNL('Error loading file', 0, 0);
    end;
  rv.SaveRTF(RTFFile, False);
end;
OnSaveRTFExtra event

Code: Select all

procedure TForm1.RichView1SaveRTFExtra(Sender: TCustomRichView;
  Area: TRVRTFSaveArea; Obj: TObject; Index1, Index2: Integer;
  InStyleSheet: Boolean; var RTFCode: TRVUnicodeString);
begin
  case Area of
    rv_rtfs_Doc:
      RTFCode :=
       '{\header\pard\plain\posxc - {\field{\*\fldinst PAGE}{\fldrslt 1}} -\par}';
     rv_rtfs_TextStyle:
       if Index1=1 then
         RTFCode := '\v'; // making TextStyles[1] hidden, otherwise empty line
           // appears at the top of sections
  end;
end;
Example:

Code: Select all

  CreateRTFWithSections(['doc1.rvf', 'doc2.rvf', 'doc3.rvf'], 'Result.rtf', RichView1);
  RichView1.Format; // if you want to display
end;

Posted: Thu Dec 13, 2007 10:44 am
by Sergey Tkachenko
Similar example, how to save RTF with several sections, each section has its own orientation: http://www.trichview.com/support/files/ ... tation.zip

This example has a small problem: empty line at the beginning of each section. To minimize this problem, this line has a very small size.

Posted: Thu Jan 28, 2010 11:22 am
by Sergey Tkachenko
The same as above, but without empty line at the beginning:
multiorientation2.zip
(3.7 KiB) Downloaded 1892 times
The reason why this empty line occurs is the following.
To prevent its appearing, RTF code must contain '\sect' (section break) instead of '\par' (paragraph break). The previous code wrote '\sect' in addition to '\par', because there is no documented way for not-saving '\par', if the item starts a new paragraph. And the document representing a new section must start a new paragraph, otherwise paragraph attributes of the first line will be lost.

How it is solved:
1) RTF code (text having style TextStyles[1], with rvteoRTFCode in Option) is written to the end of the section, not from the new line.

2) When writing this text in RTF, OnSaveItemToFile occurs. In this event, we include rvstRTFSkipPar in RVData.State. This flag forces TRichView to skip saving the next paragraph break ('\par'). This flag is used internally for saving some special items, but here it helps to solve the problem with the empty line.

[+] History of updates
2018-Apr-9: for compatibility with TRichView 17.3
[+] Old versions
http://www.trichview.com/support/files/ ... ation2.zip - for TRichView versions prior to 17.3

Saving several documents in DocX, with different page orientations

Posted: Thu Aug 20, 2020 3:42 pm
by Sergey Tkachenko
The same as above, but for DocX:
multiorientation-docx.zip
(4.36 KiB) Downloaded 1578 times
This demo shows how to create a DocX file from several documents, with different page orientations.

This demo uses a different method than the RTF demos above, it creates a special object in document that adds a section break.