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 On The Exe and also at https://github.com/tmssoftware/TMS-FlexCel.VCL-demos/tree/master/Delphi/Modules/20.Reports/60.Templates On 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 on a database, or on 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.Read(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, 'TemplatesOnTheExe', 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.