#1 2012-07-31 15:27:03

brk303
Member
Registered: 2012-02-09
Posts: 5

FastReport PDF export using SynPDF

Few people asked for this so I'll post the unit:

DFM file:

object frxExportSynPDF: TfrxExportSynPDF
  Left = 0
  Top = 0
  BorderStyle = bsDialog
  Caption = 'Export to PDF'
  ClientHeight = 321
  ClientWidth = 292
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  Position = poScreenCenter
  OnCreate = FormCreate
  OnKeyDown = FormKeyDown
  PixelsPerInch = 96
  TextHeight = 13
  object PageControl1: TPageControl
    Left = 4
    Top = 4
    Width = 285
    Height = 277
    ActivePage = ExportPage
    MultiLine = True
    TabOrder = 0
    object ExportPage: TTabSheet
      Caption = 'Export'
      object OpenCB: TCheckBox
        Left = 16
        Top = 224
        Width = 253
        Height = 17
        Caption = 'Open after export'
        Checked = True
        State = cbChecked
        TabOrder = 0
      end
      object GroupQuality: TGroupBox
        Left = 4
        Top = 128
        Width = 267
        Height = 89
        Caption = ' Export settings '
        TabOrder = 1
        object CompressedCB: TCheckBox
          Left = 12
          Top = 20
          Width = 117
          Height = 17
          Caption = 'Compressed'
          Checked = True
          State = cbChecked
          TabOrder = 0
        end
        object EmbeddedCB: TCheckBox
          Left = 12
          Top = 40
          Width = 117
          Height = 17
          Caption = 'Embedded fonts'
          TabOrder = 1
        end
        object OutlineCB: TCheckBox
          Left = 137
          Top = 20
          Width = 121
          Height = 17
          Caption = 'Outline'
          TabOrder = 3
        end
        object BackgrCB: TCheckBox
          Left = 12
          Top = 60
          Width = 117
          Height = 17
          Caption = 'Background'
          Checked = True
          State = cbChecked
          TabOrder = 2
        end
        object cbPDFA: TCheckBox
          Left = 137
          Top = 40
          Width = 97
          Height = 17
          Caption = 'PDF-A'
          TabOrder = 4
        end
      end
      object GroupPageRange: TGroupBox
        Left = 4
        Top = 4
        Width = 267
        Height = 121
        Caption = ' Page range  '
        TabOrder = 2
        object DescrL: TLabel
          Left = 12
          Top = 82
          Width = 249
          Height = 29
          AutoSize = False
          Caption = 
            'Enter page numbers and/or page ranges, separated by commas. For ' +
            'example, 1,3,5-12'
          WordWrap = True
        end
        object AllRB: TRadioButton
          Left = 12
          Top = 20
          Width = 153
          Height = 17
          HelpContext = 108
          Caption = 'All'
          Checked = True
          TabOrder = 0
          TabStop = True
        end
        object CurPageRB: TRadioButton
          Left = 3
          Top = 37
          Width = 153
          Height = 17
          HelpContext = 118
          Caption = 'Current page'
          TabOrder = 1
        end
        object PageNumbersRB: TRadioButton
          Left = 12
          Top = 60
          Width = 77
          Height = 17
          HelpContext = 124
          Caption = 'Pages:'
          TabOrder = 2
        end
        object PageNumbersE: TEdit
          Left = 92
          Top = 58
          Width = 165
          Height = 21
          HelpContext = 133
          TabOrder = 3
          OnChange = PageNumbersEChange
          OnKeyPress = PageNumbersEKeyPress
        end
      end
    end
    object InfoPage: TTabSheet
      Caption = 'Information'
      ImageIndex = 1
      object DocInfoGB: TGroupBox
        Left = 4
        Top = 4
        Width = 267
        Height = 169
        Caption = 'Document information'
        TabOrder = 0
        object TitleL: TLabel
          Left = 12
          Top = 26
          Width = 89
          Height = 16
          AutoSize = False
          Caption = 'Title'
        end
        object AuthorL: TLabel
          Left = 12
          Top = 54
          Width = 89
          Height = 16
          AutoSize = False
          Caption = 'Author'
        end
        object SubjectL: TLabel
          Left = 12
          Top = 82
          Width = 89
          Height = 16
          AutoSize = False
          Caption = 'Subject'
        end
        object KeywordsL: TLabel
          Left = 12
          Top = 110
          Width = 89
          Height = 16
          AutoSize = False
          Caption = 'Keywords'
        end
        object CreatorL: TLabel
          Left = 12
          Top = 138
          Width = 89
          Height = 16
          AutoSize = False
          Caption = 'Creator'
        end
        object TitleE: TEdit
          Left = 108
          Top = 22
          Width = 152
          Height = 21
          TabOrder = 0
        end
        object AuthorE: TEdit
          Left = 108
          Top = 50
          Width = 152
          Height = 21
          TabOrder = 1
        end
        object SubjectE: TEdit
          Left = 108
          Top = 78
          Width = 152
          Height = 21
          TabOrder = 2
        end
        object KeywordsE: TEdit
          Left = 108
          Top = 106
          Width = 152
          Height = 21
          TabOrder = 3
        end
        object CreatorE: TEdit
          Left = 108
          Top = 134
          Width = 152
          Height = 21
          TabOrder = 4
        end
      end
    end
    object ViewerPage: TTabSheet
      Caption = 'Viewer'
      ImageIndex = 3
      object ViewerGB: TGroupBox
        Left = 4
        Top = 4
        Width = 267
        Height = 149
        Caption = 'Viewer preferences'
        TabOrder = 0
        object HideToolbarCB: TCheckBox
          Left = 12
          Top = 24
          Width = 241
          Height = 17
          Caption = 'Hide toolbar'
          TabOrder = 0
        end
        object HideMenubarCB: TCheckBox
          Left = 12
          Top = 48
          Width = 241
          Height = 17
          Caption = 'Hide menubar'
          TabOrder = 1
        end
        object HideWindowUICB: TCheckBox
          Left = 12
          Top = 72
          Width = 241
          Height = 17
          Caption = 'Hide window user interface'
          TabOrder = 2
        end
        object FitWindowCB: TCheckBox
          Left = 12
          Top = 96
          Width = 241
          Height = 17
          Caption = 'Fit window'
          TabOrder = 3
        end
        object CenterWindowCB: TCheckBox
          Left = 12
          Top = 120
          Width = 241
          Height = 17
          Caption = 'Center window'
          TabOrder = 4
        end
      end
    end
  end
  object OkB: TButton
    Left = 126
    Top = 287
    Width = 75
    Height = 25
    Caption = 'OK'
    Default = True
    ModalResult = 1
    TabOrder = 1
  end
  object CancelB: TButton
    Left = 206
    Top = 287
    Width = 75
    Height = 25
    Cancel = True
    Caption = 'Cancel'
    ModalResult = 2
    TabOrder = 2
  end
  object SaveDialog1: TSaveDialog
    Options = [ofHideReadOnly, ofNoChangeDir, ofEnableSizing]
    Left = 248
    Top = 32
  end
end

Pas file:

unit frxExportSynPDF;

interface

uses
  // VCL
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  StdCtrls,
  ComCtrls,

  // Fast Report
  frxClass,

  // Synopse PDF Engine
  SynPdf;

