From 6bc68ea9b584bf8dfff92a739a0e2cd57ac55f4a Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Sat, 10 Jan 2009 21:47:59 +0000 Subject: [PATCH] fpspreadsheet: Starts adding read support git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@656 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../examples/excel2demo/excel2read.lpi | 273 ++++++++++++++++++ .../examples/excel2demo/excel2read.lpr | 49 ++++ .../examples/excel2demo/excel2write.lpi | 251 ++++++++++++++++ .../examples/excel2demo/excel2write.lpr | 43 +++ .../examples/excel2demo/run_excel2read.bat | 2 + .../run_excel2write.bat} | 2 +- .../examples/excel5demo/excel5read.lpi | 273 ++++++++++++++++++ .../examples/excel5demo/excel5read.lpr | 49 ++++ .../{excel5demo.lpi => excel5write.lpi} | 204 ++++++------- .../{excel5demo.lpr => excel5write.lpr} | 4 +- .../examples/excel5demo/run_excel5read.bat | 2 + .../examples/excel5demo/run_excel5write.bat | 3 + components/fpspreadsheet/fpolestorage.pas | 256 +++++++++++++++- components/fpspreadsheet/fpspreadsheet.pas | 193 ++++++++++++- components/fpspreadsheet/xlsbiff2.pas | 110 ++++++- 15 files changed, 1582 insertions(+), 132 deletions(-) create mode 100644 components/fpspreadsheet/examples/excel2demo/excel2read.lpi create mode 100644 components/fpspreadsheet/examples/excel2demo/excel2read.lpr create mode 100644 components/fpspreadsheet/examples/excel2demo/excel2write.lpi create mode 100644 components/fpspreadsheet/examples/excel2demo/excel2write.lpr create mode 100644 components/fpspreadsheet/examples/excel2demo/run_excel2read.bat rename components/fpspreadsheet/examples/{excel5demo/run_excel5demo.bat => excel2demo/run_excel2write.bat} (52%) create mode 100644 components/fpspreadsheet/examples/excel5demo/excel5read.lpi create mode 100644 components/fpspreadsheet/examples/excel5demo/excel5read.lpr rename components/fpspreadsheet/examples/excel5demo/{excel5demo.lpi => excel5write.lpi} (70%) mode change 100755 => 100644 rename components/fpspreadsheet/examples/excel5demo/{excel5demo.lpr => excel5write.lpr} (98%) mode change 100755 => 100644 create mode 100644 components/fpspreadsheet/examples/excel5demo/run_excel5read.bat create mode 100644 components/fpspreadsheet/examples/excel5demo/run_excel5write.bat diff --git a/components/fpspreadsheet/examples/excel2demo/excel2read.lpi b/components/fpspreadsheet/examples/excel2demo/excel2read.lpi new file mode 100644 index 000000000..a620de222 --- /dev/null +++ b/components/fpspreadsheet/examples/excel2demo/excel2read.lpi @@ -0,0 +1,273 @@ + + + + + + + + + + + + + <ActiveEditorIndexAtStart Value="4"/> + </General> + <VersionInfo> + <ProjectVersion Value=""/> + <Language Value=""/> + <CharSet Value=""/> + </VersionInfo> + <PublishOptions> + <Version Value="2"/> + <IgnoreBinaries Value="False"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> + </local> + </RunParams> + <RequiredPackages Count="1"> + <Item1> + <PackageName Value="laz_fpspreadsheet"/> + </Item1> + </RequiredPackages> + <Units Count="13"> + <Unit0> + <Filename Value="excel2read.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="excel2read"/> + <CursorPos X="6" Y="23"/> + <TopLine Value="12"/> + <EditorIndex Value="0"/> + <UsageCount Value="309"/> + <Loaded Value="True"/> + </Unit0> + <Unit1> + <Filename Value="..\fpolestorage.pas"/> + <UnitName Value="fpolestorage"/> + <CursorPos X="1" Y="1"/> + <TopLine Value="1"/> + <UsageCount Value="19"/> + </Unit1> + <Unit2> + <Filename Value="..\..\..\..\..\lazarus\lcl\interfaces\win32\win32wsstdctrls.pp"/> + <UnitName Value="Win32WSStdCtrls"/> + <CursorPos X="35" Y="720"/> + <TopLine Value="713"/> + <UsageCount Value="76"/> + </Unit2> + <Unit3> + <Filename Value="..\..\..\..\..\lazarus\ideintf\componenteditors.pas"/> + <UnitName Value="ComponentEditors"/> + <CursorPos X="40" Y="332"/> + <TopLine Value="330"/> + <UsageCount Value="74"/> + </Unit3> + <Unit4> + <Filename Value="..\..\xlsbiff5.pas"/> + <UnitName Value="xlsbiff5"/> + <CursorPos X="29" Y="1"/> + <TopLine Value="22"/> + <EditorIndex Value="3"/> + <UsageCount Value="140"/> + <Loaded Value="True"/> + </Unit4> + <Unit5> + <Filename Value="..\..\fpsutils.pas"/> + <UnitName Value="fpsutils"/> + <CursorPos X="1" Y="49"/> + <TopLine Value="30"/> + <EditorIndex Value="2"/> + <UsageCount Value="140"/> + <Loaded Value="True"/> + </Unit5> + <Unit6> + <Filename Value="..\..\xlsbiff2.pas"/> + <UnitName Value="xlsbiff2"/> + <CursorPos X="16" Y="357"/> + <TopLine Value="347"/> + <EditorIndex Value="4"/> + <UsageCount Value="139"/> + <Loaded Value="True"/> + </Unit6> + <Unit7> + <Filename Value="..\..\fpolestorage.pas"/> + <UnitName Value="fpolestorage"/> + <CursorPos X="30" Y="654"/> + <TopLine Value="642"/> + <EditorIndex Value="5"/> + <UsageCount Value="139"/> + <Loaded Value="True"/> + </Unit7> + <Unit8> + <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\classes\classesh.inc"/> + <CursorPos X="19" Y="562"/> + <TopLine Value="553"/> + <UsageCount Value="41"/> + </Unit8> + <Unit9> + <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\classes\streams.inc"/> + <CursorPos X="21" Y="158"/> + <TopLine Value="151"/> + <UsageCount Value="41"/> + </Unit9> + <Unit10> + <Filename Value="..\..\fpspreadsheet.pas"/> + <UnitName Value="fpspreadsheet"/> + <CursorPos X="2" Y="714"/> + <TopLine Value="701"/> + <EditorIndex Value="1"/> + <UsageCount Value="92"/> + <Loaded Value="True"/> + </Unit10> + <Unit11> + <Filename Value="..\..\..\..\..\lazarus\lcl\include\customtrayicon.inc"/> + <CursorPos X="22" Y="203"/> + <TopLine Value="197"/> + <UsageCount Value="67"/> + </Unit11> + <Unit12> + <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\sysutils\sysstrh.inc"/> + <CursorPos X="26" Y="154"/> + <TopLine Value="144"/> + <UsageCount Value="10"/> + </Unit12> + </Units> + <JumpHistory Count="30" HistoryIndex="29"> + <Position1> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="309" Column="1" TopLine="299"/> + </Position1> + <Position2> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="310" Column="1" TopLine="300"/> + </Position2> + <Position3> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="312" Column="1" TopLine="302"/> + </Position3> + <Position4> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="314" Column="1" TopLine="304"/> + </Position4> + <Position5> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="317" Column="1" TopLine="307"/> + </Position5> + <Position6> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="326" Column="1" TopLine="316"/> + </Position6> + <Position7> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="328" Column="1" TopLine="318"/> + </Position7> + <Position8> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="309" Column="1" TopLine="299"/> + </Position8> + <Position9> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="310" Column="1" TopLine="300"/> + </Position9> + <Position10> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="312" Column="1" TopLine="302"/> + </Position10> + <Position11> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="314" Column="1" TopLine="304"/> + </Position11> + <Position12> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="317" Column="1" TopLine="307"/> + </Position12> + <Position13> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="326" Column="1" TopLine="316"/> + </Position13> + <Position14> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="328" Column="1" TopLine="318"/> + </Position14> + <Position15> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="309" Column="1" TopLine="299"/> + </Position15> + <Position16> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="310" Column="1" TopLine="300"/> + </Position16> + <Position17> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="312" Column="1" TopLine="302"/> + </Position17> + <Position18> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="314" Column="1" TopLine="304"/> + </Position18> + <Position19> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="317" Column="1" TopLine="307"/> + </Position19> + <Position20> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="326" Column="1" TopLine="316"/> + </Position20> + <Position21> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="328" Column="1" TopLine="318"/> + </Position21> + <Position22> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="309" Column="1" TopLine="299"/> + </Position22> + <Position23> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="310" Column="1" TopLine="300"/> + </Position23> + <Position24> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="312" Column="1" TopLine="302"/> + </Position24> + <Position25> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="314" Column="1" TopLine="304"/> + </Position25> + <Position26> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="320" Column="1" TopLine="310"/> + </Position26> + <Position27> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="100" Column="16" TopLine="87"/> + </Position27> + <Position28> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="357" Column="16" TopLine="348"/> + </Position28> + <Position29> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="354" Column="6" TopLine="344"/> + </Position29> + <Position30> + <Filename Value="..\..\xlsbiff2.pas"/> + <Caret Line="356" Column="14" TopLine="340"/> + </Position30> + </JumpHistory> + </ProjectOptions> + <CompilerOptions> + <Version Value="8"/> + <PathDelim Value="\"/> + <SearchPaths> + <OtherUnitFiles Value="..\"/> + <SrcPath Value="..\"/> + </SearchPaths> + <Other> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> +</CONFIG> diff --git a/components/fpspreadsheet/examples/excel2demo/excel2read.lpr b/components/fpspreadsheet/examples/excel2demo/excel2read.lpr new file mode 100644 index 000000000..21f3f6d5e --- /dev/null +++ b/components/fpspreadsheet/examples/excel2demo/excel2read.lpr @@ -0,0 +1,49 @@ +{ +excel2read.dpr + +Demonstrates how to read an Excel 2.x file using the fpspreadsheet library + +AUTHORS: Felipe Monteiro de Carvalho +} +program excel2read; + +{$mode delphi}{$H+} + +uses + Classes, SysUtils, fpspreadsheet, xlsbiff2, laz_fpspreadsheet; + +var + MyWorkbook: TsWorkbook; + MyWorksheet: TsWorksheet; + InputFilename: string; + MyDir: string; + i: Integer; + CurCell: PCell; +begin + // Open the input file + MyDir := ExtractFilePath(ParamStr(0)); + InputFileName := MyDir + 'test' + STR_EXCEL_EXTENSION; + WriteLn('Opening input file ', InputFilename); + + // Create the spreadsheet + MyWorkbook := TsWorkbook.Create; + MyWorkbook.ReadFromFile(InputFilename, sfExcel2); + + MyWorksheet := MyWorkbook.GetFirstWorksheet; + + // Write all cells with contents to the console + WriteLn(''); + WriteLn('Contents of the first worksheet of the file:'); + WriteLn(''); + + for i := 0 to MyWorksheet.GetCellCount - 1 do + begin + CurCell := MyWorkSheet.GetCellByIndex(i); + WriteLn('Row: ', CurCell^.Row, ' Col: ', CurCell^.Col, ' Value: ', + MyWorkSheet.ReadAsAnsiText(CurCell^.Row, CurCell^.Col)); + end; + + // Finalization + MyWorkbook.Free; +end. + diff --git a/components/fpspreadsheet/examples/excel2demo/excel2write.lpi b/components/fpspreadsheet/examples/excel2demo/excel2write.lpi new file mode 100644 index 000000000..144c4522b --- /dev/null +++ b/components/fpspreadsheet/examples/excel2demo/excel2write.lpi @@ -0,0 +1,251 @@ +<?xml version="1.0"?> +<CONFIG> + <ProjectOptions> + <PathDelim Value="\"/> + <Version Value="7"/> + <General> + <Flags> + <LRSInOutputDirectory Value="False"/> + </Flags> + <MainUnit Value="0"/> + <TargetFileExt Value=".exe"/> + <Title Value="excel2write"/> + <ActiveEditorIndexAtStart Value="0"/> + </General> + <VersionInfo> + <ProjectVersion Value=""/> + <Language Value=""/> + <CharSet Value=""/> + </VersionInfo> + <PublishOptions> + <Version Value="2"/> + <IgnoreBinaries Value="False"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> + </local> + </RunParams> + <RequiredPackages Count="1"> + <Item1> + <PackageName Value="laz_fpspreadsheet"/> + </Item1> + </RequiredPackages> + <Units Count="12"> + <Unit0> + <Filename Value="excel2write.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="excel2write"/> + <CursorPos X="30" Y="37"/> + <TopLine Value="19"/> + <EditorIndex Value="0"/> + <UsageCount Value="309"/> + <Loaded Value="True"/> + </Unit0> + <Unit1> + <Filename Value="..\fpolestorage.pas"/> + <UnitName Value="fpolestorage"/> + <CursorPos X="1" Y="1"/> + <TopLine Value="1"/> + <UsageCount Value="19"/> + </Unit1> + <Unit2> + <Filename Value="..\..\..\..\..\lazarus\lcl\interfaces\win32\win32wsstdctrls.pp"/> + <UnitName Value="Win32WSStdCtrls"/> + <CursorPos X="35" Y="720"/> + <TopLine Value="713"/> + <UsageCount Value="76"/> + </Unit2> + <Unit3> + <Filename Value="..\..\..\..\..\lazarus\ideintf\componenteditors.pas"/> + <UnitName Value="ComponentEditors"/> + <CursorPos X="40" Y="332"/> + <TopLine Value="330"/> + <UsageCount Value="74"/> + </Unit3> + <Unit4> + <Filename Value="..\..\xlsbiff5.pas"/> + <UnitName Value="xlsbiff5"/> + <CursorPos X="1" Y="224"/> + <TopLine Value="215"/> + <EditorIndex Value="3"/> + <UsageCount Value="140"/> + <Loaded Value="True"/> + </Unit4> + <Unit5> + <Filename Value="..\..\fpsutils.pas"/> + <UnitName Value="fpsutils"/> + <CursorPos X="1" Y="49"/> + <TopLine Value="30"/> + <EditorIndex Value="2"/> + <UsageCount Value="140"/> + <Loaded Value="True"/> + </Unit5> + <Unit6> + <Filename Value="..\..\xlsbiff2.pas"/> + <UnitName Value="xlsbiff2"/> + <CursorPos X="1" Y="69"/> + <TopLine Value="57"/> + <EditorIndex Value="4"/> + <UsageCount Value="139"/> + <Loaded Value="True"/> + </Unit6> + <Unit7> + <Filename Value="..\..\fpolestorage.pas"/> + <UnitName Value="fpolestorage"/> + <CursorPos X="30" Y="654"/> + <TopLine Value="642"/> + <EditorIndex Value="5"/> + <UsageCount Value="139"/> + <Loaded Value="True"/> + </Unit7> + <Unit8> + <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\classes\classesh.inc"/> + <CursorPos X="19" Y="562"/> + <TopLine Value="553"/> + <UsageCount Value="41"/> + </Unit8> + <Unit9> + <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\classes\streams.inc"/> + <CursorPos X="21" Y="158"/> + <TopLine Value="151"/> + <UsageCount Value="41"/> + </Unit9> + <Unit10> + <Filename Value="..\..\fpspreadsheet.pas"/> + <UnitName Value="fpspreadsheet"/> + <CursorPos X="3" Y="428"/> + <TopLine Value="420"/> + <EditorIndex Value="1"/> + <UsageCount Value="92"/> + <Loaded Value="True"/> + </Unit10> + <Unit11> + <Filename Value="..\..\..\..\..\lazarus\lcl\include\customtrayicon.inc"/> + <CursorPos X="22" Y="203"/> + <TopLine Value="197"/> + <UsageCount Value="67"/> + </Unit11> + </Units> + <JumpHistory Count="26" HistoryIndex="25"> + <Position1> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="40" Column="5" TopLine="31"/> + </Position1> + <Position2> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="472" Column="49" TopLine="461"/> + </Position2> + <Position3> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="405" Column="5" TopLine="386"/> + </Position3> + <Position4> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="404" Column="14" TopLine="401"/> + </Position4> + <Position5> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="79" Column="42" TopLine="72"/> + </Position5> + <Position6> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="78" Column="31" TopLine="67"/> + </Position6> + <Position7> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="314" Column="39" TopLine="296"/> + </Position7> + <Position8> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="479" Column="1" TopLine="469"/> + </Position8> + <Position9> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="470" Column="1" TopLine="460"/> + </Position9> + <Position10> + <Filename Value="..\..\xlsbiff5.pas"/> + <Caret Line="217" Column="3" TopLine="205"/> + </Position10> + <Position11> + <Filename Value="..\..\xlsbiff5.pas"/> + <Caret Line="218" Column="23" TopLine="208"/> + </Position11> + <Position12> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="78" Column="10" TopLine="66"/> + </Position12> + <Position13> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="375" Column="1" TopLine="367"/> + </Position13> + <Position14> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="76" Column="17" TopLine="65"/> + </Position14> + <Position15> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="363" Column="1" TopLine="357"/> + </Position15> + <Position16> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="77" Column="7" TopLine="76"/> + </Position16> + <Position17> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="137" Column="40" TopLine="129"/> + </Position17> + <Position18> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="563" Column="5" TopLine="544"/> + </Position18> + <Position19> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="486" Column="5" TopLine="467"/> + </Position19> + <Position20> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="510" Column="5" TopLine="491"/> + </Position20> + <Position21> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="94" Column="46" TopLine="84"/> + </Position21> + <Position22> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="686" Column="5" TopLine="667"/> + </Position22> + <Position23> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="567" Column="5" TopLine="548"/> + </Position23> + <Position24> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="622" Column="1" TopLine="618"/> + </Position24> + <Position25> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="621" Column="29" TopLine="611"/> + </Position25> + <Position26> + <Filename Value="excel2write.lpr"/> + <Caret Line="30" Column="21" TopLine="19"/> + </Position26> + </JumpHistory> + </ProjectOptions> + <CompilerOptions> + <Version Value="8"/> + <PathDelim Value="\"/> + <SearchPaths> + <OtherUnitFiles Value="..\"/> + <SrcPath Value="..\"/> + </SearchPaths> + <Other> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> +</CONFIG> diff --git a/components/fpspreadsheet/examples/excel2demo/excel2write.lpr b/components/fpspreadsheet/examples/excel2demo/excel2write.lpr new file mode 100644 index 000000000..fe38d3024 --- /dev/null +++ b/components/fpspreadsheet/examples/excel2demo/excel2write.lpr @@ -0,0 +1,43 @@ +{ +excel2write.dpr + +Demonstrates how to write an Excel 2.x file using the fpspreadsheet library + +AUTHORS: Felipe Monteiro de Carvalho +} +program excel2write; + +{$mode delphi}{$H+} + +uses + Classes, SysUtils, fpspreadsheet, xlsbiff2, laz_fpspreadsheet; + +var + MyWorkbook: TsWorkbook; + MyWorksheet: TsWorksheet; + MyDir: string; +begin + // Open the output file + MyDir := ExtractFilePath(ParamStr(0)); + + // Create the spreadsheet + MyWorkbook := TsWorkbook.Create; + 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); + + // Write some string cells + MyWorksheet.WriteAnsiText(1, 0, 'First'); + MyWorksheet.WriteAnsiText(1, 1, 'Second'); + MyWorksheet.WriteAnsiText(1, 2, 'Third'); + MyWorksheet.WriteAnsiText(1, 3, 'Fourth'); + + // Save the spreadsheet to a file + MyWorkbook.WriteToFile(MyDir + 'test' + STR_EXCEL_EXTENSION, sfExcel2); + MyWorkbook.Free; +end. + diff --git a/components/fpspreadsheet/examples/excel2demo/run_excel2read.bat b/components/fpspreadsheet/examples/excel2demo/run_excel2read.bat new file mode 100644 index 000000000..5d8406c3a --- /dev/null +++ b/components/fpspreadsheet/examples/excel2demo/run_excel2read.bat @@ -0,0 +1,2 @@ +excel2read.exe +pause \ No newline at end of file diff --git a/components/fpspreadsheet/examples/excel5demo/run_excel5demo.bat b/components/fpspreadsheet/examples/excel2demo/run_excel2write.bat similarity index 52% rename from components/fpspreadsheet/examples/excel5demo/run_excel5demo.bat rename to components/fpspreadsheet/examples/excel2demo/run_excel2write.bat index d266a1db5..7c6c9938a 100644 --- a/components/fpspreadsheet/examples/excel5demo/run_excel5demo.bat +++ b/components/fpspreadsheet/examples/excel2demo/run_excel2write.bat @@ -1,3 +1,3 @@ del test.xls -excel5demo.exe +excel2write.exe pause \ No newline at end of file diff --git a/components/fpspreadsheet/examples/excel5demo/excel5read.lpi b/components/fpspreadsheet/examples/excel5demo/excel5read.lpi new file mode 100644 index 000000000..62ada40a3 --- /dev/null +++ b/components/fpspreadsheet/examples/excel5demo/excel5read.lpi @@ -0,0 +1,273 @@ +<?xml version="1.0"?> +<CONFIG> + <ProjectOptions> + <PathDelim Value="\"/> + <Version Value="7"/> + <General> + <Flags> + <LRSInOutputDirectory Value="False"/> + </Flags> + <MainUnit Value="0"/> + <TargetFileExt Value=".exe"/> + <Title Value="excel5read"/> + <ActiveEditorIndexAtStart Value="1"/> + </General> + <VersionInfo> + <ProjectVersion Value=""/> + <Language Value=""/> + <CharSet Value=""/> + </VersionInfo> + <PublishOptions> + <Version Value="2"/> + <IgnoreBinaries Value="False"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + <LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/> + </local> + </RunParams> + <RequiredPackages Count="1"> + <Item1> + <PackageName Value="laz_fpspreadsheet"/> + </Item1> + </RequiredPackages> + <Units Count="13"> + <Unit0> + <Filename Value="excel5read.lpr"/> + <IsPartOfProject Value="True"/> + <UnitName Value="excel5read"/> + <CursorPos X="1" Y="21"/> + <TopLine Value="3"/> + <EditorIndex Value="0"/> + <UsageCount Value="309"/> + <Loaded Value="True"/> + </Unit0> + <Unit1> + <Filename Value="..\fpolestorage.pas"/> + <UnitName Value="fpolestorage"/> + <CursorPos X="1" Y="1"/> + <TopLine Value="1"/> + <UsageCount Value="19"/> + </Unit1> + <Unit2> + <Filename Value="..\..\..\..\..\lazarus\lcl\interfaces\win32\win32wsstdctrls.pp"/> + <UnitName Value="Win32WSStdCtrls"/> + <CursorPos X="35" Y="720"/> + <TopLine Value="713"/> + <UsageCount Value="76"/> + </Unit2> + <Unit3> + <Filename Value="..\..\..\..\..\lazarus\ideintf\componenteditors.pas"/> + <UnitName Value="ComponentEditors"/> + <CursorPos X="40" Y="332"/> + <TopLine Value="330"/> + <UsageCount Value="74"/> + </Unit3> + <Unit4> + <Filename Value="..\..\xlsbiff5.pas"/> + <UnitName Value="xlsbiff5"/> + <CursorPos X="15" Y="64"/> + <TopLine Value="54"/> + <EditorIndex Value="3"/> + <UsageCount Value="140"/> + <Loaded Value="True"/> + </Unit4> + <Unit5> + <Filename Value="..\..\fpsutils.pas"/> + <UnitName Value="fpsutils"/> + <CursorPos X="1" Y="49"/> + <TopLine Value="30"/> + <EditorIndex Value="2"/> + <UsageCount Value="140"/> + <Loaded Value="True"/> + </Unit5> + <Unit6> + <Filename Value="..\..\xlsbiff2.pas"/> + <UnitName Value="xlsbiff2"/> + <CursorPos X="1" Y="69"/> + <TopLine Value="57"/> + <EditorIndex Value="4"/> + <UsageCount Value="139"/> + <Loaded Value="True"/> + </Unit6> + <Unit7> + <Filename Value="..\..\fpolestorage.pas"/> + <UnitName Value="fpolestorage"/> + <CursorPos X="30" Y="654"/> + <TopLine Value="642"/> + <EditorIndex Value="5"/> + <UsageCount Value="139"/> + <Loaded Value="True"/> + </Unit7> + <Unit8> + <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\classes\classesh.inc"/> + <CursorPos X="19" Y="562"/> + <TopLine Value="553"/> + <UsageCount Value="41"/> + </Unit8> + <Unit9> + <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\classes\streams.inc"/> + <CursorPos X="21" Y="158"/> + <TopLine Value="151"/> + <UsageCount Value="41"/> + </Unit9> + <Unit10> + <Filename Value="..\..\fpspreadsheet.pas"/> + <UnitName Value="fpspreadsheet"/> + <CursorPos X="1" Y="197"/> + <TopLine Value="189"/> + <EditorIndex Value="1"/> + <UsageCount Value="92"/> + <Loaded Value="True"/> + </Unit10> + <Unit11> + <Filename Value="..\..\..\..\..\lazarus\lcl\include\customtrayicon.inc"/> + <CursorPos X="22" Y="203"/> + <TopLine Value="197"/> + <UsageCount Value="67"/> + </Unit11> + <Unit12> + <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\sysutils\sysstrh.inc"/> + <CursorPos X="26" Y="154"/> + <TopLine Value="144"/> + <UsageCount Value="10"/> + </Unit12> + </Units> + <JumpHistory Count="30" HistoryIndex="29"> + <Position1> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="486" Column="5" TopLine="467"/> + </Position1> + <Position2> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="510" Column="5" TopLine="491"/> + </Position2> + <Position3> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="94" Column="46" TopLine="84"/> + </Position3> + <Position4> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="686" Column="5" TopLine="667"/> + </Position4> + <Position5> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="567" Column="5" TopLine="548"/> + </Position5> + <Position6> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="622" Column="1" TopLine="618"/> + </Position6> + <Position7> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="621" Column="29" TopLine="611"/> + </Position7> + <Position8> + <Filename Value="excel5read.lpr"/> + <Caret Line="40" Column="17" TopLine="29"/> + </Position8> + <Position9> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="85" Column="3" TopLine="83"/> + </Position9> + <Position10> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="304" Column="5" TopLine="293"/> + </Position10> + <Position11> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="319" Column="32" TopLine="305"/> + </Position11> + <Position12> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="363" Column="15" TopLine="349"/> + </Position12> + <Position13> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="362" Column="36" TopLine="353"/> + </Position13> + <Position14> + <Filename Value="excel5read.lpr"/> + <Caret Line="40" Column="17" TopLine="29"/> + </Position14> + <Position15> + <Filename Value="excel5read.lpr"/> + <Caret Line="24" Column="1" TopLine="13"/> + </Position15> + <Position16> + <Filename Value="excel5read.lpr"/> + <Caret Line="29" Column="6" TopLine="19"/> + </Position16> + <Position17> + <Filename Value="excel5read.lpr"/> + <Caret Line="16" Column="17" TopLine="6"/> + </Position17> + <Position18> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="110" Column="3" TopLine="108"/> + </Position18> + <Position19> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="475" Column="5" TopLine="456"/> + </Position19> + <Position20> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="505" Column="42" TopLine="496"/> + </Position20> + <Position21> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="175" Column="24" TopLine="165"/> + </Position21> + <Position22> + <Filename Value="excel5read.lpr"/> + <Caret Line="16" Column="17" TopLine="6"/> + </Position22> + <Position23> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="143" Column="15" TopLine="115"/> + </Position23> + <Position24> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="119" Column="67" TopLine="108"/> + </Position24> + <Position25> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="485" Column="42" TopLine="474"/> + </Position25> + <Position26> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="161" Column="3" TopLine="159"/> + </Position26> + <Position27> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="141" Column="3" TopLine="139"/> + </Position27> + <Position28> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="669" Column="20" TopLine="658"/> + </Position28> + <Position29> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="158" Column="15" TopLine="143"/> + </Position29> + <Position30> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="116" Column="71" TopLine="106"/> + </Position30> + </JumpHistory> + </ProjectOptions> + <CompilerOptions> + <Version Value="8"/> + <PathDelim Value="\"/> + <SearchPaths> + <OtherUnitFiles Value="..\"/> + <SrcPath Value="..\"/> + </SearchPaths> + <Other> + <CompilerPath Value="$(CompPath)"/> + </Other> + </CompilerOptions> +</CONFIG> diff --git a/components/fpspreadsheet/examples/excel5demo/excel5read.lpr b/components/fpspreadsheet/examples/excel5demo/excel5read.lpr new file mode 100644 index 000000000..044527a24 --- /dev/null +++ b/components/fpspreadsheet/examples/excel5demo/excel5read.lpr @@ -0,0 +1,49 @@ +{ +excel5read.dpr + +Demonstrates how to read an Excel 5.x file using the fpspreadsheet library + +AUTHORS: Felipe Monteiro de Carvalho +} +program excel5read; + +{$mode delphi}{$H+} + +uses + Classes, SysUtils, fpspreadsheet, xlsbiff5, laz_fpspreadsheet; + +var + MyWorkbook: TsWorkbook; + MyWorksheet: TsWorksheet; + InputFilename: string; + MyDir: string; + i: Integer; + CurCell: PCell; +begin + // Open the input file + MyDir := ExtractFilePath(ParamStr(0)); + InputFileName := MyDir + 'test' + STR_EXCEL_EXTENSION; + WriteLn('Opening input file ', InputFilename); + + // Create the spreadsheet + MyWorkbook := TsWorkbook.Create; + MyWorkbook.ReadFromFile(InputFilename, sfExcel5); + + MyWorksheet := MyWorkbook.GetFirstWorksheet; + + // Write all cells with contents to the console + WriteLn(''); + WriteLn('Contents of the first worksheet of the file:'); + WriteLn(''); + + for i := 0 to MyWorksheet.GetCellCount do + begin + CurCell := MyWorkSheet.GetCellByIndex(i); + WriteLn('Row: ', CurCell^.Row, ' Col: ', CurCell^.Col, ' Value: ', + MyWorkSheet.ReadAsAnsiText(CurCell^.Row, CurCell^.Col)); + end; + + // Finalization + MyWorkbook.Free; +end. + diff --git a/components/fpspreadsheet/examples/excel5demo/excel5demo.lpi b/components/fpspreadsheet/examples/excel5demo/excel5write.lpi old mode 100755 new mode 100644 similarity index 70% rename from components/fpspreadsheet/examples/excel5demo/excel5demo.lpi rename to components/fpspreadsheet/examples/excel5demo/excel5write.lpi index 978200f9c..ab6d801d0 --- a/components/fpspreadsheet/examples/excel5demo/excel5demo.lpi +++ b/components/fpspreadsheet/examples/excel5demo/excel5write.lpi @@ -2,10 +2,14 @@ <CONFIG> <ProjectOptions> <PathDelim Value="\"/> - <Version Value="6"/> + <Version Value="7"/> <General> + <Flags> + <LRSInOutputDirectory Value="False"/> + </Flags> <MainUnit Value="0"/> <TargetFileExt Value=".exe"/> + <Title Value="excel5write"/> <ActiveEditorIndexAtStart Value="0"/> </General> <VersionInfo> @@ -30,243 +34,203 @@ <PackageName Value="laz_fpspreadsheet"/> </Item1> </RequiredPackages> - <Units Count="16"> + <Units Count="12"> <Unit0> - <Filename Value="excel5demo.lpr"/> + <Filename Value="excel5write.lpr"/> <IsPartOfProject Value="True"/> - <UnitName Value="excel5demo"/> + <UnitName Value="excel5write"/> <CursorPos X="8" Y="21"/> <TopLine Value="52"/> <EditorIndex Value="0"/> - <UsageCount Value="196"/> + <UsageCount Value="309"/> <Loaded Value="True"/> </Unit0> <Unit1> - <Filename Value="..\fpspreadsheet.pas"/> - <UnitName Value="fpspreadsheet"/> - <CursorPos X="32" Y="414"/> - <TopLine Value="388"/> - <UsageCount Value="10"/> - </Unit1> - <Unit2> - <Filename Value="..\xlsbiff5.pas"/> - <UnitName Value="xlsbiff5"/> - <CursorPos X="16" Y="320"/> - <TopLine Value="300"/> - <UsageCount Value="10"/> - </Unit2> - <Unit3> <Filename Value="..\fpolestorage.pas"/> <UnitName Value="fpolestorage"/> <CursorPos X="1" Y="1"/> <TopLine Value="1"/> - <UsageCount Value="30"/> - </Unit3> - <Unit4> - <Filename Value="..\xlsbiff2.pas"/> - <UnitName Value="xlsbiff2"/> - <CursorPos X="20" Y="277"/> - <TopLine Value="260"/> - <UsageCount Value="3"/> - </Unit4> - <Unit5> - <Filename Value="..\..\..\..\..\FPC220\source\rtl\objpas\fgl.pp"/> - <UnitName Value="fgl"/> - <CursorPos X="15" Y="86"/> - <TopLine Value="55"/> - <UsageCount Value="3"/> - </Unit5> - <Unit6> + <UsageCount Value="19"/> + </Unit1> + <Unit2> <Filename Value="..\..\..\..\..\lazarus\lcl\interfaces\win32\win32wsstdctrls.pp"/> <UnitName Value="Win32WSStdCtrls"/> - <CursorPos X="11" Y="737"/> + <CursorPos X="35" Y="720"/> <TopLine Value="713"/> - <EditorIndex Value="7"/> - <UsageCount Value="88"/> - <Loaded Value="True"/> - </Unit6> - <Unit7> + <UsageCount Value="76"/> + </Unit2> + <Unit3> <Filename Value="..\..\..\..\..\lazarus\ideintf\componenteditors.pas"/> <UnitName Value="ComponentEditors"/> - <CursorPos X="54" Y="353"/> + <CursorPos X="40" Y="332"/> <TopLine Value="330"/> - <EditorIndex Value="6"/> - <UsageCount Value="86"/> - <Loaded Value="True"/> - </Unit7> - <Unit8> + <UsageCount Value="74"/> + </Unit3> + <Unit4> <Filename Value="..\..\xlsbiff5.pas"/> <UnitName Value="xlsbiff5"/> <CursorPos X="1" Y="224"/> <TopLine Value="215"/> <EditorIndex Value="3"/> - <UsageCount Value="83"/> + <UsageCount Value="140"/> <Loaded Value="True"/> - </Unit8> - <Unit9> + </Unit4> + <Unit5> <Filename Value="..\..\fpsutils.pas"/> <UnitName Value="fpsutils"/> <CursorPos X="1" Y="49"/> <TopLine Value="30"/> <EditorIndex Value="2"/> - <UsageCount Value="83"/> + <UsageCount Value="140"/> <Loaded Value="True"/> - </Unit9> - <Unit10> + </Unit5> + <Unit6> <Filename Value="..\..\xlsbiff2.pas"/> <UnitName Value="xlsbiff2"/> <CursorPos X="1" Y="69"/> <TopLine Value="57"/> <EditorIndex Value="4"/> - <UsageCount Value="83"/> + <UsageCount Value="139"/> <Loaded Value="True"/> - </Unit10> - <Unit11> + </Unit6> + <Unit7> <Filename Value="..\..\fpolestorage.pas"/> <UnitName Value="fpolestorage"/> - <CursorPos X="48" Y="534"/> - <TopLine Value="520"/> + <CursorPos X="30" Y="654"/> + <TopLine Value="642"/> <EditorIndex Value="5"/> - <UsageCount Value="83"/> + <UsageCount Value="139"/> <Loaded Value="True"/> - </Unit11> - <Unit12> + </Unit7> + <Unit8> <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\classes\classesh.inc"/> <CursorPos X="19" Y="562"/> <TopLine Value="553"/> - <UsageCount Value="53"/> - </Unit12> - <Unit13> + <UsageCount Value="41"/> + </Unit8> + <Unit9> <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\classes\streams.inc"/> <CursorPos X="21" Y="158"/> <TopLine Value="151"/> - <UsageCount Value="53"/> - </Unit13> - <Unit14> + <UsageCount Value="41"/> + </Unit9> + <Unit10> <Filename Value="..\..\fpspreadsheet.pas"/> <UnitName Value="fpspreadsheet"/> <CursorPos X="40" Y="137"/> <TopLine Value="129"/> <EditorIndex Value="1"/> - <UsageCount Value="33"/> + <UsageCount Value="92"/> <Loaded Value="True"/> - </Unit14> - <Unit15> - <Filename Value="..\..\..\..\..\lazarus26\fpc\2.2.2\source\rtl\objpas\classes\stringl.inc"/> - <CursorPos X="20" Y="768"/> - <TopLine Value="761"/> - <UsageCount Value="10"/> - </Unit15> + </Unit10> + <Unit11> + <Filename Value="..\..\..\..\..\lazarus\lcl\include\customtrayicon.inc"/> + <CursorPos X="22" Y="203"/> + <TopLine Value="197"/> + <UsageCount Value="67"/> + </Unit11> </Units> - <JumpHistory Count="27" HistoryIndex="26"> + <JumpHistory Count="25" HistoryIndex="24"> <Position1> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="246" Column="12" TopLine="237"/> + <Caret Line="40" Column="5" TopLine="31"/> </Position1> <Position2> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="79" Column="16" TopLine="78"/> + <Caret Line="472" Column="49" TopLine="461"/> </Position2> <Position3> - <Filename Value="..\..\xlsbiff5.pas"/> - <Caret Line="87" Column="16" TopLine="77"/> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="405" Column="5" TopLine="386"/> </Position3> <Position4> - <Filename Value="..\..\xlsbiff5.pas"/> - <Caret Line="218" Column="24" TopLine="207"/> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="404" Column="14" TopLine="401"/> </Position4> <Position5> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="235" Column="30" TopLine="224"/> + <Caret Line="79" Column="42" TopLine="72"/> </Position5> <Position6> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="80" Column="28" TopLine="68"/> + <Caret Line="78" Column="31" TopLine="67"/> </Position6> <Position7> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="40" Column="5" TopLine="31"/> + <Caret Line="314" Column="39" TopLine="296"/> </Position7> <Position8> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="472" Column="49" TopLine="461"/> + <Caret Line="479" Column="1" TopLine="469"/> </Position8> <Position9> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="405" Column="5" TopLine="386"/> + <Caret Line="470" Column="1" TopLine="460"/> </Position9> <Position10> - <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="404" Column="14" TopLine="401"/> + <Filename Value="..\..\xlsbiff5.pas"/> + <Caret Line="217" Column="3" TopLine="205"/> </Position10> <Position11> - <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="79" Column="42" TopLine="72"/> + <Filename Value="..\..\xlsbiff5.pas"/> + <Caret Line="218" Column="23" TopLine="208"/> </Position11> <Position12> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="78" Column="31" TopLine="67"/> + <Caret Line="78" Column="10" TopLine="66"/> </Position12> <Position13> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="314" Column="39" TopLine="296"/> + <Caret Line="375" Column="1" TopLine="367"/> </Position13> <Position14> - <Filename Value="excel5demo.lpr"/> - <Caret Line="34" Column="1" TopLine="25"/> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="76" Column="17" TopLine="65"/> </Position14> <Position15> - <Filename Value="excel5demo.lpr"/> - <Caret Line="35" Column="1" TopLine="25"/> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="363" Column="1" TopLine="357"/> </Position15> <Position16> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="479" Column="1" TopLine="469"/> + <Caret Line="77" Column="7" TopLine="76"/> </Position16> <Position17> - <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="470" Column="1" TopLine="460"/> + <Filename Value="..\..\fpspreadsheet.pas"/> + <Caret Line="137" Column="40" TopLine="129"/> </Position17> <Position18> - <Filename Value="..\..\xlsbiff5.pas"/> - <Caret Line="217" Column="3" TopLine="205"/> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="563" Column="5" TopLine="544"/> </Position18> <Position19> - <Filename Value="..\..\xlsbiff5.pas"/> - <Caret Line="218" Column="23" TopLine="208"/> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="486" Column="5" TopLine="467"/> </Position19> <Position20> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="78" Column="10" TopLine="66"/> + <Caret Line="510" Column="5" TopLine="491"/> </Position20> <Position21> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="375" Column="1" TopLine="367"/> + <Caret Line="94" Column="46" TopLine="84"/> </Position21> <Position22> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="76" Column="17" TopLine="65"/> + <Caret Line="686" Column="5" TopLine="667"/> </Position22> <Position23> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="363" Column="1" TopLine="357"/> + <Caret Line="567" Column="5" TopLine="548"/> </Position23> <Position24> <Filename Value="..\..\fpolestorage.pas"/> - <Caret Line="77" Column="7" TopLine="76"/> + <Caret Line="622" Column="1" TopLine="618"/> </Position24> <Position25> - <Filename Value="excel5demo.lpr"/> - <Caret Line="67" Column="21" TopLine="51"/> + <Filename Value="..\..\fpolestorage.pas"/> + <Caret Line="621" Column="29" TopLine="611"/> </Position25> - <Position26> - <Filename Value="..\..\fpspreadsheet.pas"/> - <Caret Line="137" Column="40" TopLine="129"/> - </Position26> - <Position27> - <Filename Value="excel5demo.lpr"/> - <Caret Line="21" Column="8" TopLine="6"/> - </Position27> </JumpHistory> </ProjectOptions> <CompilerOptions> diff --git a/components/fpspreadsheet/examples/excel5demo/excel5demo.lpr b/components/fpspreadsheet/examples/excel5demo/excel5write.lpr old mode 100755 new mode 100644 similarity index 98% rename from components/fpspreadsheet/examples/excel5demo/excel5demo.lpr rename to components/fpspreadsheet/examples/excel5demo/excel5write.lpr index c627c3914..036ae493d --- a/components/fpspreadsheet/examples/excel5demo/excel5demo.lpr +++ b/components/fpspreadsheet/examples/excel5demo/excel5write.lpr @@ -1,11 +1,11 @@ { -excel5demo.dpr +excel5write.dpr Demonstrates how to write an Excel 5.x file using the fpspreadsheet library AUTHORS: Felipe Monteiro de Carvalho } -program excel5demo; +program excel5write; {$mode delphi}{$H+} diff --git a/components/fpspreadsheet/examples/excel5demo/run_excel5read.bat b/components/fpspreadsheet/examples/excel5demo/run_excel5read.bat new file mode 100644 index 000000000..5eee2337f --- /dev/null +++ b/components/fpspreadsheet/examples/excel5demo/run_excel5read.bat @@ -0,0 +1,2 @@ +excel5read.exe +pause \ No newline at end of file diff --git a/components/fpspreadsheet/examples/excel5demo/run_excel5write.bat b/components/fpspreadsheet/examples/excel5demo/run_excel5write.bat new file mode 100644 index 000000000..6d70c6689 --- /dev/null +++ b/components/fpspreadsheet/examples/excel5demo/run_excel5write.bat @@ -0,0 +1,3 @@ +del test.xls +excel5write.exe +pause \ No newline at end of file diff --git a/components/fpspreadsheet/fpolestorage.pas b/components/fpspreadsheet/fpolestorage.pas index 506ff8770..fc551193e 100755 --- a/components/fpspreadsheet/fpolestorage.pas +++ b/components/fpspreadsheet/fpolestorage.pas @@ -60,16 +60,19 @@ type TOLEStorage = class private + { Information filled by the write routines for the helper routines } {$ifdef FPOLESTORAGE_USE_COM} FStorage: IStorage; FStream: IStream; {$endif} - { Information filled by the write routines for the helper routines } + { Fields for the read routines } + FReadingStreamSize: Int64; + { Fields for both } FOLEDocument: TOLEDocument; + FUseShortSectors: Boolean; FNumSATSectors, FNumStreamSectors, FNumTotalSectors: Cardinal; FNumStreamShortSectors: Cardinal; - FUseShortSectors: Boolean; - { Helper routines } + { Writer Helper routines } procedure WriteOLEHeader(AStream: TStream); procedure WriteSectorAllocationTable(AStream: TStream); procedure WriteDirectoryStream(AStream: TStream); @@ -78,10 +81,21 @@ type AFirstSecID, AStreamSize: Cardinal); procedure WriteShortSectorAllocationTable(AStream: TStream); procedure WriteUserStream(ADest, ASource: TStream); + { Reader helper routines } + procedure ReadOLEHeader(AStream: TStream); + procedure ReadSectorAllocationTable(AStream: TStream); + procedure ReadDirectoryStream(AStream: TStream); + procedure ReadDirectoryEntry(AStream: TStream; var AName: widestring; + var EntryType, EntryColor: Byte; var AIsStorage: Boolean; + var AFirstSecID, AStreamSize: Cardinal); + procedure ReadShortSectorAllocationTable(AStream: TStream); + procedure ReadUserStream(ADest, ASource: TStream); public constructor Create; destructor Destroy; override; procedure WriteOLEFile(AFileName: string; AOLEDocument: TOLEDocument); + procedure ReadOLEFile(AFileName: string; AOLEDocument: TOLEDocument); + procedure FreeOLEDocumentData(AOLEDocument: TOLEDocument); end; implementation @@ -475,6 +489,183 @@ begin for i := 1 to PadSize do ADest.WriteByte($00); end; +procedure TOLEStorage.ReadOLEHeader(AStream: TStream); +var + BaseAddr: Int64; +begin + BaseAddr := AStream.Position; + + { 28 2 Byte order identifier (➜4.2): FEH FFH = Little-Endian + FFH FEH = Big-Endian } + + // For now just assume little-endian + + { 30 2 Size of a sector in the compound document file (➜3.1) in power-of-two (ssz), real sector + size is sec_size = 2ssz bytes (minimum value is 7 which means 128 bytes, most used + value is 9 which means 512 bytes) } + + // Assume default value + + { 32 2 Size of a short-sector in the short-stream container stream (➜6.1) in power-of-two (sssz), + real short-sector size is short_sec_size = 2sssz bytes (maximum value is sector size + ssz, see above, most used value is 6 which means 64 bytes) } + + // Assume default value + + { 44 4 Total number of sectors used for the sector allocation table (➜5.2) } + + // Assume 1 + + { 48 4 SecID of first sector of the directory stream (➜7) } + + // Assume 1 + + { 56 4 Minimum size of a standard stream (in bytes, minimum allowed and most used size is 4096 + bytes), streams with an actual size smaller than (and not equal to) this value are stored as + short-streams (➜6) } + + // Assume 4096 + + { 60 4 SecID of first sector of the short-sector allocation table (➜6.2), or –2 (End Of Chain + SecID, ➜3.1) if not extant } + + // Assume 2 + + { 64 4 Total number of sectors used for the short-sector allocation table (➜6.2) } + + // Assume 1 + + { 68 4 SecID of first sector of the master sector allocation table (➜5.1), or –2 (End Of Chain + SecID, ➜3.1) if no additional sectors used } + + // Assume 2 + + { 72 4 Total number of sectors used for the master sector allocation table (➜5.1) } + + // Assume 0 + + { 76 436 First part of the master sector allocation table (➜5.1) containing 109 SecIDs } + + // Assume: 0, -1, -1, -1 ... +end; + +procedure TOLEStorage.ReadSectorAllocationTable(AStream: TStream); +begin + +end; + +procedure TOLEStorage.ReadDirectoryStream(AStream: TStream); +var + EntryName: widestring; + EntryType, EntryColor: Byte; + EntryIsStorage: Boolean; + EntryFirstSecID, EntryStreamSize: Cardinal; +begin + ReadDirectoryEntry(AStream, EntryName, + EntryType, EntryColor, EntryIsStorage, + EntryFirstSecID, EntryStreamSize); + + ReadDirectoryEntry(AStream, EntryName, + EntryType, EntryColor, EntryIsStorage, + EntryFirstSecID, EntryStreamSize); + + FReadingStreamSize := EntryStreamSize; +end; + +procedure TOLEStorage.ReadDirectoryEntry(AStream: TStream; + var AName: widestring; var EntryType, EntryColor: Byte; + var AIsStorage: Boolean; var AFirstSecID, AStreamSize: Cardinal); +var + BaseAddr: Int64; + EntryName: array[0..63] of WideChar; +begin + BaseAddr := AStream.Position; + + { Contents of the directory entry structure: + Offset Size Contents + 0 64 Character array of the name of the entry, always 16-bit Unicode characters, with trailing + zero character (results in a maximum name length of 31 characters) + + 00000400H 52 00 6F 00 6F 00 74 00 20 00 45 00 6E 00 74 00 } + + AStream.ReadBuffer(EntryName, 64); + + AName := EntryName; + + {Root Storage #1 + 00000440H 16 00 05 00 FF FF FF FF FF FF FF FF 01 00 00 00 + + Book #2 + 000004C0H 0A 00 02 01 FF FF FF FF FF FF FF FF FF FF FF FF + + Item #3 e #4 + 00000540H 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF + + 64 2 Size of the used area of the character buffer of the name (not character count), including + the trailing zero character (e.g. 12 for a name with 5 characters: (5+1)∙2 = 12) + 66 1 Type of the entry: 00H = Empty 03H = LockBytes (unknown) + 01H = User storage 04H = Property (unknown) + 02H = User stream 05H = Root storage + 67 1 Node colour of the entry: 00H = Red 01H = Black + 68 4 DirID of the left child node inside the red-black tree of all direct members of the parent + storage (if this entry is a user storage or stream, ➜7.1), –1 if there is no left child + 72 4 DirID of the right child node inside the red-black tree of all direct members of the parent + storage (if this entry is a user storage or stream, ➜7.1), –1 if there is no right child + 76 4 DirID of the root node entry of the red-black tree of all storage members (if this entry is a + storage, ➜7.1), –1 otherwise + } + + AStream.ReadWord(); + + EntryType := AStream.ReadByte(); + EntryColor := AStream.ReadByte(); + + AStream.ReadDWord(); + AStream.ReadDWord(); + + AIsStorage := AStream.ReadDWord() <> $FFFFFFFF; + + {Root Storage #1 + 00000470H XX XX XX XX 03 00 00 00 40 03 00 00 00 00 00 00 + + Book #2 + 000004F0H XX XX XX XX 00 00 00 00 3F 03 00 00 00 00 00 00 + + Item #3 e #4 + 00000570H XX XX XX XX 00 00 00 00 00 00 00 00 00 00 00 00 + + First 4 bytes still with the timestamp. + + 116 4 SecID of first sector or short-sector, if this entry refers to a stream (➜7.2.2), + SecID of first sector of the short-stream container stream (➜6.1), + if this is the root storage entry, 0 otherwise + + 120 4 Total stream size in bytes, if this entry refers to a stream (➜7.2.2), + total size of the short-stream container stream (➜6.1), + if this is the root storage entry, 0 otherwise + + 124 4 Not used + } + + AStream.Seek(BaseAddr + $74, soFromBeginning); + + AFirstSecID := AStream.ReadDWord(); + + AStreamSize := AStream.ReadDWord(); + + AStream.ReadDWord(); +end; + +procedure TOLEStorage.ReadShortSectorAllocationTable(AStream: TStream); +begin + +end; + +procedure TOLEStorage.ReadUserStream(ADest, ASource: TStream); +begin + ADest.CopyFrom(ASource, FReadingStreamSize); +end; + constructor TOLEStorage.Create; begin inherited Create; @@ -487,6 +678,12 @@ begin inherited Destroy; end; +{@@ + Writes the OLE document specified in AOLEDocument + to the file with name AFileName. The routine will fail + if the file already exists, or if the directory where + it should be placed doesn't exist. +} procedure TOLEStorage.WriteOLEFile(AFileName: string; AOLEDocument: TOLEDocument); var cbWritten: Cardinal; @@ -555,5 +752,58 @@ begin {$endif} end; +{@@ + Reads an OLE file. Experimental +} +procedure TOLEStorage.ReadOLEFile(AFileName: string; + AOLEDocument: TOLEDocument); +var + AFileStream: TFileStream; + CurrentSectorPos: Int64; +begin + AOLEDocument.Stream := TMemoryStream.Create; + AFileStream := TFileStream.Create(AFileName, fmOpenRead); + try + // Header + ReadOLEHeader(AFileStream); + + // Record 0, the SAT + CurrentSectorPos := $200; + AFileStream.Seek(CurrentSectorPos, soFromBeginning); + ReadSectorAllocationTable(AFileStream); + + // Record 1, the directory stream + CurrentSectorPos := $400; + AFileStream.Seek(CurrentSectorPos, soFromBeginning); + ReadDirectoryStream(AFileStream); + + // FReadingStreamSize is filled by ReadDirectoryStream + FUseShortSectors := FReadingStreamSize < INT_OLE_MIN_SIZE_FOR_STANDARD_STREAMS; + + CurrentSectorPos := $600; + + // Record 2, the Short SAT, if exists + if FUseShortSectors then + begin + AFileStream.Seek(CurrentSectorPos, soFromBeginning); + ReadShortSectorAllocationTable(AFileStream); + CurrentSectorPos := $800; + end + else + CurrentSectorPos := $600; + + // Records 3 and on (or 2 and on without Short Sectors), the user data + AFileStream.Seek(CurrentSectorPos, soFromBeginning); + ReadUserStream(FOLEDocument.Stream, AFileStream); + finally + AFileStream.Free; + end; +end; + +procedure TOLEStorage.FreeOLEDocumentData(AOLEDocument: TOLEDocument); +begin + AOLEDocument.Stream.Free; +end; + end. diff --git a/components/fpspreadsheet/fpspreadsheet.pas b/components/fpspreadsheet/fpspreadsheet.pas index 33378bab5..e29ed1f6b 100755 --- a/components/fpspreadsheet/fpspreadsheet.pas +++ b/components/fpspreadsheet/fpspreadsheet.pas @@ -76,10 +76,13 @@ type type + TsCustomSpreadReader = class; TsCustomSpreadWriter = class; {@@ TsWorksheet } + { TsWorksheet } + TsWorksheet = class private procedure RemoveCallback(data, arg: pointer); @@ -92,6 +95,9 @@ type { Data manipulation methods } function FindCell(ARow, ACol: Cardinal): PCell; function GetCell(ARow, ACol: Cardinal): PCell; + function GetCellCount: Cardinal; + function GetCellByIndex(AIndex: Cardinal): PCell; + function ReadAsAnsiText(ARow, ACol: Cardinal): ansistring; procedure RemoveAllCells; procedure WriteAnsiText(ARow, ACol: Cardinal; AText: ansistring); procedure WriteNumber(ARow, ACol: Cardinal; ANumber: double); @@ -100,15 +106,22 @@ type {@@ TsWorkbook } + { TsWorkbook } + TsWorkbook = class private + { Internal data } FWorksheets: TFPList; + { Internal methods } procedure RemoveCallback(data, arg: pointer); public { Base methods } constructor Create; destructor Destroy; override; + function CreateSpreadReader(AFormat: TsSpreadsheetFormat): TsCustomSpreadReader; function CreateSpreadWriter(AFormat: TsSpreadsheetFormat): TsCustomSpreadWriter; + procedure ReadFromFile(AFileName: string; AFormat: TsSpreadsheetFormat); + procedure ReadFromStream(AStream: TStream; AFormat: TsSpreadsheetFormat); procedure WriteToFile(AFileName: string; AFormat: TsSpreadsheetFormat); procedure WriteToStream(AStream: TStream; AFormat: TsSpreadsheetFormat); { Worksheet list handling methods } @@ -125,6 +138,8 @@ type {@@ TsCustomSpreadReader } + { TsCustomSpreadReader } + TsCustomSpreadReader = class protected FWorkbook: TsWorkbook; @@ -132,7 +147,7 @@ type public { General writing methods } procedure ReadFromFile(AFileName: string; AData: TsWorkbook); virtual; - procedure ReadFromStream(AStream: TStream; AData: TsWorkbook); virtual; abstract; + procedure ReadFromStream(AStream: TStream; AData: TsWorkbook); virtual; { Record reading methods } procedure ReadFormula(AStream: TStream); virtual; abstract; procedure ReadLabel(AStream: TStream); virtual; abstract; @@ -145,13 +160,15 @@ type {@@ TsCustomSpreadWriter } + { TsCustomSpreadWriter } + TsCustomSpreadWriter = class public { General writing methods } procedure WriteCellCallback(data, arg: pointer); procedure WriteCellsToStream(AStream: TStream; ACells: TFPList); procedure WriteToFile(AFileName: string; AData: TsWorkbook); virtual; - procedure WriteToStream(AStream: TStream; AData: TsWorkbook); virtual; abstract; + procedure WriteToStream(AStream: TStream; AData: TsWorkbook); virtual; { Record writing methods } procedure WriteFormula(AStream: TStream; const ARow, ACol: Word; const AFormula: TRPNFormula); virtual; abstract; procedure WriteLabel(AStream: TStream; const ARow, ACol: Word; const AValue: string); virtual; abstract; @@ -176,6 +193,10 @@ procedure RegisterSpreadFormat( implementation +var + { Translatable strings } + lpUnsupportedReadFormat, lpUnsupportedWriteFormat: string; + {@@ Registers a new reader/writer pair for a format } @@ -293,6 +314,75 @@ begin end; end; +{@@ + Returns the number of cells in the worksheet with contents. + + This routine is used together with GetCellByIndex to + iterate througth all cells in a worksheet efficiently. + + @return The number of cells with contents in the worksheet + + @see TCell + @see GetCellByIndex +} +function TsWorksheet.GetCellCount: Cardinal; +begin + Result := FCells.Count; +end; + +{@@ + Obtains the cell with a specific index in the internal list of cells. + + The index goes from 0 to GetCellCount - 1. + + This routine is used together with GetCellCount to + iterate througth all cells in a worksheet efficiently. + + @param AIndex The index of the cell to be obtained + + @return A pointer to the cell, or nil if it doesn't exist + + @see TCell + @see GetCellCount +} +function TsWorksheet.GetCellByIndex(AIndex: Cardinal): PCell; +begin + if FCells.Count > AIndex then Result := PCell(FCells.Items[AIndex]) + else Result := nil; +end; + +{@@ + Reads the contents of a cell and converts it to a user readable text, + if it isn't already a text. + + @param ARow The row of the cell + @param ACol The column of the cell + + @return The text representation of the cell +} +function TsWorksheet.ReadAsAnsiText(ARow, ACol: Cardinal): ansistring; +var + ACell: PCell; +begin + ACell := FindCell(ARow, ACol); + + if ACell = nil then + begin + Result := ''; + Exit; + end; + + case ACell^.ContentType of + + //cctFormula + cctNumber: Result := FloatToStr(ACell^.NumberValue); + cctString: Result := ACell^.StringValue; + cctWideString: Result := ACell^.WideStringValue; + else + Result := ACell^.StringValue; + end; +end; + {@@ Clears the list of Cells and releases their memory. } @@ -375,6 +465,10 @@ begin inherited Create; FWorksheets := TFPList.Create; + + // In the future: add support for translations + lpUnsupportedReadFormat := 'Tryed to read a spreadsheet using an unsupported format'; + lpUnsupportedWriteFormat := 'Tryed to write a spreadsheet using an unsupported format'; end; {@@ @@ -389,6 +483,27 @@ begin inherited Destroy; end; +{@@ + Convenience method which creates the correct + reader object for a given spreadsheet format. +} +function TsWorkbook.CreateSpreadReader(AFormat: TsSpreadsheetFormat): TsCustomSpreadReader; +var + i: Integer; +begin + Result := nil; + + for i := 0 to Length(GsSpreadFormats) - 1 do + if GsSpreadFormats[i].Format = AFormat then + begin + Result := GsSpreadFormats[i].ReaderClass.Create; + + Break; + end; + + if Result = nil then raise Exception.Create(lpUnsupportedReadFormat); +end; + {@@ Convenience method which creates the correct writer object for a given spreadsheet format. @@ -407,7 +522,41 @@ begin Break; end; - if Result = nil then raise Exception.Create('Unsuported spreadsheet format.'); + if Result = nil then raise Exception.Create(lpUnsupportedWriteFormat); +end; + +{@@ + Reads the document from a file. +} +procedure TsWorkbook.ReadFromFile(AFileName: string; + AFormat: TsSpreadsheetFormat); +var + AReader: TsCustomSpreadReader; +begin + AReader := CreateSpreadReader(AFormat); + + try + AReader.ReadFromFile(AFileName, Self); + finally + AReader.Free; + end; +end; + +{@@ + Reads the document from a seekable stream. +} +procedure TsWorkbook.ReadFromStream(AStream: TStream; + AFormat: TsSpreadsheetFormat); +var + AReader: TsCustomSpreadReader; +begin + AReader := CreateSpreadReader(AFormat); + + try + AReader.ReadFromStream(AStream, Self); + finally + AReader.Free; + end; end; {@@ @@ -517,9 +666,34 @@ end; { TsCustomSpreadReader } -procedure TsCustomSpreadReader.ReadFromFile(AFileName: string; AData: TsWorkbook); -begin +{@@ + Default file reading method. + Opens the file and calls ReadFromStream + + @param AFileName The input file name. + @param AData The Workbook to be filled with information from the file. + + @see TsWorkbook +} +procedure TsCustomSpreadReader.ReadFromFile(AFileName: string; AData: TsWorkbook); +var + InputFile: TFileStream; +begin + InputFile := TFileStream.Create(AFileName, fmOpenRead); + try + ReadFromStream(InputFile, AData); + finally + InputFile.Free; + end; +end; + +{@@ + This routine should be overriden in descendent classes. +} +procedure TsCustomSpreadReader.ReadFromStream(AStream: TStream; AData: TsWorkbook); +begin + raise Exception.Create(lpUnsupportedReadFormat); end; { TsCustomSpreadWriter } @@ -580,6 +754,15 @@ begin end; end; +{@@ + This routine should be overriden in descendent classes. +} +procedure TsCustomSpreadWriter.WriteToStream(AStream: TStream; AData: TsWorkbook); +begin + raise Exception.Create(lpUnsupportedWriteFormat); + +end; + finalization SetLength(GsSpreadFormats, 0); diff --git a/components/fpspreadsheet/xlsbiff2.pas b/components/fpspreadsheet/xlsbiff2.pas index 61a2fd758..a15f5b754 100755 --- a/components/fpspreadsheet/xlsbiff2.pas +++ b/components/fpspreadsheet/xlsbiff2.pas @@ -33,6 +33,21 @@ uses type + { TsSpreadBIFF2Reader } + + TsSpreadBIFF2Reader = class(TsCustomSpreadReader) + private + RecordSize: Word; + FWorksheet: TsWorksheet; + public + { General reading methods } + procedure ReadFromStream(AStream: TStream; AData: TsWorkbook); override; + { Record writing methods } + procedure ReadFormula(AStream: TStream); override; + procedure ReadLabel(AStream: TStream); override; + procedure ReadNumber(AStream: TStream); override; + end; + { TsSpreadBIFF2Writer } TsSpreadBIFF2Writer = class(TsCustomSpreadWriter) @@ -274,15 +289,108 @@ begin AStream.WriteBuffer(AValue, 8); end; +{ TsSpreadBIFF2Reader } + +procedure TsSpreadBIFF2Reader.ReadFromStream(AStream: TStream; AData: TsWorkbook); +var + BIFF2EOF: Boolean; + RecordType: Word; + CurStreamPos: Int64; +begin + BIFF2EOF := False; + + { In BIFF2 files there is only one worksheet, let's create it } + FWorksheet := AData.AddWorksheet(''); + + { Read all records in a loop } + while not BIFF2EOF do + begin + { Read the record header } + RecordType := AStream.ReadWord; + RecordSize := AStream.ReadWord; + + CurStreamPos := AStream.Position; + + case RecordType of + + INT_EXCEL_ID_NUMBER: ReadNumber(AStream); + INT_EXCEL_ID_LABEL: ReadLabel(AStream); + INT_EXCEL_ID_FORMULA: ReadFormula(AStream); + INT_EXCEL_ID_BOF: ; + INT_EXCEL_ID_EOF: BIFF2EOF := True; + else + // nothing + end; + + // Make sure we are in the right position for the next record + AStream.Seek(CurStreamPos + RecordSize, soFromBeginning); + + if AStream.Position >= AStream.Size then BIFF2EOF := True; + end; +end; + +procedure TsSpreadBIFF2Reader.ReadFormula(AStream: TStream); +begin + +end; + +procedure TsSpreadBIFF2Reader.ReadLabel(AStream: TStream); +var + L: Byte; + ARow, ACol: Word; + AValue: array[0..255] of Char; + AStrValue: ansistring; +begin + { BIFF Record data } + ARow := AStream.ReadWord(); + ACol := AStream.ReadWord(); + + { BIFF2 Attributes } + AStream.ReadByte(); + AStream.ReadByte(); + AStream.ReadByte(); + + { String with 8-bit size } + L := AStream.ReadByte(); + AStream.ReadBuffer(AValue, L); + AValue[L] := #0; + AStrValue := AValue; + + { Save the data } + FWorksheet.WriteAnsiText(ARow, ACol, AStrValue); +end; + +procedure TsSpreadBIFF2Reader.ReadNumber(AStream: TStream); +var + ARow, ACol: Word; + AValue: Double; +begin + { BIFF Record data } + ARow := AStream.ReadWord(); + ACol := AStream.ReadWord(); + + { BIFF2 Attributes } + AStream.ReadByte(); + AStream.ReadByte(); + AStream.ReadByte(); + + { IEE 754 floating-point value } + AStream.ReadBuffer(AValue, 8); + + { Save the data } + FWorksheet.WriteNumber(ARow, ACol, AValue); +end; + {******************************************************************* * Initialization section * * Registers this reader / writer on fpSpreadsheet * *******************************************************************} + initialization - RegisterSpreadFormat(TsCustomSpreadReader, TsSpreadBIFF2Writer, sfExcel2); + RegisterSpreadFormat(TsSpreadBIFF2Reader, TsSpreadBIFF2Writer, sfExcel2); end.