fpspreadsheet: Fix written oversized worksheets being defective, adapt BIFF writer's WriteDimensions method to be compatible with oversized worksheets.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3455 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz
2014-08-08 14:30:19 +00:00
parent 59bcbe2889
commit 8f666bec13
9 changed files with 125 additions and 48 deletions

View File

@@ -2939,6 +2939,8 @@ var
begin begin
// some abbreviations... // some abbreviations...
defFontSize := Workbook.GetFont(0).Size; defFontSize := Workbook.GetFont(0).Size;
GetSheetDimensions(ASheet, firstRow, lastRow, firstCol, lastCol);
{
firstCol := ASheet.GetFirstColIndex; firstCol := ASheet.GetFirstColIndex;
firstRow := ASheet.GetFirstRowIndex; firstRow := ASheet.GetFirstRowIndex;
lastCol := ASheet.GetLastColIndex; lastCol := ASheet.GetLastColIndex;
@@ -2946,6 +2948,7 @@ begin
// avoid arithmetic overflow in case of empty worksheet // avoid arithmetic overflow in case of empty worksheet
if (firstCol = $FFFFFFFF) and (lastCol = 0) then firstCol := 0; if (firstCol = $FFFFFFFF) and (lastCol = 0) then firstCol := 0;
if (FirstRow = $FFFFFFFF) and (lastRow = 0) then firstRow := 0; if (FirstRow = $FFFFFFFF) and (lastRow = 0) then firstRow := 0;
}
emptyRowsAbove := firstRow > 0; emptyRowsAbove := firstRow > 0;
// Now loop through all rows // Now loop through all rows
@@ -3103,8 +3106,8 @@ begin
FPointSeparatorSettings.DecimalSeparator:='.'; FPointSeparatorSettings.DecimalSeparator:='.';
// http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications // http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications
FLimitations.MaxCols := 1024; FLimitations.MaxColCount := 1024;
FLimitations.MaxRows := 1048576; FLimitations.MaxRowCount := 1048576;
end; end;
destructor TsSpreadOpenDocWriter.Destroy; destructor TsSpreadOpenDocWriter.Destroy;

View File