type
  TfrxExportSynPdf = class(TForm)
    PageControl1: TPageControl;
    ExportPage: TTabSheet;
    OpenCB: TCheckBox;
    GroupQuality: TGroupBox;
    CompressedCB: TCheckBox;
    EmbeddedCB: TCheckBox;
    OutlineCB: TCheckBox;
    BackgrCB: TCheckBox;
    cbPDFA: TCheckBox;
    GroupPageRange: TGroupBox;
    DescrL: TLabel;
    AllRB: TRadioButton;
    CurPageRB: TRadioButton;
    PageNumbersRB: TRadioButton;
    PageNumbersE: TEdit;
    InfoPage: TTabSheet;
    DocInfoGB: TGroupBox;
    TitleL: TLabel;
    AuthorL: TLabel;
    SubjectL: TLabel;
    KeywordsL: TLabel;
    CreatorL: TLabel;
    TitleE: TEdit;
    AuthorE: TEdit;
    SubjectE: TEdit;
    KeywordsE: TEdit;
    CreatorE: TEdit;
    ViewerPage: TTabSheet;
    ViewerGB: TGroupBox;
    HideToolbarCB: TCheckBox;
    HideMenubarCB: TCheckBox;
    HideWindowUICB: TCheckBox;
    FitWindowCB: TCheckBox;
    CenterWindowCB: TCheckBox;
    OkB: TButton;
    CancelB: TButton;
    SaveDialog1: TSaveDialog;
    procedure PageNumbersEChange(Sender: TObject);
    procedure PageNumbersEKeyPress(Sender: TObject; var Key: Char);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
  end;

  TfrxSynPDFExport = class(TfrxCustomExportFilter)
  private
    fPdfDocument: TPdfDocumentGDI;

    FMaxX: Integer;
    FMaxY: Integer;
    FMinX: Integer;
    FMinY: Integer;
    FYOffset: Integer;
    FDiv: Extended;

    FCompressed: Boolean;
    FEmbedded: Boolean;
    FOpenAfterExport: Boolean;
    FOutline: Boolean;
    FSubject: WideString;
    FAuthor: WideString;
    FBackground: Boolean;
    FCreator: WideString;
    FKeywords: WideString;
    FTitle: WideString;
    FFitWindow: Boolean;
    FHideMenubar: Boolean;
    FCenterWindow: Boolean;
    FHideWindowUI: Boolean;
    FHideToolbar: Boolean;
    fPDFA: Boolean;
    function GetPdfDocument: TPdfDocumentGDI;
  protected
    property PdfDocument: TPdfDocumentGDI read GetPdfDocument;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    class function GetDescription: String; override;

    function ShowModal: TModalResult; override;
    function Start: Boolean; override;
    procedure ExportObject(Obj: TfrxComponent); override;
    procedure Finish; override;
    procedure StartPage(Page: TfrxReportPage; Index: Integer); override;
    procedure FinishPage(Page: TfrxReportPage; Index: Integer); override;
  published
    property Compressed: Boolean read FCompressed write FCompressed default True;
    property EmbeddedFonts: Boolean read FEmbedded write FEmbedded default False;
    property OpenAfterExport: Boolean read FOpenAfterExport write FOpenAfterExport default True;
    property Outline: Boolean read FOutline write FOutline default False;
    property Background: Boolean read FBackground write FBackground default True;
    property PDFA: Boolean read fPDFA write fPDFA default False;

    property Title: WideString read FTitle write FTitle;
    property Author: WideString read FAuthor write FAuthor;
    property Subject: WideString read FSubject write FSubject;
    property Keywords: WideString read FKeywords write FKeywords;
    property Creator: WideString read FCreator write FCreator;

    property HideToolbar: Boolean read FHideToolbar write FHideToolbar default False;
    property HideMenubar: Boolean read FHideMenubar write FHideMenubar default False;
    property HideWindowUI: Boolean read FHideWindowUI write FHideWindowUI default False;
    property FitWindow: Boolean read FFitWindow write FFitWindow default False;
    property CenterWindow: Boolean read FCenterWindow write FCenterWindow default False;
  end;

implementation

uses
  // Fast Report
  frxUtils,
  frxRes,
  frxrcExports,

  // VCL
  Printers,
  ShellApi;

{$R *.dfm}

constructor TfrxSynPDFExport.Create(AOwner: TComponent);
begin
  inherited;
  fBackground := True;
  fCompressed := True;
  fOpenAfterExport := True;

  FMaxX := 0;
  FMaxY := 0;
  FMinX := 100;
  FMinY := 100;
  FYOffset := 0;
  FDiv := 1;
end;

destructor TfrxSynPDFExport.Destroy;
begin
  FreeAndNil(fPdfDocument);
  inherited;
end;

procedure TfrxSynPDFExport.Finish;
begin
  try
    if Stream <> nil then
      PdfDocument.SaveToStream(Stream)
    else
      PdfDocument.SaveToFile(FileName);
    if OpenAfterExport and not Assigned(Stream) then
      ShellExecute(GetDesktopWindow, 'open', PChar(FileName), nil, nil, SW_SHOW);
  finally
    FreeAndNil(fPdfDocument);
  end;
end;

procedure TfrxSynPDFExport.FinishPage(Page: TfrxReportPage; Index: Integer);
begin
  inherited;

end;

class function TfrxSynPDFExport.GetDescription: String;
begin
  Result := 'SynPDFexport';
end;

function TfrxSynPDFExport.GetPdfDocument: TPdfDocumentGDI;
begin
  if not Assigned(fPdfDocument) then
  begin
    fPdfDocument := TPdfDocumentGDI.Create;
    fPdfDocument.Info.Creator := Application.Name;
    fPdfDocument.Info.Author := Application.Name;
//  fPdfDocument.ScreenLogPixels := 72 ?; might be needed with non standard windows DPI settings - Daniel
  end;
  fPdfDocument.ForceNoBitmapReuse := True;
  result := fPdfDocument;
end;

function TfrxSynPDFExport.ShowModal: TModalResult;
var
  s: String;
begin
  if (Title = '') and Assigned(Report) then
    Title := Report.ReportOptions.Name;
  if not Assigned(Stream) then
  begin
    if Assigned(Report) then
      Outline := Report.PreviewOptions.OutlineVisible
    else
      Outline := True;
    with TfrxExportSynPdf.Create(nil) do
    begin
      OpenCB.Visible := not SlaveExport;
      if OverwritePrompt then
        SaveDialog1.Options := SaveDialog1.Options + [ofOverwritePrompt];
      if SlaveExport then
        FOpenAfterExport := False;

      if (FileName = '') and (not SlaveExport) then
      begin
        s := ChangeFileExt(ExtractFileName(frxUnixPath2WinPath(Report.FileName)), SaveDialog1.DefaultExt);
        SaveDialog1.FileName := s;
      end
      else
        SaveDialog1.FileName := FileName;

      OpenCB.Checked := OpenAfterExport;
      CompressedCB.Checked := Compressed;
      EmbeddedCB.Checked := EmbeddedFonts;

      OutlineCB.Checked := Outline;
      OutlineCB.Enabled := Outline;
      BackgrCB.Checked := Background;

      if PageNumbers <> '' then
      begin
        PageNumbersE.Text := PageNumbers;
        PageNumbersRB.Checked := True;
      end;

      cbPDFA.Checked := PDFA;

      TitleE.Text := Title;
      AuthorE.Text := Author;
      SubjectE.Text := Subject;
      KeywordsE.Text := Keywords;
      CreatorE.Text := Creator;

      FitWindowCB.Checked := FitWindow;
      HideMenubarCB.Checked := HideMenubar;
      CenterWindowCB.Checked := CenterWindow;
      HideWindowUICB.Checked := HideWindowUI;
      HideToolbarCB.Checked := HideToolbar;

      Result := ShowModal;
      if Result = mrOk then
      begin
        PageNumbers := '';
        CurPage := False;
        if CurPageRB.Checked then
          CurPage := True
        else if PageNumbersRB.Checked then
          PageNumbers := PageNumbersE.Text;

        OpenAfterExport := OpenCB.Checked;
        Compressed := CompressedCB.Checked;
        EmbeddedFonts := EmbeddedCB.Checked;
        Outline := OutlineCB.Checked;
        Background := BackgrCB.Checked;
        PDFA := cbPDFA.Checked;

        Title := TitleE.Text;
        Author := AuthorE.Text;
        Subject := SubjectE.Text;
        Keywords := KeywordsE.Text;
        Creator := CreatorE.Text;

        FitWindow := FitWindowCB.Checked;
        HideMenubar := HideMenubarCB.Checked;
        CenterWindow := CenterWindowCB.Checked;
        HideWindowUI := HideWindowUICB.Checked;
        HideToolbar := HideToolbarCB.Checked;

        if not SlaveExport then
        begin
          if DefaultPath <> '' then
            SaveDialog1.InitialDir := DefaultPath;
          if SaveDialog1.Execute then
            FileName := SaveDialog1.FileName
          else
            Result := mrCancel;
        end;
      end;
      Free;
    end;
  end else
    Result := mrOk;
