lazarus-ccr/components/fpspreadsheet/examples/other/demo_virtualmode_write.lpr

121 lines
4.0 KiB
ObjectPascal

program demo_virtualmode_write;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}
{$IFDEF UseCThreads}
cthreads,
{$ENDIF}
{$ENDIF}
Classes, SysUtils, lazutf8, variants,
fpstypes, fpspreadsheet, fpsallformats;
type
TDataProvider = class
procedure WriteCellDataHandler(Sender: TsWorksheet; ARow,ACol: Cardinal;
var AData: variant; var AStyleCell: PCell);
end;
var
workbook: TsWorkbook;
worksheet: TsWorksheet;
dataprovider: TDataProvider;
headerTemplate: PCell;
t: TTime;
procedure TDataProvider.WriteCellDataHandler(Sender: TsWorksheet;
ARow, ACol: Cardinal; var AData: variant; var AStyleCell: PCell);
{ This is just a sample using random data. Normally, in case of a database,
you would read a record and return its field values, such as:
Dataset.Fields[ACol].AsVariant := AData;
if ACol = Dataset.FieldCount then Dataset.Next;
// NOTE: you have to take care of advancing the database cursor!
}
var
s: String;
begin
if ARow = 0 then begin
AData := Format('Column %d', [ACol + 1]);
AStyleCell := headerTemplate;
// This makes the style of the "headerTemplate" cell available to
// formatting of all virtual cells in row 0.
// Important: The template cell must be an existing cell in the worksheet.
end else
if (ACol = 0) then
AData := NULL // Let's skip the column #0
else
if odd(random(10)) then begin
AData := Format('R=%d-C=%d', [ARow, ACol]);
end else
AData := 10000*ARow + ACol;
// you can use the event handler also to provide feedback on how the process
// progresses:
if (ACol = 0) and (ARow mod 1000 = 0) then
WriteLn('Writing row ', ARow, '...');
end;
begin
dataprovider := TDataProvider.Create;
try
workbook := TsWorkbook.Create;
try
worksheet := workbook.AddWorksheet('Sheet1');
worksheet.WriteFontStyle(0, 1, [fssBold]);
{ These are the essential commands to activate virtual mode: }
// workbook.Options := [boVirtualMode, boBufStream];
workbook.Options := [boVirtualMode];
{ boBufStream can be omitted, but is important for large files: it causes
writing temporary data to a buffered file stream instead of a pure
memory stream which can overflow memory. In cases, the option can slow
down the writing process a bit. }
{ Next two numbers define the size of virtual spreadsheet.
In case of a database, VirtualRowCount is the RecordCount, VirtualColCount
the number of fields to be written to the spreadsheet file }
worksheet.VirtualRowCount := 20000;
worksheet.VirtualColCount := 100;
{ The event handler for OnWriteCellData links the workbook to the method
from which it gets the data to be written. }
worksheet.OnWriteCellData := @dataprovider.WriteCellDataHandler;
{ If we want to change the format of some cells we have to provide this
format in template cells of the worksheet. In the example, the first
row whould be in bold letters and have a gray background.
Therefore, we define a "header template cell" and pass this in the
NeedCellData event handler.}
worksheet.WriteFontStyle(0, 0, [fssBold]);
worksheet.WriteBackgroundColor(0, 0, scSilver);
headerTemplate := worksheet.FindCell(0, 0);
worksheet.WriteRowHeight(0, 3);
worksheet.WriteColWidth(0, 30);
{ In case of a database, you would open the dataset before calling this: }
t := Now;
//workbook.WriteToFile('test_virtual.ods', sfOpenDocument, true);
//workbook.WriteToFile('test_virtual.xlsx', sfOOXML, true);
workbook.WriteToFile('test_virtual.xls', sfExcel8, true);
//workbook.WriteToFile('test_virtual.xls', sfExcel5, true);
//workbook.WriteToFile('test_virtual.xls', sfExcel2, true);
t := Now - t;
finally
workbook.Free;
end;
finally
dataprovider.Free;
end;
WriteLn(Format('Execution time: %.3f sec', [t*24*60*60]));
WriteLn('Press [ENTER] to quit...');
ReadLn;
end.