You've already forked lazarus-ccr
fpspreadsheet: Extend fpsExport to allow export of several dataset to multiple worksheets. Update db_import_export demo.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3844 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -14,19 +14,19 @@ object Form1: TForm1
|
|||||||
Height = 302
|
Height = 302
|
||||||
Top = 4
|
Top = 4
|
||||||
Width = 631
|
Width = 631
|
||||||
ActivePage = TabDataGenerator
|
ActivePage = TabExport
|
||||||
Align = alClient
|
Align = alClient
|
||||||
BorderSpacing.Around = 4
|
BorderSpacing.Around = 4
|
||||||
TabIndex = 0
|
TabIndex = 1
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
OnChange = PageControlChange
|
OnChange = PageControlChange
|
||||||
object TabDataGenerator: TTabSheet
|
object TabDataGenerator: TTabSheet
|
||||||
Caption = '1 - Create database'
|
Caption = '1 - Create database'
|
||||||
ClientHeight = 276
|
ClientHeight = 269
|
||||||
ClientWidth = 623
|
ClientWidth = 623
|
||||||
object Label2: TLabel
|
object Label2: TLabel
|
||||||
Left = 4
|
Left = 4
|
||||||
Height = 13
|
Height = 20
|
||||||
Top = 4
|
Top = 4
|
||||||
Width = 615
|
Width = 615
|
||||||
Align = alTop
|
Align = alTop
|
||||||
@ -38,25 +38,25 @@ object Form1: TForm1
|
|||||||
end
|
end
|
||||||
object Panel1: TPanel
|
object Panel1: TPanel
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 255
|
Height = 241
|
||||||
Top = 21
|
Top = 28
|
||||||
Width = 623
|
Width = 623
|
||||||
Align = alClient
|
Align = alClient
|
||||||
BevelOuter = bvNone
|
BevelOuter = bvNone
|
||||||
ClientHeight = 255
|
ClientHeight = 241
|
||||||
ClientWidth = 623
|
ClientWidth = 623
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
object HeaderLabel1: TLabel
|
object HeaderLabel1: TLabel
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 13
|
Height = 20
|
||||||
Top = 11
|
Top = 11
|
||||||
Width = 64
|
Width = 88
|
||||||
Caption = 'Record count'
|
Caption = 'Record count'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object EdRecordCount: TEdit
|
object EdRecordCount: TEdit
|
||||||
Left = 107
|
Left = 107
|
||||||
Height = 21
|
Height = 28
|
||||||
Top = 8
|
Top = 8
|
||||||
Width = 64
|
Width = 64
|
||||||
Alignment = taRightJustify
|
Alignment = taRightJustify
|
||||||
@ -66,7 +66,7 @@ object Form1: TForm1
|
|||||||
object BtnCreateDbf: TButton
|
object BtnCreateDbf: TButton
|
||||||
Left = 515
|
Left = 515
|
||||||
Height = 28
|
Height = 28
|
||||||
Top = 222
|
Top = 208
|
||||||
Width = 99
|
Width = 99
|
||||||
Anchors = [akRight, akBottom]
|
Anchors = [akRight, akBottom]
|
||||||
Caption = 'Run'
|
Caption = 'Run'
|
||||||
@ -83,8 +83,8 @@ object Form1: TForm1
|
|||||||
end
|
end
|
||||||
object InfoLabel1: TLabel
|
object InfoLabel1: TLabel
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 13
|
Height = 20
|
||||||
Top = 237
|
Top = 216
|
||||||
Width = 496
|
Width = 496
|
||||||
Anchors = [akLeft, akRight, akBottom]
|
Anchors = [akLeft, akRight, akBottom]
|
||||||
BorderSpacing.Around = 4
|
BorderSpacing.Around = 4
|
||||||
@ -93,9 +93,9 @@ object Form1: TForm1
|
|||||||
end
|
end
|
||||||
object Label1: TLabel
|
object Label1: TLabel
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 13
|
Height = 20
|
||||||
Top = 40
|
Top = 40
|
||||||
Width = 304
|
Width = 409
|
||||||
Caption = 'Please note: the binary xls files can handle only 65536 records.'
|
Caption = 'Please note: the binary xls files can handle only 65536 records.'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
@ -103,11 +103,11 @@ object Form1: TForm1
|
|||||||
end
|
end
|
||||||
object TabExport: TTabSheet
|
object TabExport: TTabSheet
|
||||||
Caption = '2 - Export to spreadsheet'
|
Caption = '2 - Export to spreadsheet'
|
||||||
ClientHeight = 276
|
ClientHeight = 269
|
||||||
ClientWidth = 623
|
ClientWidth = 623
|
||||||
object HeaderLabel2: TLabel
|
object HeaderLabel2: TLabel
|
||||||
Left = 4
|
Left = 4
|
||||||
Height = 13
|
Height = 20
|
||||||
Top = 4
|
Top = 4
|
||||||
Width = 615
|
Width = 615
|
||||||
Align = alTop
|
Align = alTop
|
||||||
@ -120,15 +120,15 @@ object Form1: TForm1
|
|||||||
object Bevel2: TBevel
|
object Bevel2: TBevel
|
||||||
Left = 0
|
Left = 0
|
||||||
Height = 3
|
Height = 3
|
||||||
Top = 21
|
Top = 28
|
||||||
Width = 623
|
Width = 623
|
||||||
Align = alTop
|
Align = alTop
|
||||||
Shape = bsTopLine
|
Shape = bsTopLine
|
||||||
end
|
end
|
||||||
object InfoLabel2: TLabel
|
object InfoLabel2: TLabel
|
||||||
Left = 8
|
Left = 8
|
||||||
Height = 13
|
Height = 20
|
||||||
Top = 258
|
Top = 244
|
||||||
Width = 504
|
Width = 504
|
||||||
Anchors = [akLeft, akRight, akBottom]
|
Anchors = [akLeft, akRight, akBottom]
|
||||||
BorderSpacing.Around = 4
|
BorderSpacing.Around = 4
|
||||||
@ -149,7 +149,7 @@ object Form1: TForm1
|
|||||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||||
ChildSizing.ControlsPerLine = 1
|
ChildSizing.ControlsPerLine = 1
|
||||||
ClientHeight = 140
|
ClientHeight = 133
|
||||||
ClientWidth = 228
|
ClientWidth = 228
|
||||||
ItemIndex = 2
|
ItemIndex = 2
|
||||||
Items.Strings = (
|
Items.Strings = (
|
||||||
@ -164,7 +164,7 @@ object Form1: TForm1
|
|||||||
object BtnExport: TButton
|
object BtnExport: TButton
|
||||||
Left = 515
|
Left = 515
|
||||||
Height = 28
|
Height = 28
|
||||||
Top = 243
|
Top = 236
|
||||||
Width = 99
|
Width = 99
|
||||||
Anchors = [akRight, akBottom]
|
Anchors = [akRight, akBottom]
|
||||||
Caption = 'Run'
|
Caption = 'Run'
|
||||||
@ -185,12 +185,13 @@ object Form1: TForm1
|
|||||||
ChildSizing.ShrinkVertical = crsScaleChilds
|
ChildSizing.ShrinkVertical = crsScaleChilds
|
||||||
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
ChildSizing.Layout = cclLeftToRightThenTopToBottom
|
||||||
ChildSizing.ControlsPerLine = 1
|
ChildSizing.ControlsPerLine = 1
|
||||||
ClientHeight = 140
|
ClientHeight = 133
|
||||||
ClientWidth = 228
|
ClientWidth = 228
|
||||||
ItemIndex = 0
|
ItemIndex = 0
|
||||||
Items.Strings = (
|
Items.Strings = (
|
||||||
'Virtual mode (memory saving)'
|
'Virtual mode (memory saving)'
|
||||||
'FPSExport'
|
'FPSExport'
|
||||||
|
'FPSExport (multiple sheets)'
|
||||||
)
|
)
|
||||||
TabOrder = 2
|
TabOrder = 2
|
||||||
end
|
end
|
||||||
|
@ -56,11 +56,14 @@ type
|
|||||||
// Actual export code when using FPSpreadsheet's fpsexport:
|
// Actual export code when using FPSpreadsheet's fpsexport:
|
||||||
// reads dbf and writes to spreadsheet
|
// reads dbf and writes to spreadsheet
|
||||||
// Expects FExportDataset to be available
|
// Expects FExportDataset to be available
|
||||||
procedure ExportUsingFPSExport(var DataFileName: string);
|
procedure ExportUsingFPSExport(MultipleSheets: Boolean; var DataFileName: string);
|
||||||
// Actual export code when using virtual mode:
|
// Actual export code when using virtual mode:
|
||||||
// reads dbf and writes to spreadsheet
|
// reads dbf and writes to spreadsheet
|
||||||
// Expects FExportDataset to be available
|
// Expects FExportDataset to be available
|
||||||
procedure ExportUsingVirtualMode(var DataFileName: string);
|
procedure ExportUsingVirtualMode(var DataFileName: string);
|
||||||
|
// FPSExport: Get sheet name
|
||||||
|
procedure ExporterGetSheetNameHandler(Sender: TObject; ASheetIndex: Integer;
|
||||||
|
var ASheetName: String);
|
||||||
// Virtual mode: for reading: all data for the database is generated here out of the spreadsheet file
|
// Virtual mode: for reading: all data for the database is generated here out of the spreadsheet file
|
||||||
procedure ReadCellDataHandler(Sender: TObject; ARow, ACol: Cardinal;
|
procedure ReadCellDataHandler(Sender: TObject; ARow, ACol: Cardinal;
|
||||||
const ADataCell: PCell);
|
const ADataCell: PCell);
|
||||||
@ -81,8 +84,11 @@ implementation
|
|||||||
type
|
type
|
||||||
// Ways to export dbf/dataset. Corresponds to the items
|
// Ways to export dbf/dataset. Corresponds to the items
|
||||||
// of the RgExportMode radiogroup
|
// of the RgExportMode radiogroup
|
||||||
TsExportModes=(seVirtual {manual coding using Virtual Mode},
|
TsExportModes=(
|
||||||
seFPSExport {uses FpSpreadsheet's fpsexport - takes more memory});
|
seVirtual, {manual coding using Virtual Mode}
|
||||||
|
seFPSExport, {uses FpSpreadsheet's fpsexport - takes more memory}
|
||||||
|
seFPSExportMulti {uses FpSpreadsheetÄs fpsexport to multiple sheets}
|
||||||
|
);
|
||||||
|
|
||||||
const
|
const
|
||||||
// Parameters for generating dbf file contents
|
// Parameters for generating dbf file contents
|
||||||
@ -197,8 +203,12 @@ begin
|
|||||||
try
|
try
|
||||||
InfoLabel1.Caption := ('Starting database export.');
|
InfoLabel1.Caption := ('Starting database export.');
|
||||||
case TsExportModes(RgExportMode.ItemIndex) of
|
case TsExportModes(RgExportMode.ItemIndex) of
|
||||||
seVirtual: ExportUsingVirtualMode(DataFileName);
|
seVirtual:
|
||||||
seFPSExport: ExportUsingFPSExport(DataFileName);
|
ExportUsingVirtualMode(DataFileName);
|
||||||
|
seFPSExport:
|
||||||
|
ExportUsingFPSExport(false, DataFileName);
|
||||||
|
seFPSExportMulti:
|
||||||
|
ExportUsingFPSExport(true, DataFileName);
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
ShowMessageFmt('Unknown export mode number %d. Please correct source code.',[RgExportMode.ItemIndex]);
|
ShowMessageFmt('Unknown export mode number %d. Please correct source code.',[RgExportMode.ItemIndex]);
|
||||||
@ -298,7 +308,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TForm1.ExportUsingFPSExport(var DataFileName: string);
|
procedure TForm1.ExportUsingFPSExport(MultipleSheets: Boolean;
|
||||||
|
var DataFileName: string);
|
||||||
var
|
var
|
||||||
Exporter: TFPSExport;
|
Exporter: TFPSExport;
|
||||||
ExportSettings: TFPSExportFormatSettings;
|
ExportSettings: TFPSExportFormatSettings;
|
||||||
@ -315,18 +326,21 @@ begin
|
|||||||
ExportSettings.HeaderRow := true;
|
ExportSettings.HeaderRow := true;
|
||||||
case FILE_FORMATS[RgFileFormat.ItemIndex] of
|
case FILE_FORMATS[RgFileFormat.ItemIndex] of
|
||||||
sfExcel2, sfExcel5:
|
sfExcel2, sfExcel5:
|
||||||
begin
|
begin
|
||||||
ShowMessage('Format not supported using this mode.');
|
ShowMessage('Format not supported using this mode.');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
sfExcel8: ExportSettings.ExportFormat := efXLS;
|
sfExcel8:
|
||||||
sfOOXML: ExportSettings.ExportFormat := efXLSX;
|
ExportSettings.ExportFormat := efXLS;
|
||||||
sfOpenDocument: ExportSettings.ExportFormat := efODS;
|
sfOOXML:
|
||||||
|
ExportSettings.ExportFormat := efXLSX;
|
||||||
|
sfOpenDocument:
|
||||||
|
ExportSettings.ExportFormat := efODS;
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
ShowMessage('Unknown export format. Please correct the source code.');
|
ShowMessage('Unknown export format. Please correct the source code.');
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
// Actually apply settings
|
// Actually apply settings
|
||||||
Exporter.FormatSettings := ExportSettings;
|
Exporter.FormatSettings := ExportSettings;
|
||||||
@ -335,7 +349,32 @@ begin
|
|||||||
Exporter.Dataset := FExportDataset;
|
Exporter.Dataset := FExportDataset;
|
||||||
Exporter.FileName := ChangeFileExt(DataFileName, FILE_EXT[
|
Exporter.FileName := ChangeFileExt(DataFileName, FILE_EXT[
|
||||||
RgFileFormat.ItemIndex]);
|
RgFileFormat.ItemIndex]);
|
||||||
Exporter.Execute;
|
|
||||||
|
// Export to multiple sheets
|
||||||
|
if MultipleSheets then
|
||||||
|
begin
|
||||||
|
Exporter.MultipleSheets := true;
|
||||||
|
Exporter.OnGetSheetName := @ExporterGetSheetNameHandler;
|
||||||
|
|
||||||
|
// On the first sheet we want "Last name", "First name" and "City"
|
||||||
|
Exporter.ExportFields.AddField('Last name');
|
||||||
|
Exporter.ExportFields.AddField('First name');
|
||||||
|
Exporter.ExportFields.AddField('City');
|
||||||
|
Exporter.Execute;
|
||||||
|
|
||||||
|
// On the second sheet we want "Last name", "First name" and "Birthday"
|
||||||
|
Exporter.ExportFields.Clear;
|
||||||
|
Exporter.ExportFields.AddField('Last name');
|
||||||
|
Exporter.ExportFields.AddField('First name');
|
||||||
|
Exporter.ExportFields.AddField('Birthday');
|
||||||
|
Exporter.Execute;
|
||||||
|
|
||||||
|
// Export complete --> we can write to file
|
||||||
|
Exporter.WriteExportFile;
|
||||||
|
end
|
||||||
|
// Export of all records to single sheet
|
||||||
|
else
|
||||||
|
Exporter.Execute;
|
||||||
finally
|
finally
|
||||||
Exporter.Free;
|
Exporter.Free;
|
||||||
ExportSettings.Free;
|
ExportSettings.Free;
|
||||||
@ -441,6 +480,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Determines the sheet name of the export using FPExport }
|
||||||
|
procedure TForm1.ExporterGetSheetNameHandler(Sender: TObject; ASheetIndex: Integer;
|
||||||
|
var ASheetName: String);
|
||||||
|
begin
|
||||||
|
case ASheetIndex of
|
||||||
|
0: ASheetName := 'Cities';
|
||||||
|
1: ASheetName := 'Birthdays';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{ This is the event handler for reading a spreadsheet file in virtual mode.
|
{ This is the event handler for reading a spreadsheet file in virtual mode.
|
||||||
ADataCell has just been read from the spreadsheet file, but will not be added
|
ADataCell has just been read from the spreadsheet file, but will not be added
|
||||||
to the workbook and will be discarded. The event handler, however, can pick
|
to the workbook and will be discarded. The event handler, however, can pick
|
||||||
|
@ -11,7 +11,8 @@ unit fpsexport;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, db, fpsallformats, fpspreadsheet, fpsstrings, fpdbexport;
|
Classes, SysUtils, db,
|
||||||
|
{%H-}fpsallformats, fpspreadsheet, fpsstrings, fpdbexport;
|
||||||
|
|
||||||
Type
|
Type
|
||||||
|
|
||||||
@ -32,17 +33,24 @@ Type
|
|||||||
private
|
private
|
||||||
FExportFormat: TExportFormat;
|
FExportFormat: TExportFormat;
|
||||||
FHeaderRow: boolean;
|
FHeaderRow: boolean;
|
||||||
|
FSheetName: String;
|
||||||
public
|
public
|
||||||
procedure Assign(Source : TPersistent); override;
|
procedure Assign(Source : TPersistent); override;
|
||||||
procedure InitSettings; override;
|
procedure InitSettings; override;
|
||||||
published
|
published
|
||||||
{@@ File format for the export }
|
{@@ File format for the export }
|
||||||
property ExportFormat: TExportFormat read FExportFormat write FExportFormat;
|
property ExportFormat: TExportFormat read FExportFormat write FExportFormat;
|
||||||
{@@ Flag that determines whethe to write the field list to the first
|
{@@ Flag that determines whether to write the field list to the first
|
||||||
row of the spreadsheet }
|
row of the spreadsheet }
|
||||||
property HeaderRow: boolean read FHeaderRow write FHeaderRow default false;
|
property HeaderRow: boolean read FHeaderRow write FHeaderRow default false;
|
||||||
|
{@@ Sheet name }
|
||||||
|
property SheetName: String read FSheetName write FSheetName;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TGetSheetNameEvent }
|
||||||
|
TsGetSheetNameEvent = procedure (Sender: TObject; ASheetIndex: Integer;
|
||||||
|
var ASheetName: String) of object;
|
||||||
|
|
||||||
{ TCustomFPSExport }
|
{ TCustomFPSExport }
|
||||||
TCustomFPSExport = Class(TCustomDatasetExporter)
|
TCustomFPSExport = Class(TCustomDatasetExporter)
|
||||||
private
|
private
|
||||||
@ -50,23 +58,36 @@ Type
|
|||||||
FSpreadsheet: TsWorkbook;
|
FSpreadsheet: TsWorkbook;
|
||||||
FSheet: TsWorksheet;
|
FSheet: TsWorksheet;
|
||||||
FFileName: string;
|
FFileName: string;
|
||||||
|
FMultipleSheets: Boolean;
|
||||||
|
FOnGetSheetName: TsGetSheetNameEvent;
|
||||||
|
function CalcSheetNameMask(const AMask: String): String;
|
||||||
|
function CalcUniqueSheetName(const AMask: String): String;
|
||||||
function GetSettings: TFPSExportFormatSettings;
|
function GetSettings: TFPSExportFormatSettings;
|
||||||
|
procedure SaveWorkbook;
|
||||||
procedure SetSettings(const AValue: TFPSExportFormatSettings);
|
procedure SetSettings(const AValue: TFPSExportFormatSettings);
|
||||||
protected
|
protected
|
||||||
function CreateFormatSettings: TCustomExportFormatSettings; override;
|
|
||||||
|
|
||||||
function CreateExportFields: TExportFields; override;
|
function CreateExportFields: TExportFields; override;
|
||||||
|
function CreateFormatSettings: TCustomExportFormatSettings; override;
|
||||||
procedure DoBeforeExecute; override;
|
procedure DoBeforeExecute; override;
|
||||||
procedure DoAfterExecute; override;
|
procedure DoAfterExecute; override;
|
||||||
procedure DoDataHeader; override;
|
procedure DoDataHeader; override;
|
||||||
procedure DoDataRowEnd; override;
|
procedure DoDataRowEnd; override;
|
||||||
|
function DoGetSheetName: String; virtual;
|
||||||
procedure ExportField(EF : TExportFieldItem); override;
|
procedure ExportField(EF : TExportFieldItem); override;
|
||||||
property FileName: String read FFileName write FFileName;
|
property FileName: String read FFileName write FFileName;
|
||||||
property Workbook: TsWorkbook read FSpreadsheet;
|
property Workbook: TsWorkbook read FSpreadsheet;
|
||||||
|
property RestorePosition default true;
|
||||||
|
property OnGetSheetName: TsGetSheetNameEvent read FOnGetSheetName write FOnGetSheetName;
|
||||||
public
|
public
|
||||||
|
constructor Create(AOwner: TComponent); override;
|
||||||
|
destructor Destroy; override;
|
||||||
|
procedure WriteExportFile;
|
||||||
{@@ Settings for the export. Note: a lot of generic settings are preent
|
{@@ Settings for the export. Note: a lot of generic settings are preent
|
||||||
that are not relevant for this export, e.g. decimal point settings }
|
that are not relevant for this export, e.g. decimal point settings }
|
||||||
property FormatSettings: TFPSExportFormatSettings read GetSettings write SetSettings;
|
property FormatSettings: TFPSExportFormatSettings read GetSettings write SetSettings;
|
||||||
|
{@@ MultipleSheets: export several datasets to multiple sheets in
|
||||||
|
the sasme file. Otherwise a single-sheet workbook is created. }
|
||||||
|
property MultipleSheets: Boolean read FMultipleSheets write FMultipleSheets default false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TFPSExport }
|
{ TFPSExport }
|
||||||
@ -87,6 +108,8 @@ Type
|
|||||||
property RestorePosition;
|
property RestorePosition;
|
||||||
{@@ Procedure to run when exporting a row }
|
{@@ Procedure to run when exporting a row }
|
||||||
property OnExportRow;
|
property OnExportRow;
|
||||||
|
{@@ Determines the name of the worksheet }
|
||||||
|
property OnGetSheetName;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@ Register export format with fpsdbexport so it can be dynamically used }
|
{@@ Register export format with fpsdbexport so it can be dynamically used }
|
||||||
@ -103,6 +126,24 @@ implementation
|
|||||||
|
|
||||||
{ TCustomFPSExport }
|
{ TCustomFPSExport }
|
||||||
|
|
||||||
|
constructor TCustomFPSExport.Create(AOwner: TComponent);
|
||||||
|
begin
|
||||||
|
inherited Create(AOwner);
|
||||||
|
RestorePosition := true;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TCustomFPSExport.Destroy;
|
||||||
|
begin
|
||||||
|
// Last chance to save file if calling WriteExportFile has been forgottem
|
||||||
|
// in case of multiple sheets.
|
||||||
|
if FMultipleSheets and (FSpreadsheet <> nil) then
|
||||||
|
begin
|
||||||
|
SaveWorkbook;
|
||||||
|
FreeAndNil(FSpreadsheet);
|
||||||
|
end;
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
function TCustomFPSExport.GetSettings: TFPSExportFormatSettings;
|
function TCustomFPSExport.GetSettings: TFPSExportFormatSettings;
|
||||||
begin
|
begin
|
||||||
result:=TFPSExportFormatSettings(Inherited FormatSettings);
|
result:=TFPSExportFormatSettings(Inherited FormatSettings);
|
||||||
@ -129,11 +170,17 @@ begin
|
|||||||
Inherited;
|
Inherited;
|
||||||
if FFileName='' then
|
if FFileName='' then
|
||||||
Raise EDataExporter.Create(rsExportFileIsRequired);
|
Raise EDataExporter.Create(rsExportFileIsRequired);
|
||||||
FSpreadsheet:=TsWorkbook.Create;
|
if (not RestorePosition) and FMultipleSheets then
|
||||||
// For extra performance. Note that virtual mode is not an option
|
Raise EDataExporter.Create(rsMultipleSheetsOnlyWithRestorePosition);
|
||||||
// due to the data export determining flow of the program.
|
|
||||||
FSpreadsheet.Options:=FSpreadsheet.Options+[boBufStream];
|
if (not FMultipleSheets) or (FSpreadsheet = nil) then
|
||||||
FSheet:=FSpreadsheet.AddWorksheet('1');
|
begin
|
||||||
|
FSpreadsheet:=TsWorkbook.Create;
|
||||||
|
FSpreadsheet.Options:=FSpreadsheet.Options+[boBufStream];
|
||||||
|
// For extra performance. Note that virtual mode is not an option
|
||||||
|
// due to the data export determining flow of the program.
|
||||||
|
end;
|
||||||
|
FSheet:=FSpreadsheet.AddWorksheet(DoGetSheetName);
|
||||||
FRow:=0;
|
FRow:=0;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -152,25 +199,34 @@ begin
|
|||||||
inherited DoDataHeader;
|
inherited DoDataHeader;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomFPSExport.DoAfterExecute;
|
{ Writes the workbook populated during the export process to file }
|
||||||
|
procedure TCustomFPSExport.SaveWorkbook;
|
||||||
begin
|
begin
|
||||||
FRow:=0;
|
FRow:=0;
|
||||||
// Overwrite existing file similar to how dbf export does it
|
// Overwrite existing file similar to how dbf export does it
|
||||||
case Formatsettings.ExportFormat of
|
case Formatsettings.ExportFormat of
|
||||||
efXLS: FSpreadSheet.WriteToFile(FFileName,sfExcel8,true);
|
efXLS:
|
||||||
efXLSX: FSpreadsheet.WriteToFile(FFilename,sfOOXML,true);
|
FSpreadSheet.WriteToFile(FFileName,sfExcel8,true);
|
||||||
efODS: FSpreadSheet.WriteToFile(FFileName,sfOpenDocument,true);
|
efXLSX:
|
||||||
efWikiTable: FSpreadSheet.WriteToFile(FFileName,sfWikitable_wikimedia,true);
|
FSpreadsheet.WriteToFile(FFilename,sfOOXML,true);
|
||||||
|
efODS:
|
||||||
|
FSpreadSheet.WriteToFile(FFileName,sfOpenDocument,true);
|
||||||
|
efWikiTable:
|
||||||
|
FSpreadSheet.WriteToFile(FFileName,sfWikitable_wikimedia,true);
|
||||||
else
|
else
|
||||||
;// raise error?
|
raise Exception.Create('[TCustomFPSExport.SaveWorkbook] ExportFormat unknown');
|
||||||
end;
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
// Don't free FSheet; done by FSpreadsheet
|
procedure TCustomFPSExport.DoAfterExecute;
|
||||||
try
|
begin
|
||||||
FreeAndNil(FSpreadsheet);
|
if not FMultipleSheets then
|
||||||
finally
|
begin
|
||||||
Inherited;
|
SaveWorkbook;
|
||||||
|
FreeAndNil(FSpreadsheet); // Don't free FSheet; done by FSpreadsheet
|
||||||
end;
|
end;
|
||||||
|
// Multi-sheet workbooks are written when WriteExportFile is called.
|
||||||
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomFPSExport.DoDataRowEnd;
|
procedure TCustomFPSExport.DoDataRowEnd;
|
||||||
@ -178,6 +234,59 @@ begin
|
|||||||
FRow:=FRow+1;
|
FRow:=FRow+1;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TCustomFPSExport.CalcSheetNameMask(const AMask: String): String;
|
||||||
|
begin
|
||||||
|
Result := AMask;
|
||||||
|
// No %d in the mask string
|
||||||
|
if pos('%d', Result) = 0 then
|
||||||
|
begin
|
||||||
|
// If the mask string is already used we'll add a number to the sheet name
|
||||||
|
if not FSpreadsheet.ValidWorksheetName(Result) then
|
||||||
|
begin
|
||||||
|
Result := AMask + '%d';
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TCustomFPSExport.CalcUniqueSheetName(const AMask: String): String;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
if pos('%d', AMask) > 0 then
|
||||||
|
begin
|
||||||
|
i := 0;
|
||||||
|
repeat
|
||||||
|
inc(i);
|
||||||
|
Result := Format(AMask, [i]);
|
||||||
|
until (FSpreadsheet.GetWorksheetByName(Result) = nil);
|
||||||
|
end else
|
||||||
|
Result := AMask;
|
||||||
|
if not FSpreadsheet.ValidWorksheetName(Result) then
|
||||||
|
Raise EDataExporter.CreateFmt(rsInvalidWorksheetName, [Result]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ Method which provides the name of the worksheet into which the dataset is to
|
||||||
|
be exported. There are several cases:
|
||||||
|
(1) Use the name defined in the FormatSettings.
|
||||||
|
(2) Provide the name in an event handler for OnGetSheetname.
|
||||||
|
The name provided from these sources can contain a %d placeholder which will
|
||||||
|
be replaced by a number such that the sheet name is unique.
|
||||||
|
If it does not contain a %d then a %d may be added if needed to get a unique
|
||||||
|
sheet name. }
|
||||||
|
function TCustomFPSExport.DoGetSheetName: String;
|
||||||
|
var
|
||||||
|
mask: String;
|
||||||
|
begin
|
||||||
|
mask := CalcSheetNameMask(FormatSettings.SheetName);
|
||||||
|
Result := CalcUniqueSheetName(mask);
|
||||||
|
if Assigned(FOnGetSheetName) then
|
||||||
|
begin
|
||||||
|
FOnGetSheetName(Self, FSpreadsheet.GetWorksheetCount, mask);
|
||||||
|
Result := CalcUniqueSheetName(mask);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TCustomFPSExport.ExportField(EF: TExportFieldItem);
|
procedure TCustomFPSExport.ExportField(EF: TExportFieldItem);
|
||||||
var
|
var
|
||||||
F : TFPSExportFieldItem;
|
F : TFPSExportFieldItem;
|
||||||
@ -210,6 +319,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCustomFPSExport.WriteExportFile;
|
||||||
|
begin
|
||||||
|
if FMultipleSheets then begin
|
||||||
|
SaveWorkbook;
|
||||||
|
FreeAndNil(FSpreadsheet);
|
||||||
|
// Don't free FSheet; done by FSpreadsheet
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure RegisterFPSExportFormat;
|
procedure RegisterFPSExportFormat;
|
||||||
begin
|
begin
|
||||||
ExportFormats.RegisterExportFormat(SFPSExport,rsFPSExportDescription,SPFSExtension,TFPSExport);
|
ExportFormats.RegisterExportFormat(SFPSExport,rsFPSExportDescription,SPFSExtension,TFPSExport);
|
||||||
@ -229,8 +348,9 @@ begin
|
|||||||
If Source is TFPSExportFormatSettings then
|
If Source is TFPSExportFormatSettings then
|
||||||
begin
|
begin
|
||||||
FS:=Source as TFPSExportFormatSettings;
|
FS:=Source as TFPSExportFormatSettings;
|
||||||
HeaderRow:=FS.HeaderRow;
|
HeaderRow := FS.HeaderRow;
|
||||||
ExportFormat:=FS.ExportFormat;
|
ExportFormat := FS.ExportFormat;
|
||||||
|
SheetName := FS.SheetName;
|
||||||
end;
|
end;
|
||||||
inherited Assign(Source);
|
inherited Assign(Source);
|
||||||
end;
|
end;
|
||||||
@ -238,7 +358,8 @@ end;
|
|||||||
procedure TFPSExportFormatSettings.InitSettings;
|
procedure TFPSExportFormatSettings.InitSettings;
|
||||||
begin
|
begin
|
||||||
inherited InitSettings;
|
inherited InitSettings;
|
||||||
FExportFormat:=efXLS; //often used format
|
FExportFormat := efXLS; //often used format
|
||||||
|
FSheetName := 'Sheet';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -12,6 +12,8 @@ interface
|
|||||||
resourcestring
|
resourcestring
|
||||||
rsExportFileIsRequired = 'Export file name is required';
|
rsExportFileIsRequired = 'Export file name is required';
|
||||||
rsFPSExportDescription = 'Spreadsheet file';
|
rsFPSExportDescription = 'Spreadsheet file';
|
||||||
|
rsMultipleSheetsOnlyWithRestorePosition = 'Export to multiple sheets is possible '+
|
||||||
|
'only if position is restored.';
|
||||||
rsUnsupportedReadFormat = 'Tried to read a spreadsheet using an unsupported format';
|
rsUnsupportedReadFormat = 'Tried to read a spreadsheet using an unsupported format';
|
||||||
rsUnsupportedWriteFormat = 'Tried to write a spreadsheet using an unsupported format';
|
rsUnsupportedWriteFormat = 'Tried to write a spreadsheet using an unsupported format';
|
||||||
rsNoValidSpreadsheetFile = '"%s" is not a valid spreadsheet file';
|
rsNoValidSpreadsheetFile = '"%s" is not a valid spreadsheet file';
|
||||||
|
Reference in New Issue
Block a user