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

Demos, code samples. Only questions related to the existing topics are allowed here.
Post Reply
Sergey Tkachenko
Site Admin
Posts: 17559
Joined: Sat Aug 27, 2005 10:28 am
Contact:

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

Post 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)
Last edited by Sergey Tkachenko on Sun Feb 13, 2011 9:47 am, edited 3 times in total.
Sergey Tkachenko
Site Admin
Posts: 17559
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post 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;
Last edited by Sergey Tkachenko on Thu Dec 11, 2008 4:18 pm, edited 1 time in total.
Sergey Tkachenko
Site Admin
Posts: 17559
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post 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.
Sergey Tkachenko
Site Admin
Posts: 17559
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

The same as above, but without empty line at the beginning:
multiorientation2.zip
(3.7 KiB) Downloaded 5129 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
Sergey Tkachenko
Site Admin
Posts: 17559
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Saving several documents in DocX, with different page orientations

Post by Sergey Tkachenko »

The same as above, but for DocX:
multiorientation-docx.zip
(4.36 KiB) Downloaded 4693 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.
Post Reply