end;

function TfrxSynPDFExport.Start: Boolean;
var
  vPdfViewerPreferences: TPdfViewerPreferences;
begin
  result := true;
  PdfDocument.NewDoc;
  PdfDocument.Info.CreationDate := CreationTime;
  PdfDocument.Info.ModDate := CreationTime;
  PdfDocument.Info.Author := Author;
  PdfDocument.Info.Subject := Subject;
  PdfDocument.Info.Keywords := Keywords;
  PdfDocument.Info.Creator := Creator;

  vPdfViewerPreferences := [];
  if FitWindow then Include(vPdfViewerPreferences, vpFitWindow);
  if HideMenubar then Include(vPdfViewerPreferences, vpHideMenubar);
  if CenterWindow then Include(vPdfViewerPreferences, vpCenterWindow);
  if HideWindowUI then Include(vPdfViewerPreferences, vpHideWindowUI);
  if HideToolbar then Include(vPdfViewerPreferences, vpHideToolbar);
  if vPdfViewerPreferences <> PdfDocument.Root.ViewerPreference then  
    PdfDocument.Root.ViewerPreference := vPdfViewerPreferences;

  if Compressed then  
    PdfDocument.CompressionMethod := cmFlateDecode
  else
    PdfDocument.CompressionMethod := cmNone;

  PdfDocument.UseOutlines := Outline;
  PdfDocument.PDFA1 := PDFA;
  PdfDocument.EmbeddedTTF := EmbeddedFonts;
end;

procedure TfrxSynPDFExport.StartPage(Page: TfrxReportPage; Index: Integer);
begin
  inherited;
  PdfDocument.DefaultPageLandscape := Page.Orientation = poLandscape;
  PdfDocument.AddPage;
end;

procedure TfrxSynPDFExport.ExportObject(Obj: TfrxComponent);
var
  z: Integer;
begin
  if (Obj is TfrxView) and (ExportNotPrintable or TfrxView(Obj).Printable) then
  begin
    if Background or not (Obj.Name = '_pagebackground') then
    begin
      z := Round(Obj.AbsLeft * FDiv);
      if z < FMinX then
        FMinX := z;
      z := FYOffset + Round(Obj.AbsTop * FDiv);
      if z < FMinY then
        FMinY := z;
      z := Round((Obj.AbsLeft + Obj.Width) * FDiv) + 1;
      if z > FMaxX then
        FMaxX := z;
      z := FYOffset + Round((Obj.AbsTop + Obj.Height) * FDiv) + 1;
      if z > FMaxY then
        FMaxY := z;
      TfrxView(Obj).Draw(PdfDocument.VCLCanvas , FDiv, FDiv, 0, FYOffset);
    end;
  end;
end;

procedure TfrxExportSynPdf.FormCreate(Sender: TObject);
begin

  Caption := frxGet(8700);
  OkB.Caption := frxGet(1);
  CancelB.Caption := frxGet(2);
  GroupPageRange.Caption := frxGet(7);
  AllRB.Caption := frxGet(3);
  CurPageRB.Caption := frxGet(4);
  PageNumbersRB.Caption := frxGet(5);
  DescrL.Caption := frxGet(9);
  GroupQuality.Caption := frxGet(8);
  CompressedCB.Caption := frxGet(8701);
  EmbeddedCB.Caption := frxGet(8702);
  OutlineCB.Caption := frxGet(8704);
  BackgrCB.Caption := frxGet(8705);
  OpenCB.Caption := frxGet(8706);
  SaveDialog1.Filter := frxGet(8707);
  SaveDialog1.DefaultExt := frxGet(8708);

  ExportPage.Caption := frxGet(107);
  DocInfoGB.Caption := frxGet(8971);
  InfoPage.Caption := frxGet(8972);
  TitleL.Caption := frxGet(8973);
  AuthorL.Caption := frxGet(8974);
  SubjectL.Caption := frxGet(8975);
  KeywordsL.Caption := frxGet(8976);
  CreatorL.Caption := frxGet(8977);

  ViewerPage.Caption := frxGet(8981);
  ViewerGB.Caption := frxGet(8982);
  HideToolbarCB.Caption := frxGet(8983);
  HideMenubarCB.Caption := frxGet(8984);
  HideWindowUICB.Caption := frxGet(8985);
  FitWindowCB.Caption := frxGet(8986);
  CenterWindowCB.Caption := frxGet(8987);

  if UseRightToLeftAlignment then
    FlipChildren(True);
end;

procedure TfrxExportSynPdf.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_F1 then
    frxResources.Help(Self);
end;

procedure TfrxExportSynPdf.PageNumbersEChange(Sender: TObject);
begin
  PageNumbersRB.Checked := True;
end;

procedure TfrxExportSynPdf.PageNumbersEKeyPress(Sender: TObject; var Key: Char);
begin
  case key of
    '0'..'9':;
    #8, '-', ',':;
  else
    key := #0;
  end;
end;

end.

Offline

#2 2012-07-31 20:49:42

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: FastReport PDF export using SynPDF

This is a very nice piece of code.

Thanks a lot for sharing it!

Offline

#3 2012-09-05 02:08:56

leus
Member
Registered: 2012-09-05
Posts: 79

Re: FastReport PDF export using SynPDF

Hello,

Tried this unit but I didn't got the complete document.

I'm expecting this: http://monserratinformatica.cl/nc62-good.pdf

But instead, I'm getting this: http://monserratinformatica.cl/nc62.pdf

(never mind the small text differences, those are expected.)

Any idea on what may be happening?

Last edited by leus (2012-09-05 02:10:03)

Offline

#4 2013-04-11 14:37:30

AdamBrett
Member
Registered: 2013-04-11
Posts: 1

Re: FastReport PDF export using SynPDF

This is a really useful piece of code, it is a pity there is no explanation of how to use it. This makes it very hard for someone like me to actually do anything with it, even though I have been programming with Delphi for 10 years. A simple sample program showing how to integrate it into a program using Fast Reports would be really useful, I see a few people have requested this as well as me smile.

So other people know what to do:

