Page 1 of 1

Load RVF with footer and save to RTF

Posted: Fri May 12, 2017 6:36 pm
by arkinform
Hello!

We use TRichView for own simple report processing. We make and save RVF templates. When user execute template, we load RVF, replace some variables and save to RTF for opening with MS Word or LibreOffice. It works fine, but we have one problem: RVF with footer is loaded without it. We can set footer manualy (commented lines) and it works, but how to get footer from RVF and why procedure LoadRVF does not load footers?

Code: Select all

RichView.RTFReadProperties.ReadDocParameters := True;
RichView.RTFReadProperties.ParaStyleMode     := rvrsAddIfNeeded;
RichView.RTFReadProperties.TextStyleMode     := rvrsAddIfNeeded;
RichView.RTFReadProperties.UnicodeMode       := rvruOnlyUnicode;

RichView.RVFOptions := [rvfoLoadDocProperties, rvfoSaveDocProperties,
      rvfoSavePicturesBody, rvfoSaveControlsBody,
      rvfoIgnoreUnknownPicFmt, rvfoIgnoreUnknownCtrls,
      rvfoConvUnknownStylesToZero, rvfoConvLargeImageIdxToZero,
      rvfoSaveBinary, rvfoSaveBack, rvfoLoadBack,
      rvfoSaveTextStyles, rvfoSaveParaStyles, rvfoSaveLayout,
      rvfoLoadLayout];

RichView.RTFOptions :=
      [rvrtfDuplicateUnicode, rvrtfSaveEMFAsWMF,
       rvrtfSaveJpegAsJpeg, rvrtfSavePngAsPng,
       rvrtfSaveDocParameters, rvrtfSaveHeaderFooter,
       rvrtfSavePicturesBinary];

RichView.LoadRVF('c:\temp\template.rvf');

// RichFooter.LoadText('c:\temp\footer.txt', 0, 0, True);
// RichView.RTFReadProperties.SetFooter(RichFooter.RVData);

RichView.SaveRTF('c:\temp\result.rtf', False);

Re: Load RVF with footer and save to RTF

Posted: Sat May 13, 2017 8:21 pm
by Sergey Tkachenko
Automatic loading of headers and footers from RVF is implemented only in ScaleRichView.

For TRichView, it's not documented but possible.

Call (before saving and loading):

Code: Select all

with RichView.GetExtraDocuments do
begin
  Clear;
  AddObject('header', RichHeader.RVData);
  AddObject('footer', RichFooter.RVData);
  // you can also specify first page and even pages header/footers using identifiers: headerf, footerf, headerr, footerr.
end;

Re: Load RVF with footer and save to RTF

Posted: Mon Sep 11, 2017 9:34 pm
by arkinform
Sorry for answer with very long delay.
I have tried your code. In this case I see footer in output RTF document, but I lose some formatting from the original RVF document (bold, alignment and etc). And more, when I remove rvfoConvUnknownStylesToZero from FRichView.RVFOptions, the output RTF document does not contain some text at all. Without processing footer (comment block with FRichView.RVData.ExtraDocumentsList and SetFooter) LoadRVF --> SaveRTF works fine.

Code: Select all

var
  FRichView: TRichView;
  FRichViewHeader: TRichView;
  FRichViewFooter: TRichView;
  FRichStyle        : TRVStyle;
  FRichStyle2       : TRVStyle;
  FRichStyle3       : TRVStyle;
