You've already forked lazarus-ccr
fpspreadsheet: Fix memory leak in virtual mode due to incorrectly initialized strings in the cell record.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3352 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -78,6 +78,7 @@
|
|||||||
<Linking>
|
<Linking>
|
||||||
<Debugging>
|
<Debugging>
|
||||||
<DebugInfoType Value="dsDwarf2Set"/>
|
<DebugInfoType Value="dsDwarf2Set"/>
|
||||||
|
<UseHeaptrc Value="True"/>
|
||||||
</Debugging>
|
</Debugging>
|
||||||
</Linking>
|
</Linking>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
|
@ -7,7 +7,7 @@ uses
|
|||||||
cthreads,
|
cthreads,
|
||||||
{$ENDIF}{$ENDIF}
|
{$ENDIF}{$ENDIF}
|
||||||
Classes, laz_fpspreadsheet,
|
Classes, laz_fpspreadsheet,
|
||||||
{ you can add units after this }
|
{ you can add units after this } lazutf8,
|
||||||
SysUtils, variants, fpspreadsheet, xlsbiff2, xlsbiff5, xlsbiff8, xlsxooxml;
|
SysUtils, variants, fpspreadsheet, xlsbiff2, xlsbiff5, xlsbiff8, xlsxooxml;
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -41,12 +41,11 @@ var
|
|||||||
// This makes the style of the "headerTemplate" cell available to
|
// This makes the style of the "headerTemplate" cell available to
|
||||||
// formatting of all virtual cells in row 0.
|
// formatting of all virtual cells in row 0.
|
||||||
// Important: The template cell must be an existing cell in the worksheet.
|
// Important: The template cell must be an existing cell in the worksheet.
|
||||||
end else {
|
end else
|
||||||
if odd(random(10)) then }begin
|
if odd(random(10)) then begin
|
||||||
s := Format('R=%d-C=%d', [ARow, ACol]);
|
AData := Format('R=%d-C=%d', [ARow, ACol]);
|
||||||
AData := s;
|
end else
|
||||||
end {else
|
AData := 10000*ARow + ACol;
|
||||||
AData := 10000*ARow + ACol};
|
|
||||||
|
|
||||||
// you can use the OnNeedData also to provide feedback on how the process
|
// you can use the OnNeedData also to provide feedback on how the process
|
||||||
// progresses:
|
// progresses:
|
||||||
@ -65,8 +64,8 @@ begin
|
|||||||
|
|
||||||
{ These are the essential commands to activate virtual mode: }
|
{ These are the essential commands to activate virtual mode: }
|
||||||
|
|
||||||
workbook.WritingOptions := [woVirtualMode, woBufStream];
|
// workbook.WritingOptions := [woVirtualMode, woBufStream];
|
||||||
// workbook.WritingOptions := [woVirtualMode];
|
workbook.WritingOptions := [woVirtualMode];
|
||||||
{ woBufStream can be omitted, but is important for large files: it causes
|
{ woBufStream can be omitted, but is important for large files: it causes
|
||||||
writing temporary data to a buffered file stream instead of a pure
|
writing temporary data to a buffered file stream instead of a pure
|
||||||
memory stream which can overflow memory. The option can slow down the
|
memory stream which can overflow memory. The option can slow down the
|
||||||
@ -75,7 +74,7 @@ begin
|
|||||||
{ Next two numbers define the size of virtual spreadsheet.
|
{ Next two numbers define the size of virtual spreadsheet.
|
||||||
In case of a database, VirtualRowCount is the RecordCount, VirtualColCount
|
In case of a database, VirtualRowCount is the RecordCount, VirtualColCount
|
||||||
the number of fields to be written to the spreadsheet file }
|
the number of fields to be written to the spreadsheet file }
|
||||||
workbook.VirtualRowCount := 60000;
|
workbook.VirtualRowCount := 20000;
|
||||||
workbook.VirtualColCount := 100;
|
workbook.VirtualColCount := 100;
|
||||||
|
|
||||||
{ The event handler for OnNeedCellData links the workbook to the method
|
{ The event handler for OnNeedCellData links the workbook to the method
|
||||||
@ -96,19 +95,20 @@ begin
|
|||||||
{ In case of a database, you would open the dataset before calling this: }
|
{ In case of a database, you would open the dataset before calling this: }
|
||||||
|
|
||||||
t := Now;
|
t := Now;
|
||||||
workbook.WriteToFile('test_virtual.xlsx', sfOOXML, true);
|
//workbook.WriteToFile('test_virtual.xlsx', sfOOXML, true);
|
||||||
//workbook.WriteToFile('test_virtual.xls', sfExcel8, true);
|
workbook.WriteToFile('test_virtual.xls', sfExcel8, true);
|
||||||
t := Now - t;
|
t := Now - t;
|
||||||
|
|
||||||
finally
|
finally
|
||||||
workbook.Free;
|
workbook.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
WriteLn(Format('Execution time: %.3f sec', [t*24*60*60]));
|
|
||||||
WriteLn('Press [ENTER] to quit...');
|
|
||||||
ReadLn;
|
|
||||||
finally
|
finally
|
||||||
dataprovider.Free;
|
dataprovider.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
WriteLn(Format('Execution time: %.3f sec', [t*24*60*60]));
|
||||||
|
WriteLn('Press [ENTER] to quit...');
|
||||||
|
ReadLn;
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -1072,6 +1072,9 @@ function GetFileFormatName(AFormat: TsSpreadsheetFormat): String;
|
|||||||
procedure MakeLEPalette(APalette: PsPalette; APaletteSize: Integer);
|
procedure MakeLEPalette(APalette: PsPalette; APaletteSize: Integer);
|
||||||
function SameCellBorders(ACell1, ACell2: PCell): Boolean;
|
function SameCellBorders(ACell1, ACell2: PCell): Boolean;
|
||||||
|
|
||||||
|
procedure InitCell(var ACell: TCell);
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
@ -1460,6 +1463,47 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{@@
|
||||||
|
Initalizes a new cell
|
||||||
|
}
|
||||||
|
procedure InitCell(var ACell: TCell);
|
||||||
|
begin
|
||||||
|
ACell.RPNFormulaValue := nil;
|
||||||
|
ACell.FormulaValue.FormulaStr := '';
|
||||||
|
ACell.UTF8StringValue := '';
|
||||||
|
ACell.NumberFormatStr := '';
|
||||||
|
FillChar(ACell, SizeOf(ACell), 0);
|
||||||
|
end;
|
||||||
|
(*
|
||||||
|
Col: Cardinal; // zero-based
|
||||||
|
Row: Cardinal; // zero-based
|
||||||
|
ContentType: TCellContentType;
|
||||||
|
{ Possible values for the cells }
|
||||||
|
FormulaValue: TsFormula;
|
||||||
|
RPNFormulaValue: TsRPNFormula;
|
||||||
|
NumberValue: double;
|
||||||
|
UTF8StringValue: ansistring;
|
||||||
|
DateTimeValue: TDateTime;
|
||||||
|
BoolValue: Boolean;
|
||||||
|
ErrorValue: TsErrorValue;
|
||||||
|
{ Formatting fields }
|
||||||
|
{ When adding/deleting formatting fields don't forget to update CopyFormat! }
|
||||||
|
UsedFormattingFields: TsUsedFormattingFields;
|
||||||
|
FontIndex: Integer;
|
||||||
|
TextRotation: TsTextRotation;
|
||||||
|
HorAlignment: TsHorAlignment;
|
||||||
|
VertAlignment: TsVertAlignment;
|
||||||
|
Border: TsCellBorders;
|
||||||
|
BorderStyles: TsCelLBorderStyles;
|
||||||
|
BackgroundColor: TsColor;
|
||||||
|
NumberFormat: TsNumberFormat;
|
||||||
|
NumberFormatStr: String;
|
||||||
|
RGBBackgroundColor: TFPColor; // only valid if BackgroundColor=scRGBCOLOR
|
||||||
|
{ Status flags }
|
||||||
|
CalcState: TsCalcState;
|
||||||
|
*)
|
||||||
|
|
||||||
|
|
||||||
{ TsWorksheet }
|
{ TsWorksheet }
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
@ -5803,6 +5847,7 @@ end;
|
|||||||
function NewRPNItem: PRPNItem;
|
function NewRPNItem: PRPNItem;
|
||||||
begin
|
begin
|
||||||
Result := GetMem(SizeOf(TRPNItem));
|
Result := GetMem(SizeOf(TRPNItem));
|
||||||
|
Result^.FE.StringValue := '';
|
||||||
FillChar(Result^.FE, SizeOf(Result^.FE), 0);
|
FillChar(Result^.FE, SizeOf(Result^.FE), 0);
|
||||||
Result^.FE.StringValue := '';
|
Result^.FE.StringValue := '';
|
||||||
end;
|
end;
|
||||||
|
@ -2577,7 +2577,8 @@ var
|
|||||||
begin
|
begin
|
||||||
for r := 0 to Workbook.VirtualRowCount-1 do begin
|
for r := 0 to Workbook.VirtualRowCount-1 do begin
|
||||||
for c := 0 to Workbook.VirtualColCount-1 do begin
|
for c := 0 to Workbook.VirtualColCount-1 do begin
|
||||||
FillChar(lCell, SizeOf(lCell), 0);
|
InitCell(lCell);
|
||||||
|
// FillChar(lCell, SizeOf(lCell), 0);
|
||||||
value := varNull;
|
value := varNull;
|
||||||
styleCell := nil;
|
styleCell := nil;
|
||||||
Workbook.OnNeedCellData(Workbook, r, c, value, styleCell);
|
Workbook.OnNeedCellData(Workbook, r, c, value, styleCell);
|
||||||
@ -2607,6 +2608,7 @@ begin
|
|||||||
end else
|
end else
|
||||||
lCell.ContentType := cctEmpty;
|
lCell.ContentType := cctEmpty;
|
||||||
WriteCellCallback(@lCell, AStream);
|
WriteCellCallback(@lCell, AStream);
|
||||||
|
value := varNULL;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -249,12 +249,12 @@ begin
|
|||||||
SetLength(FFormattingStyles, 2);
|
SetLength(FFormattingStyles, 2);
|
||||||
|
|
||||||
// Default style
|
// Default style
|
||||||
FillChar(FFormattingStyles[0], SizeOf(TCell), 0);
|
InitCell(FFormattingStyles[0]);
|
||||||
FFormattingStyles[0].BorderStyles := DEFAULT_BORDERSTYLES;
|
FFormattingStyles[0].BorderStyles := DEFAULT_BORDERSTYLES;
|
||||||
FFormattingStyles[0].Row := 0;
|
FFormattingStyles[0].Row := 0;
|
||||||
|
|
||||||
// Bold style
|
// Bold style
|
||||||
FillChar(FFormattingStyles[1], SizeOf(TCell), 0);
|
InitCell(FFormattingStyles[1]);
|
||||||
FFormattingStyles[1].UsedFormattingFields := [uffBold];
|
FFormattingStyles[1].UsedFormattingFields := [uffBold];
|
||||||
FFormattingStyles[1].FontIndex := 1; // this is the "bold" font
|
FFormattingStyles[1].FontIndex := 1; // this is the "bold" font
|
||||||
FFormattingStyles[1].Row := 1;
|
FFormattingStyles[1].Row := 1;
|
||||||
@ -917,7 +917,8 @@ begin
|
|||||||
AppendToStream(FSSheets[FCurSheetNum], Format(
|
AppendToStream(FSSheets[FCurSheetNum], Format(
|
||||||
'<row r="%d" spans="1:%d"%s>', [r+1, Workbook.VirtualColCount, rh]));
|
'<row r="%d" spans="1:%d"%s>', [r+1, Workbook.VirtualColCount, rh]));
|
||||||
for c := 0 to Workbook.VirtualColCount-1 do begin
|
for c := 0 to Workbook.VirtualColCount-1 do begin
|
||||||
FillChar(lCell, SizeOf(lCell), 0);
|
//FillChar(lCell, SizeOf(lCell), 0);
|
||||||
|
InitCell(lCell);
|
||||||
CellPosText := CurSheet.CellPosToText(r, c);
|
CellPosText := CurSheet.CellPosToText(r, c);
|
||||||
value := varNull;
|
value := varNull;
|
||||||
styleCell := nil;
|
styleCell := nil;
|
||||||
@ -948,6 +949,7 @@ begin
|
|||||||
lCell.BoolValue := value <> 0;
|
lCell.BoolValue := value <> 0;
|
||||||
end;
|
end;
|
||||||
WriteCellCallback(@lCell, FSSheets[FCurSheetNum]);
|
WriteCellCallback(@lCell, FSSheets[FCurSheetNum]);
|
||||||
|
varClear(value);
|
||||||
end;
|
end;
|
||||||
AppendToStream(FSSheets[FCurSheetNum],
|
AppendToStream(FSSheets[FCurSheetNum],
|
||||||
'</row>');
|
'</row>');
|
||||||
|
Reference in New Issue
Block a user