1. Copy the DFM code into Notepad and save-as frxSynPDFExport.dfm, copy the PAS code into Notepad and save-as frxSynPDFExport.pas.
2. Put these 2 files into a folder on your computer which is on your delphi project path, and add fxxSynPDFExport to the uses clause of your project.
3. In your project replace all references to "TfrxPDFExport" components with references to TfrxSynPDFExport. If you work with visual components you will have to delete these.

With my set up doing this worked, but resulted in PDF files in which all the fonts were scaled to 75% of usual size on the page, leaving a lot of empty space.
But the PDFs were about 30 times smaller than the original frxPRFExport!!! which is a huge improvement.

I added the line:

    fPdfDocument.ScreenLogPixels := 96; //Had to reset this to scale the PDF correctly

To this function:

function TfrxSynPDFExport.GetPdfDocument: TPdfDocumentGDI;
begin
  if not Assigned(fPdfDocument) then
  begin
    fPdfDocument := TPdfDocumentGDI.Create;
    fPdfDocument.Info.Creator := Application.Name;
    fPdfDocument.Info.Author := Application.Name;
    fPdfDocument.ScreenLogPixels := 96;//84;//112;//72; Had to reset this to scale the PDF correctly
  end;
  fPdfDocument.ForceNoBitmapReuse := True;
  result := fPdfDocument;
end;

to get it to scale correctly.

Hopefully Fast Report will incorporate Snyopse PDF into their next release and then this will not be necessary!

Offline

#5 2013-04-11 15:04:41

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: FastReport PDF export using SynPDF

I never used FastReport (since I use either ReportBuilder, QuickReport or our own mORMotReport.pas), so I was not able to help much, here...

Thanks for the feedback!

Offline

#6 2013-05-17 11:23:56

dschuch
Member
Registered: 2013-05-17
Posts: 5

Re: FastReport PDF export using SynPDF

Hey,

thank you very very much for this code. We spend tons of money/time trying to get a usefull solution for FastReport PDF-Export - this is the first one *nearly* working (we did not know SynopsePDF before). Perhpas someone can give us a hint with the last problems:

1) Synopse seems to have a bit more Space-Char, so some Words become longer, than in FR-Preview and so cutted in the PDF.

http://prodat-sql.de/tmp/PreviewFastReport.jpg
http://prodat-sql.de/tmp/SynPDF-Export.jpg
http://prodat-sql.de/tmp/FastReport-DesignView.jpg

2) See Picture: "Vor-Ort" seems to be interpreted as some kind of special code? The element is a TfrxRichView

http://prodat-sql.de/tmp/Synopse-BugVorOrt.jpg


I have checked out different Fonts, but this doesn't seem to solve the problem.

Anyone can help?

It is possible to pay for the time, if it becomes more intensive to solve this problem. We do not want to spend to much time ourself in the internals of SynopsePDF if we can avoid it, so it would be nice to hire the KnowHow for that last but major problem.

Daniel.

Last edited by dschuch (2013-05-17 11:25:49)

Offline

#7 2013-05-17 15:25:20

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: FastReport PDF export using SynPDF

Did you try the newly introduced tpExactTextCharacterPositining option?
It has been introduced by http://synopse.info/fossil/info/c6f7355eed

Offline

#8 2013-05-17 19:14:07

dschuch
Member
Registered: 2013-05-17
Posts: 5

Re: FastReport PDF export using SynPDF

Thanks a lot. With this new Version things changed. Results are better in all cases. But only KerningFromAverage is out of mistakes. I checked out all options - you can see the result-Screens.

Interesting is the filesize too: 237kb in my example for "SetTextJustification", 47kb the other two.

http://prodat-sql.de/tmp/SynPDF-KerningFromAverage.jpg *perfect

http://prodat-sql.de/tmp/SynPDF-SetText … cation.jpg    *minor mistakes

http://prodat-sql.de/tmp/SynPDF-ExactTextChar.jpg        *minor mistakes

absolutely great. We will check out this now with some more reports from our customers.

Thanks very much. Is there is a hidden Donate function on your site? wink

Daniel.

Offline

#9 2013-05-18 07:42:50

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: FastReport PDF export using SynPDF

In fact, it is hidden in the LVCL\MySecNotepad\LoginFrm.pas source code file!
smile

https://www.paypal.com/cgi-bin/webscr?c … te=1&tax=0
or
https://www.paypal.com/cgi-bin/webscr?c … y_code=EUR

Happy it helps.


It is strange, since tpExactTextCharacterPositining is the one which should give the bigger pdf size.
In this tpExactTextCharacterPositining  mode, every character is positioned in absolute coordinates, so it is more precise, but much more verbose.
The two other options use an "average" algorithm for the whole block text, depending on the word spacing or the glyph spacing. So it will produce much smaller files.
One good think with SynPDF (among others), is that you can select the rendering mode which better fits your needs.

Offline

#10 2013-05-22 11:52:30

dschuch
Member
Registered: 2013-05-17
Posts: 5

Re: FastReport PDF export using SynPDF

Hy,

@ad - got your email. fine. (found in spam today. wink )

-

@ All:
The problem with the cutted text-fields seems to evolve from the "wysiwyg" - property. It depends of the content of the memo: if it is a macro - eg [IIF ...] sometimes the text is cutted in the pdf.
Best results i still get with KerningFromAverage.

I solved it temporarily by changeing the ExportObject-Procedure:

procedure TfrxSynPDFExport.ExportObject(Obj: TfrxComponent);
Var ...
     frxCheckWysiWyg, old_wysiwyg: Boolean;
...
      frxCheckWysiWyg:=Obj IS TfrxMemoView;
      if frxCheckWysiWyg then begin
         old_wysiwyg:=TfrxMemoView(Obj).Wysiwyg;
         TfrxMemoView(Obj).Wysiwyg:=False;
      end;

      TfrxView(Obj).Draw(PdfDocument.VCLCanvas , FDiv, FDiv, 0, FYOffset);

      if frxCheckWysiWyg then
         TfrxMemoView(Obj).Wysiwyg:=old_wysiwyg;
    end;
end;

Last edited by dschuch (2013-05-22 13:33:09)

Offline

#11 2013-05-28 20:03:31

rposeika
Member
Registered: 2013-05-28
Posts: 3

Re: FastReport PDF export using SynPDF

Thank you for this excellent tool / add on for Fast Reports. it did not take me too long to get it working as desired - the PDFs are much smaller in file size and some of the graphics seem crisper.

I could have missed something -
One question - i noticed that the PDF properties (Information) exposed in the UI (DFM) - Author, Title etc. do not get embedded in the
final PDF document. (That part works with the Fastreports PDF exporter). **Did I miss something or can someone provide an example
on how to make that work.

Thanks in advance smile

Offline

#12 2013-05-31 14:49:56

rposeika
Member
Registered: 2013-05-28
Posts: 3

Re: FastReport PDF export using SynPDF

I think I figured it out by looking at general posts in this forum in regards to "info." and the base unit-see code below
regards all

function TfrxSynPDFExport.Start: Boolean;
var
  vPdfViewerPreferences: TPdfViewerPreferences;