@@ -26,8 +26,8 @@ type
{@@ Record collection limitations of a particular file format } {@@ Record collection limitations of a particular file format }
TsSpreadsheetFormatLimitations = record TsSpreadsheetFormatLimitations = record
MaxRows: Cardinal; MaxRowCount: Cardinal;
MaxCols: Cardinal; MaxColCount: Cardinal;
end; end;
const const
@@ -6173,8 +6173,8 @@ constructor TsCustomSpreadWriter.Create(AWorkbook: TsWorkbook);
begin begin
inherited Create(AWorkbook); inherited Create(AWorkbook);
{ A good starting point valid for many formats... } { A good starting point valid for many formats... }
FLimitations.MaxCols := 256; FLimitations.MaxColCount := 256;
FLimitations.MaxRows := 65536; FLimitations.MaxRowCount := 65536;
end; end;
{@@ {@@
@@ -6265,7 +6265,8 @@ end;
{@@ {@@
Determines the size of the worksheet to be written. VirtualMode is respected. Determines the size of the worksheet to be written. VirtualMode is respected.
Is called when the writer needs the size for output. Is called when the writer needs the size for output. Column and row count
limitations are repsected as well.
@param AWorksheet Worksheet to be written @param AWorksheet Worksheet to be written
@param AFirsRow Index of first row to be written @param AFirsRow Index of first row to be written
@@ -6276,15 +6277,26 @@ end;
procedure TsCustomSpreadWriter.GetSheetDimensions(AWorksheet: TsWorksheet; procedure TsCustomSpreadWriter.GetSheetDimensions(AWorksheet: TsWorksheet;
out AFirstRow, ALastRow, AFirstCol, ALastCol: Cardinal); out AFirstRow, ALastRow, AFirstCol, ALastCol: Cardinal);
begin begin
AFirstRow := 0;
AFirstCol := 0;
if (boVirtualMode in AWorksheet.Workbook.Options) then begin if (boVirtualMode in AWorksheet.Workbook.Options) then begin
AFirstRow := 0;
AFirstCol := 0;
ALastRow := AWorksheet.Workbook.VirtualRowCount-1; ALastRow := AWorksheet.Workbook.VirtualRowCount-1;
ALastCol := AWorksheet.Workbook.VirtualColCount-1; ALastCol := AWorksheet.Workbook.VirtualColCount-1;
end else begin end else begin
Workbook.UpdateCaches;
AFirstRow := AWorksheet.GetFirstRowIndex;
AFirstCol := AWorksheet.GetFirstColIndex;
ALastRow := AWorksheet.GetLastRowIndex; ALastRow := AWorksheet.GetLastRowIndex;
ALastCol := AWorksheet.GetLastColIndex; ALastCol := AWorksheet.GetLastColIndex;
end; end;
if AFirstCol >= Limitations.MaxColCount then
AFirstCol := Limitations.MaxColCount-1;
if AFirstRow >= Limitations.MaxRowCount then
AFirstRow := Limitations.MaxRowCount-1;
if ALastCol >= Limitations.MaxColCount then
ALastCol := Limitations.MaxColCount-1;
if ALastRow >= Limitations.MaxRowCount then
ALastRow := Limitations.MaxRowCount-1;
end; end;
{@@ {@@
@@ -6307,10 +6319,10 @@ var
lastCol, lastRow: Cardinal; lastCol, lastRow: Cardinal;
begin begin
Workbook.GetLastRowColIndex(lastRow, lastCol); Workbook.GetLastRowColIndex(lastRow, lastCol);
if lastRow >= FLimitations.MaxRows then if lastRow >= FLimitations.MaxRowCount then
Workbook.AddErrorMsg(lpMaxRowsExceeded, [lastRow+1, FLimitations.MaxRows]); Workbook.AddErrorMsg(lpMaxRowsExceeded, [lastRow+1, FLimitations.MaxRowCount]);
if lastCol >= FLimitations.MaxCols then if lastCol >= FLimitations.MaxColCount then
Workbook.AddErrorMsg(lpMaxColsExceeded, [lastCol+1, FLimitations.MaxCols]); Workbook.AddErrorMsg(lpMaxColsExceeded, [lastCol+1, FLimitations.MaxColCount]);
end; end;

View File

@@ -30,7 +30,6 @@ type
procedure TestWriteErrorMessages_BIFF8; procedure TestWriteErrorMessages_BIFF8;
procedure TestWriteErrorMessages_ODS; procedure TestWriteErrorMessages_ODS;
procedure TestWriteErrorMessages_OOXML; procedure TestWriteErrorMessages_OOXML;
end; end;
implementation implementation
@@ -62,10 +61,14 @@ var
row, col: Cardinal; row, col: Cardinal;
row1, row2: Cardinal; row1, row2: Cardinal;
col1, col2: Cardinal; col1, col2: Cardinal;
formula: TsFormula;
s: String; s: String;
TempFile: String; TempFile: String;
ErrList: TStringList; ErrList: TStringList;
begin begin
formula.FormulaStr := '=A1';
formula.DoubleValue := 0.0;
ErrList := TStringList.Create; ErrList := TStringList.Create;
try try
// Test 1: Too many rows // Test 1: Too many rows
@@ -78,7 +81,8 @@ begin
MyWorksheet.WriteBlank(row, 0); MyWorksheet.WriteBlank(row, 0);
MyWorksheet.WriteNumber(row, 1, 1.0); MyWorksheet.WriteNumber(row, 1, 1.0);
MyWorksheet.WriteUTF8Text(row, 2, 'A'); MyWorksheet.WriteUTF8Text(row, 2, 'A');
MyWorksheet.WriteRPNFormula(row, 3, CreateRPNFormula( MyWorksheet.WriteFormula(Row, 3, formula);
MyWorksheet.WriteRPNFormula(row, 4, CreateRPNFormula(
RPNCellValue('A1', nil))); RPNCellValue('A1', nil)));
end; end;
TempFile:=NewTempFile; TempFile:=NewTempFile;
@@ -97,10 +101,11 @@ begin
col1 := MAX_COL_COUNT[TTestFormat(AFormat)] - 5; col1 := MAX_COL_COUNT[TTestFormat(AFormat)] - 5;
col2 := MAX_COL_COUNT[TTestFormat(AFormat)] + 5; col2 := MAX_COL_COUNT[TTestFormat(AFormat)] + 5;
for col := col1 to col2 do begin for col := col1 to col2 do begin
MyWorksheet.WriteBlank(row, 0); MyWorksheet.WriteBlank(0, col);
MyWorksheet.WriteNumber(row, 1, 1.0); MyWorksheet.WriteNumber(1, col, 1.0);
MyWorksheet.WriteUTF8Text(row, 2, 'A'); MyWorksheet.WriteUTF8Text(2, col, 'A');
MyWorksheet.WriteRPNFormula(row, 3, CreateRPNFormula( MyWorksheet.WriteFormula(3, col, formula);
MyWorksheet.WriteRPNFormula(4, col, CreateRPNFormula(
RPNCellValue('A1', nil))); RPNCellValue('A1', nil)));
end; end;
TempFile:=NewTempFile; TempFile:=NewTempFile;

View File

@@ -48,7 +48,6 @@
<Unit1> <Unit1>
<Filename Value="datetests.pas"/> <Filename Value="datetests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="datetests"/>
</Unit1> </Unit1>
<Unit2> <Unit2>
<Filename Value="stringtests.pas"/> <Filename Value="stringtests.pas"/>
@@ -63,7 +62,6 @@
<Unit4> <Unit4>
<Filename Value="manualtests.pas"/> <Filename Value="manualtests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="manualtests"/>
</Unit4> </Unit4>
<Unit5> <Unit5>
<Filename Value="testsutility.pas"/> <Filename Value="testsutility.pas"/>
@@ -78,7 +76,6 @@
<Unit7> <Unit7>
<Filename Value="formattests.pas"/> <Filename Value="formattests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="formattests"/>
</Unit7> </Unit7>
<Unit8> <Unit8>
<Filename Value="colortests.pas"/> <Filename Value="colortests.pas"/>
@@ -91,7 +88,6 @@
<Unit10> <Unit10>
<Filename Value="optiontests.pas"/> <Filename Value="optiontests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="optiontests"/>
</Unit10> </Unit10>
<Unit11> <Unit11>
<Filename Value="numformatparsertests.pas"/> <Filename Value="numformatparsertests.pas"/>
@@ -100,17 +96,14 @@
<Unit12> <Unit12>
<Filename Value="rpnformulaunit.pas"/> <Filename Value="rpnformulaunit.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="rpnFormulaUnit"/>
</Unit12> </Unit12>
<Unit13> <Unit13>
<Filename Value="formulatests.pas"/> <Filename Value="formulatests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="formulatests"/>
</Unit13> </Unit13>
<Unit14> <Unit14>
<Filename Value="emptycelltests.pas"/> <Filename Value="emptycelltests.pas"/>
<IsPartOfProject Value="True"/> <IsPartOfProject Value="True"/>
<UnitName Value="emptycelltests"/>
</Unit14> </Unit14>
<Unit15> <Unit15>
<Filename Value="errortests.pas"/> <Filename Value="errortests.pas"/>

View File

@@ -1502,7 +1502,7 @@ var
s: ansistring; s: ansistring;
xf: Word; xf: Word;
begin begin
if (ARow >= FLimitations.MaxRows) or (ACol >= FLimitations.MaxCols) then if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit; exit;
RPNLength := 0; RPNLength := 0;
@@ -1608,7 +1608,7 @@ var
xf: Word; xf: Word;
rec: TBlankRecord; rec: TBlankRecord;
begin begin
if (ARow >= FLimitations.MaxRows) or (ACol >= FLimitations.MaxCols) then if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit; exit;
xf := FindXFIndex(ACell); xf := FindXFIndex(ACell);
@@ -1667,7 +1667,7 @@ var
var var
xf: Word; xf: Word;
begin begin
if (ARow >= FLimitations.MaxRows) or (ACol >= FLimitations.MaxCols) then if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit; exit;
if AValue = '' then Exit; // Writing an empty text doesn't work if AValue = '' then Exit; // Writing an empty text doesn't work
@@ -1730,7 +1730,7 @@ var
xf: Word; xf: Word;
rec: TBIFF2NumberRecord; rec: TBIFF2NumberRecord;
begin begin
if (ARow >= FLimitations.MaxRows) or (ACol >= FLimitations.MaxCols) then if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit; exit;
xf := FindXFIndex(ACell); xf := FindXFIndex(ACell);
@@ -1763,8 +1763,8 @@ var
w: Word; w: Word;
h: Single; h: Single;
begin begin
if (ARowIndex >= FLimitations.MaxRows) or (AFirstColIndex >= FLimitations.MaxCols) if (ARowIndex >= FLimitations.MaxRowCount) or (AFirstColIndex >= FLimitations.MaxColCount)
or (ALastColIndex >= FLimitations.MaxCols) or (ALastColIndex >= FLimitations.MaxColCount)
then then
exit; exit;

View File

@@ -307,6 +307,16 @@ const
); );
type type
TBIFF5DimensionsRecord = packed record
RecordID: Word;
RecordSize: Word;
FirstRow: Word;
LastRowPlus1: Word;
FirstCol: Word;
LastColPlus1: Word;
NotUsed: Word;
end;
TBIFF5LabelRecord = packed record TBIFF5LabelRecord = packed record
RecordID: Word; RecordID: Word;
RecordSize: Word; RecordSize: Word;
@@ -431,7 +441,7 @@ begin
WriteWindow2(AStream, sheet); WriteWindow2(AStream, sheet);
WritePane(AStream, sheet, true, pane); // true for "is BIFF5 or BIFF8" WritePane(AStream, sheet, true, pane); // true for "is BIFF5 or BIFF8"
WriteSelection(AStream, sheet, pane); WriteSelection(AStream, sheet, pane);
WriteRows(AStream, sheet); //WriteRows(AStream, sheet);
if (boVirtualMode in Workbook.Options) then if (boVirtualMode in Workbook.Options) then
WriteVirtualCells(AStream) WriteVirtualCells(AStream)
@@ -551,8 +561,27 @@ end;
} }
procedure TsSpreadBIFF5Writer.WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet); procedure TsSpreadBIFF5Writer.WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet);
var var
lLastCol, lLastRow: Word; rec: TBIFF5DimensionsRecord;
firstCol, lastCol, firstRow, lastRow: Cardinal;
lLastRow, lLastCol: Word;
begin begin
{ Determine sheet size }
GetSheetDimensions(AWorksheet, firstRow, lastRow, firstCol, lastCol);
{ Setup BIFF record }
rec.RecordID := WordToLE(INT_EXCEL_ID_DIMENSIONS);
rec.RecordSize := WordToLE(10);
rec.FirstRow := WordToLE(firstRow);
rec.LastRowPlus1 := WordToLE(lastRow+1);
rec.FirstCol := WordToLe(firstCol);
rec.LastColPlus1 := WordToLE(lastCol+1);
rec.NotUsed := 0;
{ Write BIFF record }
AStream.WriteBuffer(rec, SizeOf(rec));
(*
{ BIFF Record header } { BIFF Record header }
AStream.WriteWord(WordToLE(INT_EXCEL_ID_DIMENSIONS)); AStream.WriteWord(WordToLE(INT_EXCEL_ID_DIMENSIONS));
AStream.WriteWord(WordToLE(10)); AStream.WriteWord(WordToLE(10));
@@ -573,6 +602,7 @@ begin
{ Not used } { Not used }
AStream.WriteWord(0); AStream.WriteWord(0);
*)
end; end;
{******************************************************************* {*******************************************************************
@@ -951,7 +981,7 @@ var
rec: TBIFF5LabelRecord; rec: TBIFF5LabelRecord;
buf: array of byte; buf: array of byte;
begin begin
if (ARow >= FLimitations.MaxRows) or (ACol >= FLimitations.MaxCols) then if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit; exit;
case WorkBookEncoding of case WorkBookEncoding of

View File

@@ -34,9 +34,11 @@ EOF
The row and column numbering in BIFF files is zero-based. The row and column numbering in BIFF files is zero-based.
Excel file format specification obtained from: Excel file format specification obtained from:
http://sc.openoffice.org/excelfileformat.pdf http://sc.openoffice.org/excelfileformat.pdf
see also:
http://office.microsoft.com/en-us/excel-help/excel-specifications-and-limits-HP005199291.aspx
AUTHORS: Felipe Monteiro de Carvalho AUTHORS: Felipe Monteiro de Carvalho
Jose Mejuto Jose Mejuto
} }
@@ -280,6 +282,16 @@ const
); );
type type
TBIFF8DimensionsRecord = packed record
RecordID: Word;
RecordSize: Word;
FirstRow: DWord;
LastRowPlus1: DWord;
FirstCol: Word;
LastColPlus1: Word;
NotUsed: Word;
end;
TBIFF8LabelRecord = packed record TBIFF8LabelRecord = packed record
RecordID: Word; RecordID: Word;
RecordSize: Word; RecordSize: Word;
@@ -578,7 +590,24 @@ end;
procedure TsSpreadBIFF8Writer.WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet); procedure TsSpreadBIFF8Writer.WriteDimensions(AStream: TStream; AWorksheet: TsWorksheet);
var var
firstRow, lastRow, firstCol, lastCol: Cardinal; firstRow, lastRow, firstCol, lastCol: Cardinal;
rec: TBIFF8DimensionsRecord;
begin begin
{ Determine sheet size }
GetSheetDimensions(AWorksheet, firstRow, lastRow, firstCol, lastCol);
{ Populate BIFF record }
rec.RecordID := WordToLE(INT_EXCEL_ID_DIMENSIONS);
rec.RecordSize := WordToLE(14);
rec.FirstRow := DWordToLE(firstRow);
rec.LastRowPlus1 := DWordToLE(lastRow+1);
rec.FirstCol := WordToLE(firstCol);
rec.LastColPlus1 := WordToLE(lastCol+1);
rec.NotUsed := 0;
{ Write BIFF record to stream }
AStream.WriteBuffer(rec, SizeOf(rec));
(*
{ BIFF Record header } { BIFF Record header }
AStream.WriteWord(WordToLE(INT_EXCEL_ID_DIMENSIONS)); AStream.WriteWord(WordToLE(INT_EXCEL_ID_DIMENSIONS));
AStream.WriteWord(WordToLE(14)); AStream.WriteWord(WordToLE(14));
@@ -600,6 +629,7 @@ begin
{ Not used } { Not used }
AStream.WriteWord(WordToLE(0)); AStream.WriteWord(WordToLE(0));
*)
end; end;
{******************************************************************* {*******************************************************************
@@ -996,7 +1026,7 @@ var
rec: TBIFF8LabelRecord; rec: TBIFF8LabelRecord;
buf: array of byte; buf: array of byte;
begin begin
if (ARow >= FLimitations.MaxRows) or (ACol >= FLimitations.MaxCols) then if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit; exit;
WideValue := UTF8Decode(AValue); //to UTF16 WideValue := UTF8Decode(AValue); //to UTF16

View File

@@ -1852,7 +1852,7 @@ procedure TsSpreadBIFFWriter.WriteBlank(AStream: TStream;
var var
rec: TBIFF58BlankRecord; rec: TBIFF58BlankRecord;
begin begin
if (ARow >= FLimitations.MaxRows) or (ACol >= FLimitations.MaxCols) then if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit; exit;
{ BIFF record header } { BIFF record header }
@@ -1925,7 +1925,7 @@ var
w: Integer; w: Integer;
begin begin
if Assigned(ACol) then begin if Assigned(ACol) then begin
if (ACol^.Col >= FLimitations.MaxCols) then if (ACol^.Col >= FLimitations.MaxColCount) then
exit; exit;
{ BIFF record header } { BIFF record header }
@@ -2041,7 +2041,7 @@ procedure TsSpreadBIFFWriter.WriteNumber(AStream: TStream;
var var
rec: TBIFF58NumberRecord; rec: TBIFF58NumberRecord;
begin begin
if (ARow >= FLimitations.MaxRows) or (ACol >= FLimitations.MaxCols) then if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit; exit;
{ BIFF Record header } { BIFF Record header }
@@ -2269,7 +2269,7 @@ var
RPNLength: Word; RPNLength: Word;
RecordSizePos, FinalPos: Int64; RecordSizePos, FinalPos: Int64;
begin begin
if (ARow >= FLimitations.MaxRows) or (ACol >= FLimitations.MaxCols) then if (ARow >= FLimitations.MaxRowCount) or (ACol >= FLimitations.MaxColCount) then
exit; exit;
{ BIFF Record header } { BIFF Record header }
@@ -2494,9 +2494,9 @@ var
rowheight: Word; rowheight: Word;
h: Single; h: Single;
begin begin
if (ARowIndex >= FLimitations.MaxRows) or if (ARowIndex >= FLimitations.MaxRowCount) or
(AFirstColIndex >= FLimitations.MaxCols) or (AFirstColIndex >= FLimitations.MaxColCount) or
(ALastColIndex >= FLimitations.MaxCols) (ALastColIndex >= FLimitations.MaxColCount)
then then
exit; exit;

View File

@@ -1857,9 +1857,11 @@ begin
AppendToStream(AStream, AppendToStream(AStream,
'<sheetData>'); '<sheetData>');
GetSheetDimensions(AWorksheet, r1, r2, c1, c2);
if (boVirtualMode in Workbook.Options) and Assigned(Workbook.OnWriteCellData) if (boVirtualMode in Workbook.Options) and Assigned(Workbook.OnWriteCellData)
then begin then begin
for r := 0 to Workbook.VirtualRowCount-1 do begin for r := 0 to r2 do begin
row := AWorksheet.FindRow(r); row := AWorksheet.FindRow(r);
if row <> nil then if row <> nil then
rh := Format(' ht="%g" customHeight="1"', [ rh := Format(' ht="%g" customHeight="1"', [
@@ -1868,7 +1870,7 @@ begin
rh := ''; rh := '';
AppendToStream(AStream, Format( AppendToStream(AStream, 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 c2 do begin
InitCell(lCell); InitCell(lCell);
value := varNull; value := varNull;
styleCell := nil; styleCell := nil;
@@ -1905,6 +1907,7 @@ begin
end else end else
begin begin
// The cells need to be written in order, row by row, cell by cell // The cells need to be written in order, row by row, cell by cell
(*
c1 := AWorksheet.GetFirstColIndex; c1 := AWorksheet.GetFirstColIndex;
c2 := AWorksheet.GetLastColIndex; c2 := AWorksheet.GetLastColIndex;
if (c1 = $FFFFFFFF) and (c2 = 0) then c1 := 0; // avoid arithmetic overflow in case of empty worksheet if (c1 = $FFFFFFFF) and (c2 = 0) then c1 := 0; // avoid arithmetic overflow in case of empty worksheet
@@ -1912,6 +1915,7 @@ begin
r2 := AWorksheet.GetlastRowIndex; r2 := AWorksheet.GetlastRowIndex;
if (r1 = $FFFFFFFF) and (r2 = 0) then r1 := 0; // avoid arithmetic overflow in case of empty worksheet if (r1 = $FFFFFFFF) and (r2 = 0) then r1 := 0; // avoid arithmetic overflow in case of empty worksheet
// for r := 0 to AWorksheet.GetLastRowIndex do begin // for r := 0 to AWorksheet.GetLastRowIndex do begin
*)
for r := r1 to r2 do begin for r := r1 to r2 do begin
// If the row has a custom height add this value to the <row> specification // If the row has a custom height add this value to the <row> specification
row := AWorksheet.FindRow(r); row := AWorksheet.FindRow(r);
@@ -2298,8 +2302,8 @@ begin
FPointSeparatorSettings.DecimalSeparator := '.'; FPointSeparatorSettings.DecimalSeparator := '.';
// http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications // http://en.wikipedia.org/wiki/List_of_spreadsheet_software#Specifications
FLimitations.MaxCols := 16384; FLimitations.MaxColCount := 16384;
FLimitations.MaxRows := 1048576; FLimitations.MaxRowCount := 1048576;
end; end;
procedure TsSpreadOOXMLWriter.CreateNumFormatList; procedure TsSpreadOOXMLWriter.CreateNumFormatList;