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 @@ <UseAppBundle Value="False"/> - <ActiveEditorIndexAtStart Value="1"/> + <ActiveEditorIndexAtStart Value="3"/> </General> <VersionInfo> <ProjectVersion Value=""/> @@ -38,8 +38,8 @@ <Filename Value="opendocwrite.lpr"/> <IsPartOfProject Value="True"/> <UnitName Value="opendocwrite"/> - <CursorPos X="30" Y="37"/> - <TopLine Value="33"/> + <CursorPos X="33" Y="61"/> + <TopLine Value="47"/> <EditorIndex Value="0"/> <UsageCount Value="309"/> <Loaded Value="True"/> @@ -86,8 +86,8 @@ <Unit6> <Filename Value="..\..\xlsbiff2.pas"/> <UnitName Value="xlsbiff2"/> - <CursorPos X="1" Y="360"/> - <TopLine Value="339"/> + <CursorPos X="1" Y="16"/> + <TopLine Value="1"/> <EditorIndex Value="6"/> <UsageCount Value="139"/> <Loaded Value="True"/> @@ -116,10 +116,10 @@ <Unit10> <Filename Value="..\..\fpspreadsheet.pas"/> <UnitName Value="fpspreadsheet"/> - <CursorPos X="1" Y="752"/> - <TopLine Value="737"/> + <CursorPos X="46" Y="308"/> + <TopLine Value="296"/> <EditorIndex Value="3"/> - <UsageCount Value="94"/> + <UsageCount Value="95"/> <Loaded Value="True"/> </Unit10> <Unit11> @@ -131,10 +131,10 @@ <Unit12> <Filename Value="..\..\fpsopendocument.pas"/> <UnitName Value="fpsopendocument"/> - <CursorPos X="87" Y="394"/> - <TopLine Value="386"/> + <CursorPos X="9" Y="266"/> + <TopLine Value="263"/> <EditorIndex Value="1"/> - <UsageCount Value="12"/> + <UsageCount Value="13"/> <Loaded Value="True"/> </Unit12> <Unit13> @@ -143,130 +143,130 @@ <CursorPos X="1" Y="268"/> <TopLine Value="253"/> <EditorIndex Value="2"/> - <UsageCount Value="12"/> + <UsageCount Value="13"/> <Loaded Value="True"/> </Unit13> </Units> <JumpHistory Count="30" HistoryIndex="29"> <Position1> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="386" Column="1" TopLine="372"/> + <Caret Line="390" Column="26" TopLine="377"/> </Position1> <Position2> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="390" Column="26" TopLine="377"/> + <Caret Line="420" Column="32" TopLine="407"/> </Position2> <Position3> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="420" Column="32" TopLine="407"/> + <Caret Line="421" Column="14" TopLine="408"/> </Position3> <Position4> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="421" Column="14" TopLine="408"/> + <Caret Line="460" Column="33" TopLine="440"/> </Position4> <Position5> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="460" Column="33" TopLine="440"/> + <Caret Line="181" Column="91" TopLine="160"/> </Position5> <Position6> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="181" Column="91" TopLine="160"/> + <Caret Line="769" Column="83" TopLine="754"/> </Position6> <Position7> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="769" Column="83" TopLine="754"/> + <Caret Line="102" Column="15" TopLine="89"/> </Position7> <Position8> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="102" Column="15" TopLine="89"/> + <Caret Line="103" Column="15" TopLine="90"/> </Position8> <Position9> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="103" Column="15" TopLine="90"/> + <Caret Line="404" Column="5" TopLine="379"/> </Position9> <Position10> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="404" Column="5" TopLine="379"/> + <Caret Line="187" Column="1" TopLine="172"/> </Position10> <Position11> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="187" Column="1" TopLine="172"/> + <Caret Line="380" Column="17" TopLine="362"/> </Position11> <Position12> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="380" Column="17" TopLine="362"/> + <Caret Line="412" Column="1" TopLine="404"/> </Position12> <Position13> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="412" Column="1" TopLine="404"/> + <Caret Line="716" Column="1" TopLine="702"/> </Position13> <Position14> <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="716" Column="1" TopLine="702"/> + <Caret Line="167" Column="17" TopLine="154"/> </Position14> <Position15> - <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="167" Column="17" TopLine="154"/> - </Position15> - <Position16> <Filename Value="..\..\xlsbiff2.pas"/> <Caret Line="69" Column="1" TopLine="57"/> - </Position16> - <Position17> + </Position15> + <Position16> <Filename Value="opendocwrite.lpr"/> <Caret Line="71" Column="1" TopLine="46"/> - </Position17> - <Position18> + </Position16> + <Position17> <Filename Value="..\..\xlsxooxml.pas"/> <Caret Line="48" Column="16" TopLine="35"/> + </Position17> + <Position18> + <Filename Value="..\..\fpsopendocument.pas"/> + <Caret Line="105" Column="1" TopLine="80"/> </Position18> <Position19> <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="105" Column="1" TopLine="80"/> + <Caret Line="111" Column="1" TopLine="86"/> </Position19> <Position20> <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="111" Column="1" TopLine="86"/> + <Caret Line="386" Column="1" TopLine="377"/> </Position20> <Position21> <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="386" Column="1" TopLine="377"/> + <Caret Line="357" Column="1" TopLine="350"/> </Position21> <Position22> <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="357" Column="1" TopLine="350"/> + <Caret Line="304" Column="3" TopLine="294"/> </Position22> <Position23> <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="304" Column="3" TopLine="294"/> + <Caret Line="265" Column="28" TopLine="253"/> </Position23> <Position24> <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="265" Column="28" TopLine="253"/> + <Caret Line="313" Column="1" TopLine="301"/> </Position24> <Position25> <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="313" Column="1" TopLine="301"/> + <Caret Line="41" Column="45" TopLine="37"/> </Position25> <Position26> <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="41" Column="45" TopLine="37"/> + <Caret Line="355" Column="5" TopLine="331"/> </Position26> <Position27> <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="355" Column="5" TopLine="331"/> + <Caret Line="311" Column="1" TopLine="299"/> </Position27> <Position28> <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="311" Column="1" TopLine="299"/> + <Caret Line="260" Column="28" TopLine="249"/> </Position28> <Position29> - <Filename Value="..\..\fpsopendocument.pas"/> - <Caret Line="260" Column="28" TopLine="249"/> - </Position29> - <Position30> <Filename Value="..\..\fpspreadsheet.pas"/> <Caret Line="365" Column="5" TopLine="340"/> + </Position29> + <Position30> + <Filename Value="..\..\fpsopendocument.pas"/> + <Caret Line="290" Column="5" TopLine="265"/> </Position30> </JumpHistory> </ProjectOptions> 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 ' </office:font-face-decls>' + LineEnding + // Automatic styles -'<office:automatic-styles>' + LineEnding + -'<style:style style:name="co1" style:family="table-column">' + LineEnding + -'<style:table-column-properties fo:break-before="auto" style:column-width="2.267cm"/>' + LineEnding + -'</style:style>' + LineEnding + -'<style:style style:name="ro1" style:family="table-row">' + LineEnding + -'<style:table-row-properties style:row-height="0.416cm" fo:break-before="auto" style:use-optimal-row-height="true"/>' + LineEnding + -'</style:style>' + LineEnding + -'<style:style style:name="ta1" style:family="table" style:master-page-name="Default">' + LineEnding + -'<style:table-properties table:display="true" style:writing-mode="lr-tb"/>' + LineEnding + -'</style:style>' + LineEnding + -'</office:automatic-styles>' + LineEnding + + ' <office:automatic-styles>' + LineEnding + + ' <style:style style:name="co1" style:family="table-column">' + LineEnding + + ' <style:table-column-properties fo:break-before="auto" style:column-width="2.267cm"/>' + LineEnding + + ' </style:style>' + LineEnding + + ' <style:style style:name="ro1" style:family="table-row">' + LineEnding + + ' <style:table-row-properties style:row-height="0.416cm" fo:break-before="auto" style:use-optimal-row-height="true"/>' + LineEnding + + ' </style:style>' + LineEnding + + ' <style:style style:name="ta1" style:family="table" style:master-page-name="Default">' + LineEnding + + ' <style:table-properties table:display="true" style:writing-mode="lr-tb"/>' + LineEnding + + ' </style:style>' + LineEnding + + ' </office:automatic-styles>' + LineEnding + -{ ' <office:automatic-styles>' + LineEnding + - ' <style:style style:name="ID0EM" style:family="table-column" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding + - ' <style:table-column-properties fo:break-before="auto" style:column-width="1.961cm" />' + LineEnding + - ' </style:style>' + LineEnding + - ' <style:style style:name="ID0EM" style:family="table-row" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding + - ' <style:table-row-properties fo:break-before="auto" style:row-height="0.45cm" />' + LineEnding + - ' </style:style>' + LineEnding + - ' <style:style style:name="ID1E6B" style:family="table-cell" style:parent-style-name="Default" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding + - ' <style:text-properties fo:font-size="10" style:font-name="Arial" />' + LineEnding + - ' </style:style>' + LineEnding + - ' <style:style style:name="ID2EY" style:family="table" style:master-page-name="Default" xmlns:v="urn:schemas-microsoft-com:vml">' + LineEnding + - ' <style:table-properties />' + LineEnding + - ' </style:style>' + LineEnding + - ' <style:style style:name="scenario" style:family="table" style:master-page-name="Default">' + LineEnding + - ' <style:table-properties table:display="false" style:writing-mode="lr-tb" />' + LineEnding + - ' </style:style>' + LineEnding + - ' </office:automatic-styles>' + LineEnding +} + // Body + ' <office:body>' + LineEnding + + ' <office:spreadsheet>' + LineEnding; - // Body - ' <office:body>' + LineEnding + - ' <office:spreadsheet>' + LineEnding; - - for i := 0 to AData.GetWorksheetCount - 1 do - begin - CurSheet := Adata.GetWorksheetByIndex(i); - - // Header - FContent := FContent + '<table:table table:name="' + CurSheet.Name + '" table:style-name="ta1">' + LineEnding - + '<table:table-column table:style-name="co1" table:number-columns-repeated="' + - IntToStr(CurSheet.GetLastColNumber + 1) + '" table:default-cell-style-name="Default"/>' + LineEnding; - - // The cells need to be written in order, row by row - for j := 0 to CurSheet.GetLastRowNumber do - begin - FContent := FContent + '<table:table-row table:style-name="ro1">' + 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 + '</table:table-row>' + LineEnding; - end; - - // Footer - FContent := FContent + '</table:table>' + LineEnding; - end; + for i := 0 to AData.GetWorksheetCount - 1 do + begin + WriteWorksheet(Adata.GetWorksheetByIndex(i)); + end; FContent := FContent + ' </office:spreadsheet>' + LineEnding + @@ -301,6 +257,36 @@ begin '</office:document-content>'; end; +procedure TsSpreadOpenDocWriter.WriteWorksheet(CurSheet: TsWorksheet); +var + j, k: Integer; + CurCell: PCell; +begin + // Header + FContent := FContent + + ' <table:table table:name="' + CurSheet.Name + '" table:style-name="ta1">' + LineEnding + + ' <table:table-column table:style-name="co1" table:number-columns-repeated="' + + IntToStr(CurSheet.GetLastColNumber + 1) + '" table:default-cell-style-name="Default"/>' + LineEnding; + + // The cells need to be written in order, row by row + for j := 0 to CurSheet.GetLastRowNumber do + begin + FContent := FContent + + ' <table:table-row table:style-name="ro1">' + 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 + ' </table:table-row>' + LineEnding; + end; + + // Footer + FContent := FContent + ' </table:table>' + 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();