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>
|
||||
<Debugging>
|
||||
<DebugInfoType Value="dsDwarf2Set"/>
|
||||
<UseHeaptrc Value="True"/>
|
||||
</Debugging>
|
||||
</Linking>
|
||||
</CompilerOptions>
|
||||
|
@ -7,7 +7,7 @@ uses
|
||||
cthreads,
|
||||
{$ENDIF}{$ENDIF}
|
||||
Classes, laz_fpspreadsheet,
|
||||
{ you can add units after this }
|
||||
{ you can add units after this } lazutf8,
|
||||
SysUtils, variants, fpspreadsheet, xlsbiff2, xlsbiff5, xlsbiff8, xlsxooxml;
|
||||
|
||||
type
|
||||
@ -41,12 +41,11 @@ var
|
||||
// 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 odd(random(10)) then }begin
|
||||
s := Format('R=%d-C=%d', [ARow, ACol]);
|
||||
AData := s;
|
||||
end {else
|
||||
AData := 10000*ARow + ACol};
|
||||
end 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 OnNeedData also to provide feedback on how the process
|
||||
// progresses:
|
||||
@ -65,8 +64,8 @@ begin
|
||||
|
||||
{ These are the essential commands to activate virtual mode: }
|
||||
|
||||
workbook.WritingOptions := [woVirtualMode, woBufStream];
|
||||
// workbook.WritingOptions := [woVirtualMode];
|
||||
// workbook.WritingOptions := [woVirtualMode, woBufStream];
|
||||
workbook.WritingOptions := [woVirtualMode];
|
||||
{ woBufStream 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. The option can slow down the
|
||||
@ -75,7 +74,7 @@ begin
|
||||
{ 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 }
|
||||
workbook.VirtualRowCount := 60000;
|
||||
workbook.VirtualRowCount := 20000;
|
||||
workbook.VirtualColCount := 100;
|
||||
|
||||
{ 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: }
|
||||
|
||||
t := Now;
|
||||
workbook.WriteToFile('test_virtual.xlsx', sfOOXML, true);
|
||||
//workbook.WriteToFile('test_virtual.xls', sfExcel8, true);
|
||||
//workbook.WriteToFile('test_virtual.xlsx', sfOOXML, true);
|
||||
workbook.WriteToFile('test_virtual.xls', sfExcel8, true);
|
||||
t := Now - t;
|
||||
|
||||
finally
|
||||
workbook.Free;
|
||||
end;
|
||||
|
||||
WriteLn(Format('Execution time: %.3f sec', [t*24*60*60]));
|
||||
WriteLn('Press [ENTER] to quit...');
|
||||
ReadLn;
|
||||
finally
|
||||
dataprovider.Free;
|
||||
end;
|
||||
|
||||
WriteLn(Format('Execution time: %.3f sec', [t*24*60*60]));
|
||||
WriteLn('Press [ENTER] to quit...');
|
||||
ReadLn;
|
||||
end.
|
||||
|
||||
|
@ -1072,6 +1072,9 @@ function GetFileFormatName(AFormat: TsSpreadsheetFormat): String;
|
||||
procedure MakeLEPalette(APalette: PsPalette; APaletteSize: Integer);
|
||||
function SameCellBorders(ACell1, ACell2: PCell): Boolean;
|
||||
|
||||
procedure InitCell(var ACell: TCell);
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -1460,6 +1463,47 @@ begin
|
||||
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 }
|
||||
|
||||
{@@
|
||||
@ -5803,6 +5847,7 @@ end;
|
||||
function NewRPNItem: PRPNItem;
|
||||
begin
|
||||
Result := GetMem(SizeOf(TRPNItem));
|
||||
Result^.FE.StringValue := '';
|
||||
FillChar(Result^.FE, SizeOf(Result^.FE), 0);
|
||||
Result^.FE.StringValue := '';
|
||||
end;
|
||||
|
@ -2577,7 +2577,8 @@ var
|
||||
begin
|
||||
for r := 0 to Workbook.VirtualRowCount-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;
|
||||
styleCell := nil;
|
||||
Workbook.OnNeedCellData(Workbook, r, c, value, styleCell);
|
||||
@ -2607,6 +2608,7 @@ begin
|
||||
end else
|
||||
lCell.ContentType := cctEmpty;
|
||||
WriteCellCallback(@lCell, AStream);
|
||||
value := varNULL;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -249,12 +249,12 @@ begin
|
||||
SetLength(FFormattingStyles, 2);
|
||||
|
||||
// Default style
|
||||
FillChar(FFormattingStyles[0], SizeOf(TCell), 0);
|
||||
InitCell(FFormattingStyles[0]);
|
||||
FFormattingStyles[0].BorderStyles := DEFAULT_BORDERSTYLES;
|
||||
FFormattingStyles[0].Row := 0;
|
||||
|
||||
// Bold style
|
||||
FillChar(FFormattingStyles[1], SizeOf(TCell), 0);
|
||||
InitCell(FFormattingStyles[1]);
|
||||
FFormattingStyles[1].UsedFormattingFields := [uffBold];
|
||||
FFormattingStyles[1].FontIndex := 1; // this is the "bold" font
|
||||
FFormattingStyles[1].Row := 1;
|
||||
@ -917,7 +917,8 @@ begin
|
||||
AppendToStream(FSSheets[FCurSheetNum], Format(
|
||||
'<row r="%d" spans="1:%d"%s>', [r+1, Workbook.VirtualColCount, rh]));
|
||||
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);
|
||||
value := varNull;
|
||||
styleCell := nil;
|
||||
@ -948,6 +949,7 @@ begin
|
||||
lCell.BoolValue := value <> 0;
|
||||
end;
|
||||
WriteCellCallback(@lCell, FSSheets[FCurSheetNum]);
|
||||
varClear(value);
|
||||
end;
|
||||
AppendToStream(FSSheets[FCurSheetNum],
|
||||
'</row>');
|
||||
|
Reference in New Issue
Block a user