begin
  result := true;
  PdfDocument.NewDoc;
  PdfDocument.PDFA1 := PDFA;//<<<new location
  PdfDocument.Info.CreationDate := CreationTime;
  PdfDocument.Info.ModDate := CreationTime;
  PdfDocument.Info.Author := Author;
  PdfDocument.Info.Subject := Subject;
  PdfDocument.Info.Keywords := Keywords;
  PdfDocument.Info.Creator := Creator;

  vPdfViewerPreferences := [];
  if FitWindow then Include(vPdfViewerPreferences, vpFitWindow);
  if HideMenubar then Include(vPdfViewerPreferences, vpHideMenubar);
  if CenterWindow then Include(vPdfViewerPreferences, vpCenterWindow);
  if HideWindowUI then Include(vPdfViewerPreferences, vpHideWindowUI);
  if HideToolbar then Include(vPdfViewerPreferences, vpHideToolbar);
  if vPdfViewerPreferences <> PdfDocument.Root.ViewerPreference then
    PdfDocument.Root.ViewerPreference := vPdfViewerPreferences;

  if Compressed then  
    PdfDocument.CompressionMethod := cmFlateDecode
  else
    PdfDocument.CompressionMethod := cmNone;

  PdfDocument.UseOutlines := Outline;
  //PdfDocument.PDFA1 := PDFA;//old location
  PdfDocument.EmbeddedTTF := EmbeddedFonts;
end;

Last edited by rposeika (2013-06-03 16:46:13)

Offline

#13 2013-06-03 15:08:12

rposeika
Member
Registered: 2013-05-28
Posts: 3

Re: FastReport PDF export using SynPDF

update
-I have also encountered the following issues or did not know how to make work, which I corrected, or got to work by slight code changes.
--I will post solutions later.

1. PaperSize from FR Report not coming through to the synPDF doc
2. Paper Orientation (Landscape or portrait) was not getting updated (was always portrait)

hope this helps others

Offline

#14 2013-06-27 10:54:32

cocce
Member
Registered: 2011-11-02
Posts: 28

Re: FastReport PDF export using SynPDF

Hi, i tried the export class but seems to have a problem with transparent images, png specially.

Is there a workaroung for that?

Thanks

Offline

#15 2013-06-27 15:02:19

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,182
Website

Re: FastReport PDF export using SynPDF

SynPDF does not handle picture transparency yet.
AFAIK transparency in PDF is somewhat complex to implement.
Any help is welcome here.

The workaround is to build one bitmap without transparency, joining several transparent images, then use this non transparent bitmap within the report.
It will work as expected.

Offline

#16 2015-01-06 09:30:59

HaraldSimon
Member
Registered: 2015-01-06
Posts: 3

Re: FastReport PDF export using SynPDF

rposeika wrote:

-I have also encountered the following issues or did not know how to make work, which I corrected, or got to work by slight code changes.
--I will post solutions later.

1. PaperSize from FR Report not coming through to the synPDF doc
2. Paper Orientation (Landscape or portrait) was not getting updated (was always portrait)

Set the right PaperSize in TfrxSynPDFExport.StartPage:

procedure TfrxSynPDFExport.StartPage(Page: TfrxReportPage; Index: Integer);
begin
  inherited;

  case Page.PaperSize of
    DMPAPER_LETTER,
    DMPAPER_LETTERSMALL:  PdfDocument.DefaultPaperSize := psLetter;
    DMPAPER_LEGAL:        PdfDocument.DefaultPaperSize := psLegal;
    DMPAPER_A3:           PdfDocument.DefaultPaperSize := psA3;
    DMPAPER_A4,
    DMPAPER_A4SMALL:      PdfDocument.DefaultPaperSize := psA4;
    DMPAPER_A5:           PdfDocument.DefaultPaperSize := psA5;
  else
    PdfDocument.DefaultPaperSize := psUserDefined;
    PdfDocument.DefaultPageWidth := Round((Page.PaperWidth / 25.4) * 72.0);
    PdfDocument.DefaultPageHeight := Round((Page.PaperHeight / 25.4) * 72.0);
  end;

  PdfDocument.DefaultPageLandscape := (Page.Orientation = poLandscape);
  PdfDocument.AddPage;
end;

Offline

#17 2015-03-18 01:38:14

iexuexi
Member
Registered: 2015-03-18
Posts: 4

Re: FastReport PDF export using SynPDF

the unit name is frxExportSynPDF. Why do you save the code source as TfrxSynPDFExport.pas

edit: yes, AdamBrett you are right, thank you!

AdamBrett wrote:

This is a really useful piece of code, it is a pity there is no explanation of how to use it. This makes it very hard for someone like me to actually do anything with it, even though I have been programming with Delphi for 10 years. A simple sample program showing how to integrate it into a program using Fast Reports would be really useful, I see a few people have requested this as well as me smile.

So other people know what to do:

1. Copy the DFM code into Notepad and save-as frxSynPDFExport.dfm, copy the PAS code into Notepad and save-as frxSynPDFExport.pas.
2. Put these 2 files into a folder on your computer which is on your delphi project path, and add fxxSynPDFExport to the uses clause of your project.
3. In your project replace all references to "TfrxPDFExport" components with references to TfrxSynPDFExport. If you work with visual components you will have to delete these.

With my set up doing this worked, but resulted in PDF files in which all the fonts were scaled to 75% of usual size on the page, leaving a lot of empty space.
But the PDFs were about 30 times smaller than the original frxPRFExport!!! which is a huge improvement.

I added the line:

    fPdfDocument.ScreenLogPixels := 96; //Had to reset this to scale the PDF correctly

To this function:

function TfrxSynPDFExport.GetPdfDocument: TPdfDocumentGDI;
begin
  if not Assigned(fPdfDocument) then
  begin
    fPdfDocument := TPdfDocumentGDI.Create;
    fPdfDocument.Info.Creator := Application.Name;
    fPdfDocument.Info.Author := Application.Name;
    fPdfDocument.ScreenLogPixels := 96;//84;//112;//72; Had to reset this to scale the PDF correctly
  end;
  fPdfDocument.ForceNoBitmapReuse := True;
  result := fPdfDocument;
end;

to get it to scale correctly.

Hopefully Fast Report will incorporate Snyopse PDF into their next release and then this will not be necessary!

Last edited by iexuexi (2015-03-18 08:00:26)

Offline

#18 2015-03-18 02:17:23

iexuexi
Member
Registered: 2015-03-18
Posts: 4

Re: FastReport PDF export using SynPDF

what is the version of Fast Report which you use????

brk303 wrote:

Few people asked for this so I'll post the unit:

DFM file:

