Table of Contents

Templates in the executable (Delphi)

Note

This demo is available in your FlexCel installation at <FlexCel Install Folder>\Demo\Delphi\Modules\20.Reports\60.Templates In The Exe and also at https:​//​github.​com/​tmssoftware/​TMS-​FlexCel.​VCL-​demos/​tree/​master/​Delphi/​Modules/​20.​Reports/​60.​Templates In The Exe

Overview

Sometimes you might want to distribute your templates embedded in your application, instead of shipping the separately.

Concepts

  • How to embed a template directly in the exe file. For step-by-step instructions please read Embedding Excel files in your application

  • Dealing with includes. Included files are normally searched on the same path as the original file, but here, as we are reading from a stream, we must tell FlexCel where to find the embedded template. This is done with the TFlexCelReport.GetInclude event.

  • While here we show how to use a stream to read a template from the executable, you can use a very similar approach to store your templates in a database, or in any place you like. Just call the TFlexCelReport.Run with a stream with your data, and assign the TFlexCelReport.GetInclude event to assign the data for the included files.

Files

UMainForm.pas

unit UMainForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  FlexCel.VCLSupport, FlexCel.Core, FlexCel.XlsAdapter, FlexCel.Report, FlexCel.Render,
  {$if CompilerVersion >= 23.0} System.UITypes, {$IFEND}
  ShellApi,
  Controls, Forms, Dialogs, StdCtrls, ExtCtrls;

type
  TMainForm = class(TForm)
    btnCancel: TButton;
    btnGo: TButton;
    SaveDialog: TSaveDialog;
    Label1: TLabel;
    procedure btnCancelClick(Sender: TObject);
    procedure btnGoClick(Sender: TObject);
  private
    procedure RunReport;
    procedure GetIncludes(const sender: TObject;const e: TGetIncludeEventArgs);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation
uses IOUtils, DemoData;

{$R *.dfm}

procedure TMainForm.btnCancelClick(Sender: TObject);
begin
  Close;
end;

procedure TMainForm.btnGoClick(Sender: TObject);
begin
  RunReport;

end;


procedure TMainForm.GetIncludes(const sender: TObject; const e: TGetIncludeEventArgs);
var
  IncReport: TResourceStream;
  b: TBytes;
begin
  IncReport := TResourceStream.Create(hinstance, TPath.GetFileNameWithoutExtension(e.FileName), RT_RCDATA);
  try
    SetLength(b, IncReport.Size);
    if (Length(b) > 0) then IncReport.ReadBuffer(b[0], Length(b));
    e.IncludeData := b;
  finally
    IncReport.Free;
  end;
end;

procedure TMainForm.RunReport;
var
  Report: TFlexCelReport;
  TemplateStream: TResourceStream;
  OutputStream: TFileStream;
begin
  if not SaveDialog.Execute then exit;

  Report := TFlexCelReport.Create(true);
  try
    Report.GetInclude := GetIncludes; //this is only needed if you have includes.
    Report.AddTable(DemoTables);
    Report.SetValue('Date', Now);

    TemplateStream := TResourceStream.Create(hinstance, 'TemplatesInTheExe', RT_RCDATA);
    try
      OutputStream := TFileStream.Create(SaveDialog.FileName, fmCreate);
      try
        Report.Run(TemplateStream, OutputStream);
      finally
        OutputStream.Free;
      end;
    finally
      TemplateStream.Free;
    end;
  finally
    Report.Free;
  end;

  if MessageDlg('Do you want to open the generated file?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
  begin
    ShellExecute(0, 'open', PCHAR(SaveDialog.FileName), nil, nil, SW_SHOWNORMAL);
  end;


end;

end.