You've already forked lazarus-ccr
fpspreadsheet: Improves reading excel 5 files
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@658 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -34,13 +34,13 @@
|
||||
<PackageName Value="laz_fpspreadsheet"/>
|
||||
</Item1>
|
||||
</RequiredPackages>
|
||||
<Units Count="13">
|
||||
<Units Count="15">
|
||||
<Unit0>
|
||||
<Filename Value="excel5read.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="excel5read"/>
|
||||
<CursorPos X="16" Y="38"/>
|
||||
<TopLine Value="30"/>
|
||||
<CursorPos X="20" Y="30"/>
|
||||
<TopLine Value="21"/>
|
||||
<EditorIndex Value="0"/>
|
||||
<UsageCount Value="309"/>
|
||||
<Loaded Value="True"/>
|
||||
@ -69,8 +69,8 @@
|
||||
<Unit4>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<UnitName Value="xlsbiff5"/>
|
||||
<CursorPos X="1" Y="910"/>
|
||||
<TopLine Value="904"/>
|
||||
<CursorPos X="53" Y="913"/>
|
||||
<TopLine Value="903"/>
|
||||
<EditorIndex Value="3"/>
|
||||
<UsageCount Value="140"/>
|
||||
<Loaded Value="True"/>
|
||||
@ -78,8 +78,8 @@
|
||||
<Unit5>
|
||||
<Filename Value="..\..\fpsutils.pas"/>
|
||||
<UnitName Value="fpsutils"/>
|
||||
<CursorPos X="1" Y="49"/>
|
||||
<TopLine Value="30"/>
|
||||
<CursorPos X="16" Y="10"/>
|
||||
<TopLine Value="1"/>
|
||||
<EditorIndex Value="2"/>
|
||||
<UsageCount Value="140"/>
|
||||
<Loaded Value="True"/>
|
||||
@ -117,10 +117,10 @@
|
||||
<Unit10>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<UnitName Value="fpspreadsheet"/>
|
||||
<CursorPos X="47" Y="149"/>
|
||||
<TopLine Value="133"/>
|
||||
<CursorPos X="5" Y="181"/>
|
||||
<TopLine Value="171"/>
|
||||
<EditorIndex Value="1"/>
|
||||
<UsageCount Value="92"/>
|
||||
<UsageCount Value="94"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit10>
|
||||
<Unit11>
|
||||
@ -135,127 +135,141 @@
|
||||
<TopLine Value="144"/>
|
||||
<UsageCount Value="10"/>
|
||||
</Unit12>
|
||||
<Unit13>
|
||||
<Filename Value="..\..\..\..\..\lazarus\lcl\stdctrls.pp"/>
|
||||
<UnitName Value="StdCtrls"/>
|
||||
<CursorPos X="19" Y="665"/>
|
||||
<TopLine Value="662"/>
|
||||
<UsageCount Value="10"/>
|
||||
</Unit13>
|
||||
<Unit14>
|
||||
<Filename Value="..\..\..\..\..\lazarus\lcl\controls.pp"/>
|
||||
<UnitName Value="Controls"/>
|
||||
<CursorPos X="20" Y="1513"/>
|
||||
<TopLine Value="1508"/>
|
||||
<UsageCount Value="10"/>
|
||||
</Unit14>
|
||||
</Units>
|
||||
<JumpHistory Count="30" HistoryIndex="29">
|
||||
<Position1>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="119" Column="67" TopLine="108"/>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="895" Column="1" TopLine="885"/>
|
||||
</Position1>
|
||||
<Position2>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="485" Column="42" TopLine="474"/>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="908" Column="1" TopLine="898"/>
|
||||
</Position2>
|
||||
<Position3>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="161" Column="3" TopLine="159"/>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="910" Column="1" TopLine="900"/>
|
||||
</Position3>
|
||||
<Position4>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="141" Column="3" TopLine="139"/>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="913" Column="1" TopLine="903"/>
|
||||
</Position4>
|
||||
<Position5>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="669" Column="20" TopLine="658"/>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="911" Column="1" TopLine="900"/>
|
||||
</Position5>
|
||||
<Position6>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="158" Column="15" TopLine="143"/>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="912" Column="1" TopLine="902"/>
|
||||
</Position6>
|
||||
<Position7>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="116" Column="71" TopLine="106"/>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="915" Column="1" TopLine="905"/>
|
||||
</Position7>
|
||||
<Position8>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="886" Column="1" TopLine="876"/>
|
||||
<Caret Line="918" Column="1" TopLine="908"/>
|
||||
</Position8>
|
||||
<Position9>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="888" Column="1" TopLine="878"/>
|
||||
<Caret Line="919" Column="1" TopLine="909"/>
|
||||
</Position9>
|
||||
<Position10>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="891" Column="1" TopLine="881"/>
|
||||
<Caret Line="921" Column="1" TopLine="911"/>
|
||||
</Position10>
|
||||
<Position11>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="894" Column="1" TopLine="884"/>
|
||||
<Caret Line="923" Column="1" TopLine="913"/>
|
||||
</Position11>
|
||||
<Position12>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="895" Column="1" TopLine="885"/>
|
||||
<Caret Line="918" Column="1" TopLine="908"/>
|
||||
</Position12>
|
||||
<Position13>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="897" Column="1" TopLine="887"/>
|
||||
<Caret Line="921" Column="1" TopLine="911"/>
|
||||
</Position13>
|
||||
<Position14>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="899" Column="1" TopLine="889"/>
|
||||
<Caret Line="913" Column="3" TopLine="919"/>
|
||||
</Position14>
|
||||
<Position15>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="904" Column="14" TopLine="895"/>
|
||||
<Caret Line="924" Column="1" TopLine="914"/>
|
||||
</Position15>
|
||||
<Position16>
|
||||
<Filename Value="..\..\fpolestorage.pas"/>
|
||||
<Caret Line="768" Column="1" TopLine="765"/>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="926" Column="1" TopLine="916"/>
|
||||
</Position16>
|
||||
<Position17>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="886" Column="1" TopLine="876"/>
|
||||
<Caret Line="918" Column="1" TopLine="910"/>
|
||||
</Position17>
|
||||
<Position18>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="888" Column="1" TopLine="878"/>
|
||||
<Caret Line="886" Column="1" TopLine="867"/>
|
||||
</Position18>
|
||||
<Position19>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="891" Column="1" TopLine="881"/>
|
||||
<Caret Line="889" Column="1" TopLine="876"/>
|
||||
</Position19>
|
||||
<Position20>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="886" Column="1" TopLine="867"/>
|
||||
<Caret Line="68" Column="24" TopLine="58"/>
|
||||
</Position20>
|
||||
<Position21>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="894" Column="1" TopLine="882"/>
|
||||
<Caret Line="887" Column="1" TopLine="882"/>
|
||||
</Position21>
|
||||
<Position22>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="64" Column="41" TopLine="60"/>
|
||||
<Caret Line="64" Column="37" TopLine="55"/>
|
||||
</Position22>
|
||||
<Position23>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="70" Column="24" TopLine="60"/>
|
||||
<Caret Line="934" Column="5" TopLine="915"/>
|
||||
</Position23>
|
||||
<Position24>
|
||||
<Filename Value="..\..\fpolestorage.pas"/>
|
||||
<Caret Line="797" Column="16" TopLine="784"/>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="941" Column="23" TopLine="925"/>
|
||||
</Position24>
|
||||
<Position25>
|
||||
<Filename Value="..\..\fpolestorage.pas"/>
|
||||
<Caret Line="670" Column="37" TopLine="655"/>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="72" Column="25" TopLine="62"/>
|
||||
</Position25>
|
||||
<Position26>
|
||||
<Filename Value="..\..\fpolestorage.pas"/>
|
||||
<Caret Line="666" Column="13" TopLine="659"/>
|
||||
<Filename Value="..\..\fpspreadsheet.pas"/>
|
||||
<Caret Line="499" Column="45" TopLine="486"/>
|
||||
</Position26>
|
||||
<Position27>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="895" Column="1" TopLine="885"/>
|
||||
<Caret Line="948" Column="1" TopLine="946"/>
|
||||
</Position27>
|
||||
<Position28>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="908" Column="1" TopLine="898"/>
|
||||
<Caret Line="994" Column="12" TopLine="981"/>
|
||||
</Position28>
|
||||
<Position29>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="910" Column="1" TopLine="900"/>
|
||||
<Caret Line="891" Column="1" TopLine="872"/>
|
||||
</Position29>
|
||||
<Position30>
|
||||
<Filename Value="..\..\xlsbiff5.pas"/>
|
||||
<Caret Line="913" Column="1" TopLine="903"/>
|
||||
<Caret Line="70" Column="15" TopLine="60"/>
|
||||
</Position30>
|
||||
</JumpHistory>
|
||||
</ProjectOptions>
|
||||
@ -270,12 +284,4 @@
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<BreakPoints Count="1">
|
||||
<Item1>
|
||||
<Source Value="..\..\xlsbiff5.pas"/>
|
||||
<Line Value="910"/>
|
||||
</Item1>
|
||||
</BreakPoints>
|
||||
</Debugging>
|
||||
</CONFIG>
|
||||
|
@ -65,6 +65,11 @@ type
|
||||
private
|
||||
RecordSize: Word;
|
||||
FWorksheet: TsWorksheet;
|
||||
FWorksheetNames: TStringList;
|
||||
FCurrentWorksheet: Integer;
|
||||
procedure ReadWorkbookGlobals(AStream: TStream; AData: TsWorkbook);
|
||||
procedure ReadWorksheet(AStream: TStream; AData: TsWorkbook);
|
||||
procedure ReadBoundsheet(AStream: TStream);
|
||||
public
|
||||
{ General reading methods }
|
||||
procedure ReadFromFile(AFileName: string; AData: TsWorkbook); override;
|
||||
@ -878,6 +883,96 @@ end;
|
||||
|
||||
{ TsSpreadBIFF5Reader }
|
||||
|
||||
procedure TsSpreadBIFF5Reader.ReadWorkbookGlobals(AStream: TStream;
|
||||
AData: TsWorkbook);
|
||||
var
|
||||
SectionEOF: Boolean = False;
|
||||
RecordType: Word;
|
||||
CurStreamPos: Int64;
|
||||
begin
|
||||
while (not SectionEOF) do
|
||||
begin
|
||||
{ Read the record header }
|
||||
RecordType := WordLEToN(AStream.ReadWord);
|
||||
RecordSize := WordLEToN(AStream.ReadWord);
|
||||
|
||||
CurStreamPos := AStream.Position;
|
||||
|
||||
case RecordType of
|
||||
INT_EXCEL_ID_BOF: ;
|
||||
INT_EXCEL_ID_BOUNDSHEET: ReadBoundSheet(AStream);
|
||||
INT_EXCEL_ID_EOF: SectionEOF := True;
|
||||
else
|
||||
// nothing
|
||||
end;
|
||||
|
||||
// Make sure we are in the right position for the next record
|
||||
AStream.Seek(CurStreamPos + RecordSize, soFromBeginning);
|
||||
|
||||
// Check for the end of the file
|
||||
if AStream.Position >= AStream.Size then SectionEOF := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadBIFF5Reader.ReadWorksheet(AStream: TStream; AData: TsWorkbook);
|
||||
var
|
||||
SectionEOF: Boolean = False;
|
||||
RecordType: Word;
|
||||
CurStreamPos: Int64;
|
||||
begin
|
||||
FWorksheet := AData.AddWorksheet(FWorksheetNames.Strings[FCurrentWorksheet]);
|
||||
|
||||
while (not SectionEOF) do
|
||||
begin
|
||||
{ Read the record header }
|
||||
RecordType := WordLEToN(AStream.ReadWord);
|
||||
RecordSize := WordLEToN(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: SectionEOF := True;
|
||||
else
|
||||
// nothing
|
||||
end;
|
||||
|
||||
// Make sure we are in the right position for the next record
|
||||
AStream.Seek(CurStreamPos + RecordSize, soFromBeginning);
|
||||
|
||||
// Check for the end of the file
|
||||
if AStream.Position >= AStream.Size then SectionEOF := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TsSpreadBIFF5Reader.ReadBoundsheet(AStream: TStream);
|
||||
var
|
||||
Len: Byte;
|
||||
Str: array[0..255] of Char;
|
||||
begin
|
||||
{ Absolute stream position of the BOF record of the sheet represented
|
||||
by this record }
|
||||
// Just assume that they are in order
|
||||
AStream.ReadDWord();
|
||||
|
||||
{ Visibility }
|
||||
AStream.ReadByte();
|
||||
|
||||
{ Sheet type }
|
||||
AStream.ReadByte();
|
||||
|
||||
{ Sheet name: Byte string, 8-bit length }
|
||||
Len := AStream.ReadByte();
|
||||
AStream.ReadBuffer(Str, Len);
|
||||
Str[Len] := #0;
|
||||
|
||||
FWorksheetNames.Add(Str);
|
||||
end;
|
||||
|
||||
procedure TsSpreadBIFF5Reader.ReadFromFile(AFileName: string; AData: TsWorkbook);
|
||||
var
|
||||
MemStream: TMemoryStream;
|
||||
@ -895,6 +990,9 @@ begin
|
||||
// Rewind the stream and read from it
|
||||
MemStream.Position := 0;
|
||||
ReadFromStream(MemStream, AData);
|
||||
|
||||
// Uncomment to verify if the data was correctly optained from the OLE file
|
||||
// MemStream.SaveToFile(SysUtils.ChangeFileExt(AFileName, 'bin.xls'));
|
||||
finally
|
||||
MemStream.Free;
|
||||
OLEStorage.Free;
|
||||
@ -904,38 +1002,37 @@ end;
|
||||
procedure TsSpreadBIFF5Reader.ReadFromStream(AStream: TStream; AData: TsWorkbook);
|
||||
var
|
||||
BIFF5EOF: Boolean;
|
||||
RecordType: Word;
|
||||
CurStreamPos: Int64;
|
||||
begin
|
||||
{ Initializations }
|
||||
|
||||
FWorksheetNames := TStringList.Create;
|
||||
FWorksheetNames.Clear;
|
||||
FCurrentWorksheet := 0;
|
||||
BIFF5EOF := False;
|
||||
|
||||
FWorksheet := AData.AddWorksheet('');
|
||||
{ Read workbook globals }
|
||||
|
||||
{ Read all records in a loop }
|
||||
while not BIFF5EOF do
|
||||
ReadWorkbookGlobals(AStream, AData);
|
||||
|
||||
// Check for the end of the file
|
||||
if AStream.Position >= AStream.Size then BIFF5EOF := True;
|
||||
|
||||
{ Now read all worksheets }
|
||||
|
||||
while (not BIFF5EOF) do
|
||||
begin
|
||||
{ Read the record header }
|
||||
RecordType := WordLEToN(AStream.ReadWord);
|
||||
RecordSize := WordLEToN(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: BIFF5EOF := True;
|
||||
else
|
||||
// nothing
|
||||
end;
|
||||
|
||||
// Make sure we are in the right position for the next record
|
||||
AStream.Seek(CurStreamPos + RecordSize, soFromBeginning);
|
||||
ReadWorksheet(AStream, AData);
|
||||
|
||||
// Check for the end of the file
|
||||
if AStream.Position >= AStream.Size then BIFF5EOF := True;
|
||||
|
||||
// Final preparations
|
||||
Inc(FCurrentWorksheet);
|
||||
end;
|
||||
|
||||
{ Finalizations }
|
||||
|
||||
FWorksheetNames.Free;
|
||||
end;
|
||||
|
||||
procedure TsSpreadBIFF5Reader.ReadFormula(AStream: TStream);
|
||||
|
Reference in New Issue
Block a user