object frxExportSynPDF: TfrxExportSynPDF
  Left = 0
  Top = 0
  BorderStyle = bsDialog
  Caption = 'Export to PDF'
  ClientHeight = 321
  ClientWidth = 292
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  KeyPreview = True
  OldCreateOrder = False
  Position = poScreenCenter
  OnCreate = FormCreate
  OnKeyDown = FormKeyDown
  PixelsPerInch = 96
  TextHeight = 13
  object PageControl1: TPageControl
    Left = 4
    Top = 4
    Width = 285
    Height = 277
    ActivePage = ExportPage
    MultiLine = True
    TabOrder = 0
    object ExportPage: TTabSheet
      Caption = 'Export'
      object OpenCB: TCheckBox
        Left = 16
        Top = 224
        Width = 253
        Height = 17
        Caption = 'Open after export'
        Checked = True
        State = cbChecked
        TabOrder = 0
      end
      object GroupQuality: TGroupBox
        Left = 4
        Top = 128
        Width = 267
        Height = 89
        Caption = ' Export settings '
        TabOrder = 1
        object CompressedCB: TCheckBox
          Left = 12
          Top = 20
          Width = 117
          Height = 17
          Caption = 'Compressed'
          Checked = True
          State = cbChecked
          TabOrder = 0
        end
        object EmbeddedCB: TCheckBox
          Left = 12
          Top = 40
          Width = 117
          Height = 17
          Caption = 'Embedded fonts'
          TabOrder = 1
        end
        object OutlineCB: TCheckBox
          Left = 137
          Top = 20
          Width = 121
          Height = 17
          Caption = 'Outline'
          TabOrder = 3
        end
        object BackgrCB: TCheckBox
          Left = 12
          Top = 60
          Width = 117
          Height = 17
          Caption = 'Background'
          Checked = True
          State = cbChecked
          TabOrder = 2
        end
        object cbPDFA: TCheckBox
          Left = 137
          Top = 40
          Width = 97
          Height = 17
          Caption = 'PDF-A'
          TabOrder = 4
        end
      end
      object GroupPageRange: TGroupBox
        Left = 4
        Top = 4
        Width = 267
        Height = 121
        Caption = ' Page range  '
        TabOrder = 2
        object DescrL: TLabel
          Left = 12
          Top = 82
          Width = 249
          Height = 29
          AutoSize = False
          Caption = 
            'Enter page numbers and/or page ranges, separated by commas. For ' +
            'example, 1,3,5-12'
          WordWrap = True
        end
        object AllRB: TRadioButton
          Left = 12
          Top = 20
          Width = 153
          Height = 17
          HelpContext = 108
          Caption = 'All'
          Checked = True
          TabOrder = 0
          TabStop = True
        end
        object CurPageRB: TRadioButton
          Left = 3
          Top = 37
          Width = 153
          Height = 17
          HelpContext = 118
          Caption = 'Current page'
          TabOrder = 1
        end
        object PageNumbersRB: TRadioButton
          Left = 12
          Top = 60
          Width = 77
          Height = 17
          HelpContext = 124
          Caption = 'Pages:'
          TabOrder = 2
        end
        object PageNumbersE: TEdit
          Left = 92
          Top = 58
          Width = 165
          Height = 21
          HelpContext = 133
          TabOrder = 3
          OnChange = PageNumbersEChange
          OnKeyPress = PageNumbersEKeyPress
        end
      end
    end
    object InfoPage: TTabSheet
      Caption = 'Information'
      ImageIndex = 1
      object DocInfoGB: TGroupBox
        Left = 4
        Top = 4
        Width = 267
        Height = 169
        Caption = 'Document information'
        TabOrder = 0
        object TitleL: TLabel
          Left = 12
          Top = 26
          Width = 89
          Height = 16
          AutoSize = False
          Caption = 'Title'
        end
        object AuthorL: TLabel
          Left = 12
          Top = 54
          Width = 89
          Height = 16
          AutoSize = False
          Caption = 'Author'
        end
        object SubjectL: TLabel
          Left = 12
          Top = 82
          Width = 89
          Height = 16
          AutoSize = False
          Caption = 'Subject'
        end
        object KeywordsL: TLabel
          Left = 12
          Top = 110
          Width = 89
          Height = 16
          AutoSize = False
          Caption = 'Keywords'
        end
        object CreatorL: TLabel
          Left = 12
          Top = 138
          Width = 89
          Height = 16
          AutoSize = False
          Caption = 'Creator'
        end
        object TitleE: TEdit
          Left = 108
          Top = 22
          Width = 152
          Height = 21
          TabOrder = 0
        end
        object AuthorE: TEdit
          Left = 108
          Top = 50
          Width = 152
          Height = 21
          TabOrder = 1
        end
        object SubjectE: TEdit
          Left = 108
          Top = 78
          Width = 152
          Height = 21
          TabOrder = 2
        end
        object KeywordsE: TEdit
          Left = 108
          Top = 106
          Width = 152
          Height = 21
          TabOrder = 3
        end
        object CreatorE: TEdit
          Left = 108
          Top = 134
          Width = 152
          Height = 21
          TabOrder = 4
        end
      end
    end
    object ViewerPage: TTabSheet
      Caption = 'Viewer'
      ImageIndex = 3
      object ViewerGB: TGroupBox
        Left = 4
        Top = 4
        Width = 267
        Height = 149
        Caption = 'Viewer preferences'
        TabOrder = 0
        object HideToolbarCB: TCheckBox
          Left = 12
          Top = 24
          Width = 241
          Height = 17
          Caption = 'Hide toolbar'
          TabOrder = 0
        end
        object HideMenubarCB: TCheckBox
          Left = 12
          Top = 48
          Width = 241
          Height = 17
          Caption = 'Hide menubar'
          TabOrder = 1
        end
        object HideWindowUICB: TCheckBox
          Left = 12
          Top = 72
          Width = 241
          Height = 17
          Caption = 'Hide window user interface'
          TabOrder = 2
        end
        object FitWindowCB: TCheckBox
          Left = 12
          Top = 96
          Width = 241
          Height = 17
          Caption = 'Fit window'
          TabOrder = 3
        end
        object CenterWindowCB: TCheckBox
          Left = 12
          Top = 120
          Width = 241
          Height = 17
          Caption = 'Center window'
          TabOrder = 4
        end
      end
    end
  end
  object OkB: TButton
    Left = 126
    Top = 287
    Width = 75
    Height = 25
    Caption = 'OK'
    Default = True
    ModalResult = 1
    TabOrder = 1
  end
  object CancelB: TButton
    Left = 206
    Top = 287
    Width = 75
    Height = 25
    Cancel = True
    Caption = 'Cancel'
    ModalResult = 2
    TabOrder = 2
  end
  object SaveDialog1: TSaveDialog
    Options = [ofHideReadOnly, ofNoChangeDir, ofEnableSizing]
    Left = 248
    Top = 32
  end
end

Pas file:

unit frxExportSynPDF;

interface

uses
  // VCL
  Windows,
  Messages,
  SysUtils,
  Variants,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  StdCtrls,
  ComCtrls,

  // Fast Report
  frxClass,

  // Synopse PDF Engine
  SynPdf;

