You've already forked lazarus-ccr
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:
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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"/>
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
Reference in New Issue
Block a user