begin
  FRichView         := TRichView.Create(nil);
  FRichViewHeader   := TRichView.Create(nil);
  FRichViewFooter   := TRichView.Create(nil);

  FRichStyle        := TRVStyle.Create(nil);
  FRichStyle2       := TRVStyle.Create(nil);
  FRichStyle3       := TRVStyle.Create(nil);
  try
    FRichView.Visible      := False;
    FRichView.Parent       := Self;
    FRichView.Style        := FRichStyle;

    FRichViewHeader.Visible      := False;
    FRichViewHeader.Parent       := Self;
    FRichViewHeader.Style        := FRichStyle;

    FRichViewFooter.Visible      := False;
    FRichViewFooter.Parent       := Self;
    FRichViewFooter.Style        := FRichStyle;

    FRichView.RTFReadProperties.TextStyleMode := rvrsAddIfNeeded;
    FRichView.RTFReadProperties.ParaStyleMode := rvrsAddIfNeeded;
    FRichView.RTFReadProperties.UnicodeMode := rvruOnlyUnicode;

    FRichViewHeader.RTFOptions := FRichView.RTFOptions;
    FRichViewHeader.RTFReadProperties.TextStyleMode := rvrsAddIfNeeded;
    FRichViewHeader.RTFReadProperties.ParaStyleMode := rvrsAddIfNeeded;
    FRichViewHeader.RTFReadProperties.UnicodeMode := rvruOnlyUnicode;

    FRichViewFooter.RTFOptions := FRichView.RTFOptions;
    FRichViewFooter.RTFReadProperties.TextStyleMode := rvrsAddIfNeeded;
    FRichViewFooter.RTFReadProperties.ParaStyleMode := rvrsAddIfNeeded;
    FRichViewFooter.RTFReadProperties.UnicodeMode := rvruOnlyUnicode;

    FRichView.RVFOptions := [rvfoLoadDocProperties, rvfoSaveDocProperties,
          rvfoSavePicturesBody, rvfoSaveControlsBody,
          rvfoIgnoreUnknownPicFmt, rvfoIgnoreUnknownCtrls,
          rvfoConvUnknownStylesToZero, rvfoConvLargeImageIdxToZero,
          rvfoSaveBinary, rvfoSaveBack, rvfoLoadBack,
          rvfoSaveTextStyles, rvfoSaveParaStyles, rvfoSaveLayout,
          rvfoLoadLayout];

    FRichView.RTFOptions :=
          [rvrtfDuplicateUnicode, rvrtfSaveEMFAsWMF,
           rvrtfSaveJpegAsJpeg, rvrtfSavePngAsPng,
           rvrtfSaveDocParameters, rvrtfSaveHeaderFooter,
           rvrtfSavePicturesBinary];

    with FRichView.RVData.ExtraDocumentsList do
    begin
      Clear;
      AddObject('header', FRichViewHeader.RVData);
      AddObject('footer', FRichViewFooter.RVData);
      // you can also specify first page and even pages header/footers using identifiers: headerf, footerf, headerr, footerr.
    end;

    FRichView.LoadRVF('c:\temp\template.rvf');

    FRichView.RTFReadProperties.SetFooter(FRichViewFooter.RVData);

    FRichView.SaveRTF('c:\temp\result.rtf', False);

  finally
    FRichStyle.Free;
    FRichStyle2.Free;
    FRichStyle3.Free;
    FRichViewHeader.Free;
    FRichViewFooter.Free;
    FRichView.Free;
  end;

Re: Load RVF with footer and save to RTF

Posted: Tue Sep 12, 2017 8:30 am
by Sergey Tkachenko
1) You create three RVStyles, but assign the same RVStyle (FRichStyle) to all 3 controls. Assign different RVStyles, and the main problem will be fixed.
2) Assign the same RVFOptions to FRichViewHeader and FRichViewFooter, otherwise RTF will have incorrect formatting in headers and footers.
3) Optional. Your RVF file uses StyleTemplates (named styles). If you want to keep them in RTF, add:

Code: Select all

    FRichView.UseStyleTemplates := True;
    FRichViewHeader.UseStyleTemplates := True;
    FRichViewFooter.UseStyleTemplates := True;
    FRichStyle2.MainRVStyle := FRichStyle;
    FRichStyle3.MainRVStyle := FRichStyle;
(I assume that FRichStyle2 is assigned to FRichViewHeader.Style, FRichStyle3 is assigned to FRichViewFooter.Style)

Re: Load RVF with footer and save to RTF

Posted: Mon Oct 02, 2017 3:05 pm
by arkinform
Thank you, works fine