type
  TfrxExportSynPdf = class(TForm)
    PageControl1: TPageControl;
    ExportPage: TTabSheet;
    OpenCB: TCheckBox;
    GroupQuality: TGroupBox;
    CompressedCB: TCheckBox;
    EmbeddedCB: TCheckBox;
    OutlineCB: TCheckBox;
    BackgrCB: TCheckBox;
    cbPDFA: TCheckBox;
    GroupPageRange: TGroupBox;
    DescrL: TLabel;
    AllRB: TRadioButton;
    CurPageRB: TRadioButton;
    PageNumbersRB: TRadioButton;
    PageNumbersE: TEdit;
    InfoPage: TTabSheet;
    DocInfoGB: TGroupBox;
    TitleL: TLabel;
    AuthorL: TLabel;
    SubjectL: TLabel;
    KeywordsL: TLabel;
    CreatorL: TLabel;
    TitleE: TEdit;
    AuthorE: TEdit;
    SubjectE: TEdit;
    KeywordsE: TEdit;
    CreatorE: TEdit;
    ViewerPage: TTabSheet;
    ViewerGB: TGroupBox;
    HideToolbarCB: TCheckBox;
    HideMenubarCB: TCheckBox;
    HideWindowUICB: TCheckBox;
    FitWindowCB: TCheckBox;
    CenterWindowCB: TCheckBox;
    OkB: TButton;
    CancelB: TButton;
    SaveDialog1: TSaveDialog;
    procedure PageNumbersEChange(Sender: TObject);
    procedure PageNumbersEKeyPress(Sender: TObject; var Key: Char);
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure FormCreate(Sender: TObject);
  end;

  TfrxSynPDFExport = class(TfrxCustomExportFilter)
  private
    fPdfDocument: TPdfDocumentGDI;

    FMaxX: Integer;
    FMaxY: Integer;
    FMinX: Integer;
    FMinY: Integer;
    FYOffset: Integer;
    FDiv: Extended;

    FCompressed: Boolean;
    FEmbedded: Boolean;
    FOpenAfterExport: Boolean;
    FOutline: Boolean;
    FSubject: WideString;
    FAuthor: WideString;
    FBackground: Boolean;
    FCreator: WideString;
    FKeywords: WideString;
    FTitle: WideString;
    FFitWindow: Boolean;
    FHideMenubar: Boolean;
    FCenterWindow: Boolean;
    FHideWindowUI: Boolean;
    FHideToolbar: Boolean;
    fPDFA: Boolean;
    function GetPdfDocument: TPdfDocumentGDI;
  protected
    property PdfDocument: TPdfDocumentGDI read GetPdfDocument;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    class function GetDescription: String; override;

    function ShowModal: TModalResult; override;
    function Start: Boolean; override;
    procedure ExportObject(Obj: TfrxComponent); override;
    procedure Finish; override;
    procedure StartPage(Page: TfrxReportPage; Index: Integer); override;
    procedure FinishPage(Page: TfrxReportPage; Index: Integer); override;
  published
    property Compressed: Boolean read FCompressed write FCompressed default True;
    property EmbeddedFonts: Boolean read FEmbedded write FEmbedded default False;
    property OpenAfterExport: Boolean read FOpenAfterExport write FOpenAfterExport default True;
    property Outline: Boolean read FOutline write FOutline default False;
    property Background: Boolean read FBackground write FBackground default True;
    property PDFA: Boolean read fPDFA write fPDFA default False;

    property Title: WideString read FTitle write FTitle;
    property Author: WideString read FAuthor write FAuthor;
    property Subject: WideString read FSubject write FSubject;
    property Keywords: WideString read FKeywords write FKeywords;
    property Creator: WideString read FCreator write FCreator;

    property HideToolbar: Boolean read FHideToolbar write FHideToolbar default False;
    property HideMenubar: Boolean read FHideMenubar write FHideMenubar default False;
    property HideWindowUI: Boolean read FHideWindowUI write FHideWindowUI default False;
    property FitWindow: Boolean read FFitWindow write FFitWindow default False;
    property CenterWindow: Boolean read FCenterWindow write FCenterWindow default False;
  end;

implementation

uses
  // Fast Report
  frxUtils,
  frxRes,
  frxrcExports,

  // VCL
  Printers,
  ShellApi;

{$R *.dfm}

constructor TfrxSynPDFExport.Create(AOwner: TComponent);
begin
  inherited;
  fBackground := True;
  fCompressed := True;
  fOpenAfterExport := True;

  FMaxX := 0;
  FMaxY := 0;
  FMinX := 100;
  FMinY := 100;
  FYOffset := 0;
  FDiv := 1;
end;

destructor TfrxSynPDFExport.Destroy;
begin
  FreeAndNil(fPdfDocument);
  inherited;
end;

procedure TfrxSynPDFExport.Finish;
begin
  try
    if Stream <> nil then
      PdfDocument.SaveToStream(Stream)
    else
      PdfDocument.SaveToFile(FileName);
    if OpenAfterExport and not Assigned(Stream) then
      ShellExecute(GetDesktopWindow, 'open', PChar(FileName), nil, nil, SW_SHOW);
  finally
    FreeAndNil(fPdfDocument);
  end;
end;

procedure TfrxSynPDFExport.FinishPage(Page: TfrxReportPage; Index: Integer);
begin
  inherited;

end;

class function TfrxSynPDFExport.GetDescription: String;
begin
  Result := 'SynPDFexport';
end;

function TfrxSynPDFExport.GetPdfDocument: TPdfDocumentGDI;
begin
  if not Assigned(fPdfDocument) then
  begin
    fPdfDocument := TPdfDocumentGDI.Create;
    fPdfDocument.Info.Creator := Application.Name;
    fPdfDocument.Info.Author := Application.Name;
//  fPdfDocument.ScreenLogPixels := 72 ?; might be needed with non standard windows DPI settings - Daniel
  end;
  fPdfDocument.ForceNoBitmapReuse := True;
  result := fPdfDocument;
end;

function TfrxSynPDFExport.ShowModal: TModalResult;
var
  s: String;
begin
  if (Title = '') and Assigned(Report) then
    Title := Report.ReportOptions.Name;
  if not Assigned(Stream) then
  begin
    if Assigned(Report) then
      Outline := Report.PreviewOptions.OutlineVisible
    else
      Outline := True;
    with TfrxExportSynPdf.Create(nil) do
    begin
      OpenCB.Visible := not SlaveExport;
      if OverwritePrompt then
        SaveDialog1.Options := SaveDialog1.Options + [ofOverwritePrompt];
      if SlaveExport then
        FOpenAfterExport := False;

      if (FileName = '') and (not SlaveExport) then
      begin
        s := ChangeFileExt(ExtractFileName(frxUnixPath2WinPath(Report.FileName)), SaveDialog1.DefaultExt);
        SaveDialog1.FileName := s;
      end
      else
        SaveDialog1.FileName := FileName;

      OpenCB.Checked := OpenAfterExport;
      CompressedCB.Checked := Compressed;
      EmbeddedCB.Checked := EmbeddedFonts;

      OutlineCB.Checked := Outline;
      OutlineCB.Enabled := Outline;
      BackgrCB.Checked := Background;

      if PageNumbers <> '' then
      begin
        PageNumbersE.Text := PageNumbers;
        PageNumbersRB.Checked := True;
      end;

      cbPDFA.Checked := PDFA;

      TitleE.Text := Title;
      AuthorE.Text := Author;
      SubjectE.Text := Subject;
      KeywordsE.Text := Keywords;
      CreatorE.Text := Creator;

      FitWindowCB.Checked := FitWindow;
      HideMenubarCB.Checked := HideMenubar;
      CenterWindowCB.Checked := CenterWindow;
      HideWindowUICB.Checked := HideWindowUI;
      HideToolbarCB.Checked := HideToolbar;

      Result := ShowModal;
      if Result = mrOk then
      begin
        PageNumbers := '';
        CurPage := False;
        if CurPageRB.Checked then
          CurPage := True
        else if PageNumbersRB.Checked then
          PageNumbers := PageNumbersE.Text;

        OpenAfterExport := OpenCB.Checked;
        Compressed := CompressedCB.Checked;
        EmbeddedFonts := EmbeddedCB.Checked;
        Outline := OutlineCB.Checked;
        Background := BackgrCB.Checked;
        PDFA := cbPDFA.Checked;

        Title := TitleE.Text;
        Author := AuthorE.Text;
        Subject := SubjectE.Text;
        Keywords := KeywordsE.Text;
        Creator := CreatorE.Text;

        FitWindow := FitWindowCB.Checked;
        HideMenubar := HideMenubarCB.Checked;
        CenterWindow := CenterWindowCB.Checked;
        HideWindowUI := HideWindowUICB.Checked;
        HideToolbar := HideToolbarCB.Checked;

        if not SlaveExport then
        begin
          if DefaultPath <> '' then
            SaveDialog1.InitialDir := DefaultPath;
          if SaveDialog1.Execute then
            FileName := SaveDialog1.FileName
          else
            Result := mrCancel;
        end;
      end;
      Free;
    end;
  end else
    Result := mrOk;
