diff --git a/components/fpspreadsheet/examples/excel2demo/excel2read.lpi b/components/fpspreadsheet/examples/excel2demo/excel2read.lpi
index 723d3bedd..41331d5e1 100644
--- a/components/fpspreadsheet/examples/excel2demo/excel2read.lpi
+++ b/components/fpspreadsheet/examples/excel2demo/excel2read.lpi
@@ -38,8 +38,8 @@
-
-
+
+
diff --git a/components/fpspreadsheet/examples/excel2demo/excel2write.lpi b/components/fpspreadsheet/examples/excel2demo/excel2write.lpi
index e32632841..51672116a 100644
--- a/components/fpspreadsheet/examples/excel2demo/excel2write.lpi
+++ b/components/fpspreadsheet/examples/excel2demo/excel2write.lpi
@@ -38,7 +38,7 @@
-
+
@@ -116,8 +116,8 @@
-
-
+
+
diff --git a/components/fpspreadsheet/examples/excel2demo/excel2write.lpr b/components/fpspreadsheet/examples/excel2demo/excel2write.lpr
index 931e786b3..6b377501d 100644
--- a/components/fpspreadsheet/examples/excel2demo/excel2write.lpr
+++ b/components/fpspreadsheet/examples/excel2demo/excel2write.lpr
@@ -25,16 +25,16 @@ begin
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet');
// Write some number cells
- MyWorksheet.WriteNumber(0, 0, 1.0);
- MyWorksheet.WriteNumber(0, 1, 2.0);
- MyWorksheet.WriteNumber(0, 2, 3.0);
- MyWorksheet.WriteNumber(0, 3, 4.0);
+ MyWorksheet.WriteNumber(1, 1, 1.0);
+ MyWorksheet.WriteNumber(1, 2, 2.0);
+ MyWorksheet.WriteNumber(1, 3, 3.0);
+ MyWorksheet.WriteNumber(1, 4, 4.0);
// Write some string cells
- MyWorksheet.WriteUTF8Text(1, 0, 'First');
- MyWorksheet.WriteUTF8Text(1, 1, 'Second');
- MyWorksheet.WriteUTF8Text(1, 2, 'Third');
- MyWorksheet.WriteUTF8Text(1, 3, 'Fourth');
+ MyWorksheet.WriteUTF8Text(2, 1, 'First');
+ MyWorksheet.WriteUTF8Text(2, 2, 'Second');
+ MyWorksheet.WriteUTF8Text(2, 3, 'Third');
+ MyWorksheet.WriteUTF8Text(2, 4, 'Fourth');
// Save the spreadsheet to a file
MyWorkbook.WriteToFile(MyDir + 'test' + STR_EXCEL_EXTENSION, sfExcel2);
diff --git a/components/fpspreadsheet/examples/excel5demo/excel5write.lpr b/components/fpspreadsheet/examples/excel5demo/excel5write.lpr
index accb4d33f..1b676b6ea 100644
--- a/components/fpspreadsheet/examples/excel5demo/excel5write.lpr
+++ b/components/fpspreadsheet/examples/excel5demo/excel5write.lpr
@@ -28,10 +28,10 @@ begin
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet');
// Write some number cells
- MyWorksheet.WriteNumber(0, 0, 1.0);
- MyWorksheet.WriteNumber(0, 1, 2.0);
- MyWorksheet.WriteNumber(0, 2, 3.0);
- MyWorksheet.WriteNumber(0, 3, 4.0);
+ MyWorksheet.WriteNumber(1, 1, 1.0);
+ MyWorksheet.WriteNumber(1, 2, 2.0);
+ MyWorksheet.WriteNumber(1, 3, 3.0);
+ MyWorksheet.WriteNumber(1, 4, 4.0);
{ Uncommend this to test large XLS files
for i := 2 to 20 do
@@ -47,22 +47,22 @@ begin
// or, in RPN: A1, B1, +
SetLength(MyFormula, 3);
MyFormula[0].TokenID := INT_EXCEL_TOKEN_TREFV; {A1}
- MyFormula[0].Col := 0;
- MyFormula[0].Row := 0;
+ MyFormula[0].Col := 1;
+ MyFormula[0].Row := 1;
MyFormula[1].TokenID := INT_EXCEL_TOKEN_TREFV; {B1}
- MyFormula[1].Col := 1;
- MyFormula[1].Row := 0;
+ MyFormula[1].Col := 2;
+ MyFormula[1].Row := 1;
MyFormula[2].TokenID := INT_EXCEL_TOKEN_TADD; {+}
- MyWorksheet.WriteRPNFormula(0, 4, MyFormula);
+ MyWorksheet.WriteRPNFormula(1, 5, MyFormula);
// Creates a new worksheet
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet 2');
// Write some string cells
- MyWorksheet.WriteUTF8Text(0, 0, 'First');
- MyWorksheet.WriteUTF8Text(0, 1, 'Second');
- MyWorksheet.WriteUTF8Text(0, 2, 'Third');
- MyWorksheet.WriteUTF8Text(0, 3, 'Fourth');
+ MyWorksheet.WriteUTF8Text(1, 1, 'First');
+ MyWorksheet.WriteUTF8Text(1, 2, 'Second');
+ MyWorksheet.WriteUTF8Text(1, 3, 'Third');
+ MyWorksheet.WriteUTF8Text(1, 4, 'Fourth');
// Save the spreadsheet to a file
MyWorkbook.WriteToFile(MyDir + 'test' + STR_EXCEL_EXTENSION, sfExcel5);
diff --git a/components/fpspreadsheet/examples/opendocdemo/opendocwrite.lpi b/components/fpspreadsheet/examples/opendocdemo/opendocwrite.lpi
index 1b9850e45..9ce023901 100644
--- a/components/fpspreadsheet/examples/opendocdemo/opendocwrite.lpi
+++ b/components/fpspreadsheet/examples/opendocdemo/opendocwrite.lpi
@@ -11,7 +11,7 @@
-
+
@@ -38,8 +38,8 @@
-
-
+
+
@@ -86,8 +86,8 @@
-
-
+
+
@@ -116,10 +116,10 @@
-
-
+
+
-
+
@@ -131,10 +131,10 @@
-
-
+
+
-
+
@@ -143,130 +143,130 @@
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
-
-
+
+
-
-
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
+
-
-
-
-
+
+
+
+
diff --git a/components/fpspreadsheet/examples/opendocdemo/opendocwrite.lpr b/components/fpspreadsheet/examples/opendocdemo/opendocwrite.lpr
index e058b712d..75ab0d688 100644
--- a/components/fpspreadsheet/examples/opendocdemo/opendocwrite.lpr
+++ b/components/fpspreadsheet/examples/opendocdemo/opendocwrite.lpr
@@ -28,10 +28,10 @@ begin
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet');
// Write some number cells
- MyWorksheet.WriteNumber(0, 0, 1.0);
- MyWorksheet.WriteNumber(0, 1, 2.0);
- MyWorksheet.WriteNumber(0, 2, 3.0);
- MyWorksheet.WriteNumber(0, 3, 4.0);
+ MyWorksheet.WriteNumber(1, 1, 1.0);
+ MyWorksheet.WriteNumber(1, 2, 2.0);
+ MyWorksheet.WriteNumber(1, 3, 3.0);
+ MyWorksheet.WriteNumber(1, 4, 4.0);
{ Uncommend this to test large XLS files
for i := 2 to 20 do
@@ -59,10 +59,10 @@ begin
MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet 2');
// Write some string cells
- MyWorksheet.WriteUTF8Text(0, 0, 'First');
- MyWorksheet.WriteUTF8Text(0, 1, 'Second');
- MyWorksheet.WriteUTF8Text(0, 2, 'Third');
- MyWorksheet.WriteUTF8Text(0, 3, 'Fourth');
+ MyWorksheet.WriteUTF8Text(1, 1, 'First');
+ MyWorksheet.WriteUTF8Text(1, 2, 'Second');
+ MyWorksheet.WriteUTF8Text(1, 3, 'Third');
+ MyWorksheet.WriteUTF8Text(1, 4, 'Fourth');
*)
// Save the spreadsheet to a file
diff --git a/components/fpspreadsheet/fpsopendocument.pas b/components/fpspreadsheet/fpsopendocument.pas
index 3d7c09c34..e312dcc38 100755
--- a/components/fpspreadsheet/fpsopendocument.pas
+++ b/components/fpspreadsheet/fpsopendocument.pas
@@ -5,22 +5,19 @@ Writes an OpenDocument 1.0 Spreadsheet document
An OpenDocument document is a compressed ZIP file with the following files inside:
-filename\
- content.xml - Actual contents
- meta.xml - Authoring data
- settings.xml - User persistent viewing information, such as zoom, cursor position, etc.
- styles.xml - Styles, which are the only way to do formatting
- mimetype - application/vnd.oasis.opendocument.spreadsheet
- META-INF
- manifest.xml -
+content.xml - Actual contents
+meta.xml - Authoring data
+settings.xml - User persistent viewing information, such as zoom, cursor position, etc.
+styles.xml - Styles, which are the only way to do formatting
+mimetype - application/vnd.oasis.opendocument.spreadsheet
+META-INF
+ manifest.xml -
Specifications obtained from:
http://docs.oasis-open.org/office/v1.1/OS/OpenDocument-v1.1.pdf
AUTHORS: Felipe Monteiro de Carvalho
-
-IMPORTANT: This writer doesn't work yet!!! This is just initial code.
}
unit fpsopendocument;
@@ -51,6 +48,7 @@ type
// Routines to write those files
procedure WriteGlobalFiles;
procedure WriteContent(AData: TsWorkbook);
+ procedure WriteWorksheet(CurSheet: TsWorksheet);
public
{ General writing methods }
procedure WriteStringToFile(AFileName, AString: string);
@@ -200,9 +198,7 @@ end;
procedure TsSpreadOpenDocWriter.WriteContent(AData: TsWorkbook);
var
- i, j, k: Integer;
- CurSheet: TsWorksheet;
- CurCell: PCell;
+ i: Integer;
begin
FContent :=
XML_HEADER + LineEnding +
@@ -234,66 +230,26 @@ begin
' ' + LineEnding +
// Automatic styles
-'' + LineEnding +
-'' + LineEnding +
-'' + LineEnding +
-'' + LineEnding +
-'' + LineEnding +
-'' + LineEnding +
-'' + LineEnding +
-'' + LineEnding +
-'' + LineEnding +
-'' + LineEnding +
-'' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
+ ' ' + LineEnding +
-{ ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +
- ' ' + LineEnding +}
+ // Body
+ ' ' + LineEnding +
+ ' ' + LineEnding;
- // Body
- ' ' + LineEnding +
- ' ' + LineEnding;
-
- for i := 0 to AData.GetWorksheetCount - 1 do
- begin
- CurSheet := Adata.GetWorksheetByIndex(i);
-
- // Header
- FContent := FContent + '' + LineEnding
- + '' + LineEnding;
-
- // The cells need to be written in order, row by row
- for j := 0 to CurSheet.GetLastRowNumber do
- begin
- FContent := FContent + '' + LineEnding;
-
- for k := 0 to CurSheet.FCells.Count - 1 do
- begin
- CurCell := CurSheet.FCells.Items[k];
- if CurCell^.Row = j then WriteCellCallback(CurCell, nil);
- end;
-
- FContent := FContent + '' + LineEnding;
- end;
-
- // Footer
- FContent := FContent + '' + LineEnding;
- end;
+ for i := 0 to AData.GetWorksheetCount - 1 do
+ begin
+ WriteWorksheet(Adata.GetWorksheetByIndex(i));
+ end;
FContent := FContent +
' ' + LineEnding +
@@ -301,6 +257,36 @@ begin
'';
end;
+procedure TsSpreadOpenDocWriter.WriteWorksheet(CurSheet: TsWorksheet);
+var
+ j, k: Integer;
+ CurCell: PCell;
+begin
+ // Header
+ FContent := FContent +
+ ' ' + LineEnding +
+ ' ' + LineEnding;
+
+ // The cells need to be written in order, row by row
+ for j := 0 to CurSheet.GetLastRowNumber do
+ begin
+ FContent := FContent +
+ ' ' + LineEnding;
+
+ for k := 0 to CurSheet.FCells.Count - 1 do
+ begin
+ CurCell := CurSheet.FCells.Items[k];
+ if CurCell^.Row = j then WriteCellCallback(CurCell, nil);
+ end;
+
+ FContent := FContent + ' ' + LineEnding;
+ end;
+
+ // Footer
+ FContent := FContent + ' ' + LineEnding;
+end;
+
{*******************************************************************
* TsSpreadOOXMLWriter.WriteStringToFile ()
*
diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas
index 321bd5015..79bc24832 100755
--- a/components/fpspreadsheet/fpspreadsheet.pas
+++ b/components/fpspreadsheet/fpspreadsheet.pas
@@ -61,12 +61,13 @@ type
{@@ Describes the type of content of a cell on a TsWorksheet }
- TCellContentType = (cctFormula, cctNumber, cctUTF8String);
+ TCellContentType = (cctEmpty, cctFormula, cctNumber, cctUTF8String);
{@@ Cell structure for TsWorksheet }
TCell = record
- Row, Col: Cardinal;
+ Col: Byte;
+ Row: Word;
ContentType: TCellContentType;
FormulaValue: TRPNFormula;
NumberValue: double;
@@ -303,6 +304,9 @@ end;
}
function TsWorksheet.GetCell(ARow, ACol: Cardinal): PCell;
begin
+ // First make sure the row and col values are valid
+ if (ARow = 0) or (ACol = 0) then raise Exception.Create('FPSpreadsheet: Row and Col numbers cannot be zero');
+
Result := FindCell(ARow, ACol);
if (Result = nil) then
diff --git a/components/fpspreadsheet/xlsbiff2.pas b/components/fpspreadsheet/xlsbiff2.pas
index 28c4eb4b6..cbb1ab89b 100755
--- a/components/fpspreadsheet/xlsbiff2.pas
+++ b/components/fpspreadsheet/xlsbiff2.pas
@@ -13,6 +13,9 @@ To ensure a properly formed file, the following order must be respected:
2nd to Nth record: Any record
Last record: EOF
+The row and column numbering in BIFF files is zero-based,
+while in FPSpreadsheet it is 1-based, so this needs to be considered.
+
Excel file format specification obtained from:
http://sc.openoffice.org/excelfileformat.pdf
@@ -82,6 +85,10 @@ const
INT_EXCEL_CHART = $0020;
INT_EXCEL_MACRO_SHEET = $0040;
+ { Marks differences between the BIFF format and FPSpreadsheet }
+ INT_FPS_BIFF_ROW_DELTA = 1;
+ INT_FPS_BIFF_COL_DELTA = 1;
+
{ TsSpreadBIFF2Writer }
{*******************************************************************
@@ -165,8 +172,8 @@ begin
AStream.WriteWord(WordToLE(17 + RPNLength));
{ BIFF Record data }
- AStream.WriteWord(WordToLE(ARow));
- AStream.WriteWord(WordToLE(ACol));
+ AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
+ AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ BIFF2 Attributes }
AStream.WriteByte($0);
@@ -211,8 +218,8 @@ begin
INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA:
begin
- AStream.WriteWord(AFormula[i].Row and MASK_EXCEL_ROW);
- AStream.WriteByte(AFormula[i].Col);
+ AStream.WriteWord( (AFormula[i].Row - INT_FPS_BIFF_ROW_DELTA) and MASK_EXCEL_ROW);
+ AStream.WriteByte(AFormula[i].Col - INT_FPS_BIFF_COL_DELTA);
Inc(RPNLength, 3);
end;
@@ -250,8 +257,8 @@ begin
AStream.WriteWord(WordToLE(8 + L));
{ BIFF Record data }
- AStream.WriteWord(WordToLE(ARow));
- AStream.WriteWord(WordToLE(ACol));
+ AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
+ AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ BIFF2 Attributes }
AStream.WriteByte($0);
@@ -279,8 +286,8 @@ begin
AStream.WriteWord(WordToLE(15));
{ BIFF Record data }
- AStream.WriteWord(WordToLE(ARow));
- AStream.WriteWord(WordToLE(ACol));
+ AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
+ AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ BIFF2 Attributes }
AStream.WriteByte($0);
@@ -344,8 +351,8 @@ var
AStrValue: ansistring;
begin
{ BIFF Record data }
- ARow := WordLEToN(AStream.ReadWord);
- ACol := WordLEToN(AStream.ReadWord);
+ ARow := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_ROW_DELTA;
+ ACol := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_COL_DELTA;
{ BIFF2 Attributes }
AStream.ReadByte();
@@ -368,8 +375,8 @@ var
AValue: Double;
begin
{ BIFF Record data }
- ARow := WordLEToN(AStream.ReadWord);
- ACol := WordLEToN(AStream.ReadWord);
+ ARow := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_ROW_DELTA;
+ ACol := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_COL_DELTA;
{ BIFF2 Attributes }
AStream.ReadByte();
diff --git a/components/fpspreadsheet/xlsbiff5.pas b/components/fpspreadsheet/xlsbiff5.pas
index 8e7c330bd..564aadb20 100755
--- a/components/fpspreadsheet/xlsbiff5.pas
+++ b/components/fpspreadsheet/xlsbiff5.pas
@@ -31,6 +31,9 @@ DIMENSIONS
WINDOW2
EOF
+The row and column numbering in BIFF files is zero-based,
+while in FPSpreadsheet it is 1-based, so this needs to be considered.
+
Excel file format specification obtained from:
http://sc.openoffice.org/excelfileformat.pdf
@@ -203,6 +206,10 @@ const
MASK_XF_VERT_ALIGN = $70;
+ { Marks differences between the BIFF format and FPSpreadsheet }
+ INT_FPS_BIFF_ROW_DELTA = 1;
+ INT_FPS_BIFF_COL_DELTA = 1;
+
{
Exported functions
}
@@ -550,8 +557,8 @@ begin
AStream.WriteWord(WordToLE(22 + RPNLength));
{ BIFF Record data }
- AStream.WriteWord(WordToLE(ARow));
- AStream.WriteWord(WordToLE(ACol));
+ AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
+ AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ Index to XF Record }
AStream.WriteWord($0000);
@@ -596,8 +603,8 @@ begin
INT_EXCEL_TOKEN_TREFR, INT_EXCEL_TOKEN_TREFV, INT_EXCEL_TOKEN_TREFA:
begin
- AStream.WriteWord(AFormula[i].Row and MASK_EXCEL_ROW);
- AStream.WriteByte(AFormula[i].Col);
+ AStream.WriteWord( (AFormula[i].Row - INT_FPS_BIFF_ROW_DELTA) and MASK_EXCEL_ROW);
+ AStream.WriteByte(AFormula[i].Col - INT_FPS_BIFF_COL_DELTA);
Inc(RPNLength, 3);
end;
@@ -667,8 +674,8 @@ begin
AStream.WriteWord(WordToLE(8 + L));
{ BIFF Record data }
- AStream.WriteWord(WordToLE(ARow));
- AStream.WriteWord(WordToLE(ACol));
+ AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
+ AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ Index to XF record }
AStream.WriteWord(15);
@@ -694,8 +701,8 @@ begin
AStream.WriteWord(WordToLE(14));
{ BIFF Record data }
- AStream.WriteWord(WordToLE(ARow));
- AStream.WriteWord(WordToLE(ACol));
+ AStream.WriteWord(WordToLE(ARow - INT_FPS_BIFF_ROW_DELTA));
+ AStream.WriteWord(WordToLE(ACol - INT_FPS_BIFF_COL_DELTA));
{ Index to XF record }
AStream.WriteWord($0);
@@ -1053,8 +1060,8 @@ var
AValue: Double;
begin
{ BIFF Record data }
- ARow := WordLEToN(AStream.ReadWord);
- ACol := WordLEToN(AStream.ReadWord);
+ ARow := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_ROW_DELTA;
+ ACol := WordLEToN(AStream.ReadWord) + INT_FPS_BIFF_COL_DELTA;
{ Index to XF record }
AStream.ReadWord();