end;

function TfrxSynPDFExport.Start: Boolean;
var
  vPdfViewerPreferences: TPdfViewerPreferences;
begin
  result := true;
  PdfDocument.NewDoc;
  PdfDocument.Info.CreationDate := CreationTime;
  PdfDocument.Info.ModDate := CreationTime;
  PdfDocument.Info.Author := Author;
  PdfDocument.Info.Subject := Subject;
  PdfDocument.Info.Keywords := Keywords;
  PdfDocument.Info.Creator := Creator;

  vPdfViewerPreferences := [];
  if FitWindow then Include(vPdfViewerPreferences, vpFitWindow);
  if HideMenubar then Include(vPdfViewerPreferences, vpHideMenubar);
  if CenterWindow then Include(vPdfViewerPreferences, vpCenterWindow);
  if HideWindowUI then Include(vPdfViewerPreferences, vpHideWindowUI);
  if HideToolbar then Include(vPdfViewerPreferences, vpHideToolbar);
  if vPdfViewerPreferences <> PdfDocument.Root.ViewerPreference then  
    PdfDocument.Root.ViewerPreference := vPdfViewerPreferences;

  if Compressed then  
    PdfDocument.CompressionMethod := cmFlateDecode
  else
    PdfDocument.CompressionMethod := cmNone;

  PdfDocument.UseOutlines := Outline;
  PdfDocument.PDFA1 := PDFA;
  PdfDocument.EmbeddedTTF := EmbeddedFonts;
end;

procedure TfrxSynPDFExport.StartPage(Page: TfrxReportPage; Index: Integer);
begin
  inherited;
  PdfDocument.DefaultPageLandscape := Page.Orientation = poLandscape;
  PdfDocument.AddPage;
end;

procedure TfrxSynPDFExport.ExportObject(Obj: TfrxComponent);
var
  z: Integer;
begin
  if (Obj is TfrxView) and (ExportNotPrintable or TfrxView(Obj).Printable) then
  begin
    if Background or not (Obj.Name = '_pagebackground') then
    begin
      z := Round(Obj.AbsLeft * FDiv);
      if z < FMinX then
        FMinX := z;
      z := FYOffset + Round(Obj.AbsTop * FDiv);
      if z < FMinY then
        FMinY := z;
      z := Round((Obj.AbsLeft + Obj.Width) * FDiv) + 1;
      if z > FMaxX then
        FMaxX := z;
      z := FYOffset + Round((Obj.AbsTop + Obj.Height) * FDiv) + 1;
      if z > FMaxY then
        FMaxY := z;
      TfrxView(Obj).Draw(PdfDocument.VCLCanvas , FDiv, FDiv, 0, FYOffset);
    end;
  end;
end;

procedure TfrxExportSynPdf.FormCreate(Sender: TObject);
begin

  Caption := frxGet(8700);
  OkB.Caption := frxGet(1);
  CancelB.Caption := frxGet(2);
  GroupPageRange.Caption := frxGet(7);
  AllRB.Caption := frxGet(3);
  CurPageRB.Caption := frxGet(4);
  PageNumbersRB.Caption := frxGet(5);
  DescrL.Caption := frxGet(9);
  GroupQuality.Caption := frxGet(8);
  CompressedCB.Caption := frxGet(8701);
  EmbeddedCB.Caption := frxGet(8702);
  OutlineCB.Caption := frxGet(8704);
  BackgrCB.Caption := frxGet(8705);
  OpenCB.Caption := frxGet(8706);
  SaveDialog1.Filter := frxGet(8707);
  SaveDialog1.DefaultExt := frxGet(8708);

  ExportPage.Caption := frxGet(107);
  DocInfoGB.Caption := frxGet(8971);
  InfoPage.Caption := frxGet(8972);
  TitleL.Caption := frxGet(8973);
  AuthorL.Caption := frxGet(8974);
  SubjectL.Caption := frxGet(8975);
  KeywordsL.Caption := frxGet(8976);
  CreatorL.Caption := frxGet(8977);

  ViewerPage.Caption := frxGet(8981);
  ViewerGB.Caption := frxGet(8982);
  HideToolbarCB.Caption := frxGet(8983);
  HideMenubarCB.Caption := frxGet(8984);
  HideWindowUICB.Caption := frxGet(8985);
  FitWindowCB.Caption := frxGet(8986);
  CenterWindowCB.Caption := frxGet(8987);

  if UseRightToLeftAlignment then
    FlipChildren(True);
end;

procedure TfrxExportSynPdf.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if Key = VK_F1 then
    frxResources.Help(Self);
end;

procedure TfrxExportSynPdf.PageNumbersEChange(Sender: TObject);
begin
  PageNumbersRB.Checked := True;
end;

procedure TfrxExportSynPdf.PageNumbersEKeyPress(Sender: TObject; var Key: Char);
begin
  case key of
    '0'..'9':;
    #8, '-', ',':;
  else
    key := #0;
  end;
end;

end.

Offline

#19 2016-03-01 23:49:12

miab3
Member
From: Poland
Registered: 2014-10-01
Posts: 188

Re: FastReport PDF export using SynPDF

@ab,

In the Fastreport 5.4.4 (published yesterday) is an example of use this module with mORMot.

Michal

Last edited by miab3 (2016-03-01 23:51:30)

Offline

#20 2017-03-23 11:32:38

CarlosM
Member
Registered: 2017-03-23
Posts: 7

Re: FastReport PDF export using SynPDF

Hello,

I have issues with exporting ShapeView, Barcode2dView and gradients.

See these images:

Show in frxPreview
Fastreport with SynPDF

Render with synPDF
Fastreport with SynPDF

Other
Fastreport with SynPDF

Last edited by CarlosM (2017-03-29 11:05:01)

Offline

#21 2017-04-13 14:14:39

WBTeam
Member
Registered: 2017-01-31
Posts: 7

Re: FastReport PDF export using SynPDF

We're using Fast Report 5.6, and we export Fast Report report's as meta file, then we use SynPDF to create PDF files from those metafiles (.emf).

We've been experiencing various display issues, clipping issues, words overlapping each others, and so on, but all of those issues are fixed and we have a very good results using the RenderMetaFile method this way:

Pdf.Canvas.RenderMetaFile(pMetaFile, 1.1, 0, 0, 0, tpSetTextJustification, 0, 0, tcNeverClip);

Hope this helps!

Last edited by WBTeam (2017-04-14 15:22:22)

Offline

#22 2017-04-13 15:36:51

CarlosM
Member
Registered: 2017-03-23
Posts: 7

Re: FastReport PDF export using SynPDF

You don´t use synexportfilter ?

call directly to this function ?

Offline

#23 2017-04-14 06:51:51

WBTeam
Member
Registered: 2017-01-31
Posts: 7

Re: FastReport PDF export using SynPDF

We don't use the frxSynPdfExport filter because it has the mentionned issues (clipping, word position, and so on).

Offline

#24 2017-04-14 07:02:58

CarlosM
Member
Registered: 2017-03-23
Posts: 7

Re: FastReport PDF export using SynPDF

Could you paste code used for export from FastReport 5.6 ?

Thank you

Offline

#25 2017-04-14 07:45:34

gsunr
Member
Registered: 2017-04-11
Posts: 2

Re: FastReport PDF export using SynPDF

Sorry for that, but somebody have similar issue ?
https://synopse.info/forum/viewtopic.php?id=3924

Offline

Board footer

Powered by FluxBB