unit XLSReadII2;
{
********************************************************************************
******* XLSReadWriteII V2.00 *******
******* *******
******* Copyright(C) 1999,2004 Lars Arvidsson, Axolot Data *******
******* *******
******* email: [email protected] *******
******* URL: http://www.axolot.com *******
********************************************************************************
** Users of the XLSReadWriteII component must accept the following **
** disclaimer of warranty: **
** **
** XLSReadWriteII is supplied as is. The author disclaims all warranties, **
** expressedor implied, including, without limitation, the warranties of **
** merchantability and of fitness for any purpose. The author assumes no **
** liability for damages, direct or consequential, which may result from the **
** use of XLSReadWriteII. **
********************************************************************************
}
{$B-}
{$R-}
interface
uses Classes, SysUtils, Windows, Messages, BIFFRecsII2, CellFormats2, SheetData2,
XLSStream2, XLSReadWriteII2, XLSUtils2, Dialogs, DecodeFormula2,
XLSFonts2, ExcelMaskII2, Validate2, Math, XLSRWIIResourceStrings2,
RecordStorage2, Escher2, MergedCells2;
type TSharedFormula = record
Row1,Row2: word;
Col1,Col2: byte;
Len: word;
Formula: PByteArray;
end;
type TXLSReadII = class(TObject)
protected
PBuf: PByteArray;
FXLS: TXLSReadWriteII2;
FCurrSheet: integer;
FXLSStream: TXLSStream;
FBoundsheets: TStringList;
FBoundsheetIndex: integer;
Header: TBIFFHeader;
FSharedFormulas: array of TSharedFormula;
CurrRecs: TRecordStorage;
InsertRecord: boolean;
// File prefix
procedure RREC_FILEPASS;
procedure RREC_INTERFACEHDR;
procedure RREC_ADDMENU;
procedure RREC_DELMENU;
procedure RREC_INTERFACEEND;
procedure RREC_WRITEACCESS;
procedure RREC_CODEPAGE;
procedure RREC_DSF;
procedure RREC_FNGROUPCOUNT;
procedure RREC_WINDOWPROTECT;
procedure RREC_PROTECT;
procedure RREC_PASSWORD;
procedure RREC_PROT4REV;
procedure RREC_PROT4REVPASS;
procedure RREC_WINDOW1;
procedure RREC_BACKUP;
procedure RREC_HIDEOBJ;
procedure RREC_1904;
procedure RREC_PRECISION;
procedure RREC_REFRESHALL;
procedure RREC_BOOKBOOL;
procedure RREC_PALETTE;
procedure RREC_FONT;
procedure RREC_FORMAT;
procedure RREC_XF;
procedure RREC_STYLE;
procedure RREC_NAME;
procedure RREC_SUPBOOK;
procedure RREC_EXTERNNAME;
procedure RREC_XCT;
procedure RREC_EXTERNCOUNT;
procedure RREC_EXTERNSHEET;
procedure RREC_USESELFS;
procedure RREC_BOUNDSHEET;
procedure RREC_COUNTRY;
procedure RREC_RECALCID;
procedure RREC_MSODRAWINGGROUP;
procedure RREC_SST;
procedure RREC_EXTSST;
procedure RREC_EOF;
// Sheet prefix
procedure RREC_CALCMODE;
procedure RREC_CALCCOUNT;
procedure RREC_REFMODE;
procedure RREC_ITERATION;
procedure RREC_DELTA;
procedure RREC_SAVERECALC;
procedure RREC_PRINTHEADERS;
procedure RREC_PRINTGRIDLINES;
procedure RREC_GRIDSET;
procedure RREC_GUTS;
procedure RREC_DEFAULTROWHEIGHT;
procedure RREC_WSBOOL;
procedure RREC_HORIZONTALPAGEBREAKS;
procedure RREC_VERTICALPAGEBREAKS;
procedure RREC_HEADER;
procedure RREC_FOOTER;
procedure RREC_HCENTER;
procedure RREC_VCENTER;
procedure RREC_PLS;
procedure RREC_SETUP;
procedure RREC_LEFTMARGIN;
procedure RREC_RIGHTMARGIN;
procedure RREC_TOPMARGIN;
procedure RREC_BOTTOMMARGIN;
procedure RREC_DEFCOLWIDTH;
procedure RREC_COLINFO;
procedure RREC_DIMENSIONS;
// Sheet data
procedure RREC_INTEGER_20;
procedure RREC_NUMBER_20;
procedure RREC_LABEL_20;
procedure RREC_ROW;
procedure RREC_BLANK;
procedure RREC_BOOLERR;
procedure RREC_FORMULA;
procedure RREC_FORMULA_30;
procedure RREC_NUMBER;
procedure RREC_RK;
procedure RREC_MULRK;
procedure RREC_MULBLANK;
procedure RREC_LABELSST;
procedure RREC_LABEL;
procedure RREC_RSTRING;
procedure RREC_NOTE;
procedure READ_SHRFMLA;
// Sheet suffix
procedure RREC_MSODRAWING;
procedure RREC_MSODRAWINGSELECTION;
procedure RREC_WINDOW2;
procedure RREC_SCL;
procedure RREC_PANE;
procedure RREC_SELECTION;
procedure RREC_DVAL;
procedure RREC_MERGEDCELLS;
procedure RREC_CONDFMT;
procedure RREC_HLINK;
procedure Clear;
procedure ClearSharedFmla;
procedure ReadFormulaVal(Col,Row,FormatIndex: integer; Value: double; Formula: PByteArray; Len: integer);
procedure FixupSharedFormula(ACol,ARow: integer);
public
constructor Create(XLS: TXLSReadWriteII2);
destructor Destroy; override;
procedure LoadFromStream(Stream: TStream);
end;
implementation
constructor TXLSReadII.Create(XLS: TXLSReadWriteII2);
begin
FXLS := XLS;
FXLSStream := TXLSStream.Create;
FXLSStream.SaveVBA := XLS.PreserveMacros;
FBoundsheets := TStringList.Create;
end;
destructor TXLSReadII.Destroy;
begin
FXLSStream.Free;
FBoundsheets.Free;
ClearSharedFmla;
inherited Destroy;
end;
procedure TXLSReadII.Clear;
begin
FCurrSheet := -1;
FBoundsheets.Clear;
FBoundsheetIndex := -1;
end;
procedure TXLSReadII.ClearSharedFmla;
var
i: integer;
begin
for i := 0 to High(FSharedFormulas) do
FreeMem(FSharedFormulas[i].Formula);
SetLength(FSharedFormulas,0);
end;
procedure TXLSReadII.LoadFromStream(Stream: TStream);
var
ProgressCount: integer;
Count: integer;
InUSERSVIEW: boolean;
begin
InUSERSVIEW := False;
Count := 0;
Clear;
FXLS.WriteDefaultData := False;
try
FXLSStream.ExtraObjects := FXLS.ExtraObjects;
FXLSStream.SourceStream := Stream;
FXLS.Version := FXLSStream.OpenRead(FXLS.Filename);
GetMem(PBuf,FXLS.MaxBuffsize);
CurrRecs := FXLS.Records;
ProgressCount := 0;
if Assigned(FXLS.OnProgress) then
FXLS.OnProgress(Self,0);
try
while FXLSStream.ReadHeader(Header) = SizeOf(TBIFFHeader) do begin
if Header.Length > FXLS.MaxBuffsize then begin
// Invalid record sizer
FXLSStream.Seek(Header.Length,soFromCurrent);
Continue;
end
else if (Header.RecID and INTERNAL_PLACEHOLDER) <> 0 then
raise Exception.Create('Bad record in file')
else if ((Header.RecID and $FF) <> BIFFRECID_BOF) and (Header.RecId <> BIFFRECID_SST) and (Header.RecId <> BIFFRECID_MSODRAWINGGROUP) and (Header.RecId <> BIFFRECID_MSODRAWING) then begin
FXLSStream.Read(PBuf^,Header.Length);
{
if FXLSStream.IsEncrypted and (Header.Length > 0) then
FXLSStream.Decrypt(PBuf,Header.Length);
}
end;
Inc(ProgressCount);
if ProgressCount >= 100 then begin
if Assigned(FXLS.OnProgress) then
FXLS.OnProgress(Self,Round((FXLSStream.Pos / FXLSStream.Size) * 100));
ProgressCount := 0;
end;
// if ((Header.RecID and $FF) <> BIFFRECID_BOF) and (Header.RecID <> BIFFRECID_EXCEL9FILE) then
// CurrRecs.Add(Header,PBuf);
if InUSERSVIEW then begin
if Header.RecID = BIFFRECID_USERSVIEWEND then
InUSERSVIEW := False;
Continue;
end;
InsertRecord := True;
case Header.RecID of
BIFFRECID_EOF: begin
CurrRecs.UpdateDefault(Header,PBuf);
InsertRecord := False;
ClearSharedFmla;
if (FBoundsheets.Count = 0) or (FBoundsheetIndex >= (FBoundsheets.Count - 1)) then begin
Break;
end;
end;
// File prefix
// BIFFRECID_OBPROJ: InsertRecord := False;
BIFFRECID_EXCEL9FILE: InsertRecord := False;
BIFFRECID_FILEPASS: RREC_FILEPASS;
BIFFRECID_INTERFACEHDR: RREC_INTERFACEHDR;
BIFFRECID_INTERFACEEND: RREC_INTERFACEEND;
BIFFRECID_WRITEACCESS: RREC_WRITEACCESS;
BIFFRECID_CODEPAGE: RREC_CODEPAGE;
BIFFRECID_DSF: RREC_DSF;
BIFFRECID_FNGROUPCOUNT: RREC_FNGROUPCOUNT;
BIFFRECID_WINDOWPROTECT: RREC_WINDOWPROTECT;
BIFFRECID_PROTECT: RREC_PROTECT;
BIFFRECID_PASSWORD: RREC_PASSWORD;
BIFFRECID_PROT4REV: RREC_PROT4REV;
BIFFRECID_PROT4REVPASS: RREC_PROT4REVPASS;
BIFFRECID_WINDOW1: RREC_WINDOW1;
BIFFRECID_BACKUP: RREC_BACKUP;
BIFFRECID_HIDEOBJ: RREC_HIDEOBJ;
BIFFRECID_1904: RREC_1904;
BIFFRECID_PRECISION: RREC_PRECISION;
BIFFRECID_REFRESHALL: RREC_REFRESHALL;
BIFFRECID_BOOKBOOL: RREC_BOOKBOOL;
BIFFRECID_PALETTE: RREC_PALETTE;
BIFFRECID_FONT,$0231: RREC_FONT;
BIFFRECID_FORMAT: RREC_FORMAT;
BIFFRECID_XF_30,
BIFFRECID_XF_40,
BIFFRECID_XF: RREC_XF;
// STYLE (inbyggda) m錽te finnas, annars s� fungerar inte "style"
// knapparna i Excel.
// BIFFRECID_STYLE: RREC_STYLE;
BIFFRECID_NAME,$0218: RREC_NAME;
BIFFRECID_SUPBOOK: RREC_SUPBOOK;
BIFFRECID_EXTERNNAME,$0223: RREC_EXTERNNAME;
BIFFRECID_XCT: RREC_XCT;
BIFFRECID_EXTERNCOUNT: RREC_EXTERNCOUNT;
BIFFRECID_EXTERNSHEET: RREC_EXTERNSHEET;
BIFFRECID_USESELFS: RREC_USESELFS;
BIFFRECID_BOUNDSHEET: RREC_BOUNDSHEET;
BIFFRECID_COUNTRY: RREC_COUNTRY;
BIFFRECID_RECALCID: RREC_RECALCID;
BIFFRECID_MSODRAWINGGROUP: RREC_MSODRAWINGGROUP;
BIFFRECID_SST: RREC_SST;
BIFFRECID_EXTSST: RREC_EXTSST;
// Sheet prefix
BIFFRECID_CALCMODE: RREC_CALCMODE;
BIFFRECID_CALCCOUNT: RREC_CALCCOUNT;
BIFFRECID_REFMODE: RREC_REFMODE;
BIFFRECID_ITERATION: RREC_ITERATION;
BIFFRECID_DELTA: RREC_DELTA;
BIFFRECID_SAVERECALC: RREC_SAVERECALC;
BIFFRECID_PRINTHEADERS: RREC_PRINTHEADERS;
BIFFRECID_PRINTGRIDLINES: RREC_PRINTGRIDLINES;
BIFFRECID_GRIDSET: RREC_GRIDSET;
BIFFRECID_GUTS: RREC_GUTS;
BIFFRECID_DEFAULTROWHEIGHT: RREC_DEFAULTROWHEIGHT;
BIFFRECID_WSBOOL: RREC_WSBOOL;
BIFFRECID_HORIZONTALPAGEBREAKS:RREC_HORIZONTALPAGEBREAKS;
BIFFRECID_VERTICALPAGEBREAKS: RREC_VERTICALPAGEBREAKS;
BIFFRECID_HEADER: RREC_HEADER;
BIFFRECID_FOOTER: RREC_FOOTER;
BIFFRECID_HCENTER: RREC_HCENTER;
BIFFRECID_VCENTER: RREC_VCENTER;
BIFFRECID_PLS: RREC_PLS;
BIFFRECID_SETUP: RREC_SETUP;
BIFFRECID_LEFTMARGIN: RREC_LEFTMARGIN;
BIFFRECID_RIGHTMARGIN: RREC_RIGHTMARGIN;
BIFFRECID_TOPMARGIN: RREC_TOPMARGIN;
BIFFRECID_BOTTOMMARGIN: RREC_BOTTOMMARGIN;
BIFFRECID_DEFCOLWIDTH: RREC_DEFCOLWIDTH;
BIFFRECID_COLINFO: RREC_COLINFO;
BIFFRECID_DIMENSIONS_20,
BIFFRECID_DIMENSIONS: RREC_DIMENSIONS;
// Sheet cells/data
BIFFRECID_INDEX: InsertRecord := False;
BIFFRECID_DBCELL: InsertRecord := False;
BIFFRECID_INTEGER_20: RREC_INTEGER_20;
BIFFRECID_NUMBER_20: RREC_NUMBER_20;
BIFFRECID_LABEL_20: RREC_LABEL_20;
BIFFRECID_ROW: RREC_ROW;
BIFFRECID_BLANK: RREC_BLANK;
BIFFRECID_BOOLERR: RREC_BOOLERR;
BIFFRECID_FORMULA: RREC_FORMULA;
BIFFRECID_FORMULA_30,
BIFFRECID_FORMULA_40: RREC_FORMULA_30;
BIFFRECID_MULBLANK: RREC_MULBLANK;
BIFFRECID_RK,
BIFFRECID_RK7: RREC_RK;
BIFFRECID_MULRK: RREC_MULRK;
BIFFRECID_NUMBER: RREC_NUMBER;
BIFFRECID_LABELSST: RREC_LABELSST;
BIFFRECID_LABEL: RREC_LABEL;
BIFFRECID_RSTRING: RREC_RSTRING;
BIFFRECID_NOTE: RREC_NOTE;
// Sheet suffix
BIFFRECID_MSODRAWING: RREC_MSODRAWING;
BIFFRECID_MSODRAWINGSELECTION: RREC_MSODRAWINGSELECTION;
BIFFRECID_WINDOW2: RREC_WINDOW2;
{
BIFFRECID_SCL: RREC_SCL;
}
BIFFRECID_PANE: RREC_PANE;
BIFFRECID_SELECTION: RREC_SELECTION;
BIFFRECID_MERGEDCELLS: RREC_MERGEDCELLS;
BIFFRECID_CONDFMT: RREC_CONDFMT;
BIFFRECID_HLINK: RREC_HLINK;
BIFFRECID_DVAL: RREC_DVAL;
BIFFRECID_USERBVIEW: InsertRecord := False;
BIFFRECID_USERSVIEWBEGIN: begin
InsertRecord := False;
InUSERSVIEW := True;
end;
else begin
if (Header.RecID and $FF) = BIFFRECID_BOF then begin
FXLSStream.ReadUnencrypted(PBuf^,Header.Length);
InsertRecord := False;
case PRecBOF8(PBuf).SubStreamType of
$0005: begin // Workbook globals
if Header.Length > 256 then
raise Exception.Create(ersInvalidBOFSize);
if PRecBOF8(PBuf).SubStreamType = $0010 then
FXLS.IsMac := (FXLS.Version >= xvExcel97) and ((PRecBOF8(PBuf).FileHistoryFlags and $00000010) = $00000010);
CurrRecs := FXLS.Records;
CurrRecs.UpdateDefault(Header,PBuf);
end;
$0006: begin // VB Module
raise Exception.Create('VB module unhandled');
end;
$0010: begin // Worksheet
Inc(FBoundsheetIndex);
Inc(FCurrSheet);
FXLS.Sheets.Add;
FXLS.Sheets[FCurrSheet].Name := ExcelStrToWideString(FBoundsheets[FBoundsheetIndex]);
FXLS.Sheets[FCurrSheet].HasDefaultRecords := True;
CurrRecs := FXLS.Sheets[FCurrSheet].Records;
CurrRecs.UpdateDefault(Header,PBuf);
end;
$0020: begin // Chart
Inc(FBoundsheetIndex);
FXLS.SheetCharts.LoadFromStream(FXLSStream,ExcelStrToWideString(FBoundsheets[FBoundsheetIndex]),PBuf,FXLS.Fonts,FBoundsheetIndex);
//raise Exception.Create('Chart unhandled');
end;
$0040: begin // BIFF4 Macro sheet
raise Exception.Create('BIFF4 Macro unhandled');
end;
$0100: begin // BIFF4 Workbook globals
raise Exception.Create('BIFF4 Workbook unhandled');
end;
end;
end
end;
end;
if InsertRecord then
CurrRecs.AddRec(Header,PBuf);
Inc(Count);
end;
except
on E: Exception do
raise Exception.CreateFmt('Error on reading record # %d, %.4X Offs: %.8X' + #13 + E.Message,[Count,Header.RecId,FXLSStream.Pos]);
end;
if Assigned(FXLS.OnProgress) then
FXLS.OnProgress(Self,100);
finally
FXLSStream.Close;
FreeMem(PBuf);
end;
end;
// Sheet cells
procedure TXLSReadII.RREC_BLANK;
begin
InsertRecord := False;
with PRecBLANK(PBuf)^ do
FXLS.Sheets[FCurrSheet].IntWriteBlank(Col,Row,FormatIndex);
end;
procedure TXLSReadII.RREC_ROW;
begin
InsertRecord := False;
if XLS_DebugMode then begin
if Assigned(FXLS.OnRowHeight) and (PRecROW(PBuf).Height <> 255) then
FXLS.OnRowHeight(Self,PRecROW(PBuf).Row,PRecROW(PBuf).FormatIndex,PRecROW(PBuf).Height);
end;
if (PRecROW(PBuf).Options and $0080) = $0080 then
FXLS.Sheets[FCurrSheet].Rows.SetRecROW(PRecROW(PBuf),PRecROW(PBuf).FormatIndex and $0FFF)
else
FXLS.Sheets[FCurrSheet].Rows.SetRecROW(PRecROW(PBuf),DEFAULT_FORMAT);
end;
procedure TXLSReadII.RREC_BOOLERR;
begin
InsertRecord := False;
with PRecBOOLERR(PBuf)^ do begin
if Error = 0 then
FXLS.Sheets[FCurrSheet].IntWriteBoolean(Col,Row,FormatIndex,Boolean(BoolErr))
else
FXLS.Sheets[FCurrSheet].IntWriteError(Col,Row,FormatIndex,ErrorCodeToCellError(BoolErr));
end;
end;
procedure TXLSReadII.ReadFormulaVal(Col,Row,FormatIndex: integer; Value: double; Formula: PByteArray; Len: integer);
var
// ExtSz: integer;
Fmla: PByteArray;
S: string;
begin
// ExtSz := 0;
GetMem(Fmla,Len);
try
// Formula points to PBuf, which is overwritten by the next read of the file.
Move(Formula^,Fmla^,Len);
case TByte8Array(Value)[0] of
0: begin
Header.RecID := FXLSStream.PeekHeader;
if (Header.RecID = BIFFRECID_SHRFMLA) or (Header.RecID = $04BC) then begin
raise Exception.Create('Unxepected SHRFMLA');
{
ExtSz := SizeOf(TBIFFHeader) + Header.Length;
FXLSStream.Read(PBuf^,Header.Length);
FXLSStream.ReadHeader(Header);
}
end;
if Header.RecID = BIFFRECID_STRING then begin
FXLSStream.ReadHeader(Header);
FXLSStream.Read(PBuf^,Header.Length);
S := ByteStrToWideString(@PRecSTRING(PBuf).Data,PRecSTRING(PBuf).Len);
{
if ExtSz > 0 then begin
Inc(ExtSz,SizeOf(TBIFFHeader) + Header.Length);
FXLSStream.Seek2(-ExtSz,soFromCurrent);
end;
}
end
else if Header.RecID = BIFFRECID_STRING_20 then begin
FXLSStream.ReadHeader(Header);
FXLSStream.Read(PBuf^,Header.Length);
S := ByteStrToWideString(@PRec2STRING(PBuf).Data,PRec2STRING(PBuf).Len);
end
else
Exit;
FXLS.Sheets[FCurrSheet].WriteRawStrFormula(Col,Row,FormatIndex,Fmla,Len,S);
end;
1: FXLS.Sheets[FCurrSheet].WriteRawBoolFormula(Col,Row,FormatIndex,Fmla,Len,Boolean(Integer(TByte8Array(Value)[2])));
2: FXLS.Sheets[FCurrSheet].WriteRawErrFormula(Col,Row,FormatIndex,Fmla,Len,TByte8Array(Value)[2]);
// Undocumented: the value 3 indicates that the result is an empty string,
// and therefore there is no STRING record following the formula.
3: FXLS.Sheets[FCurrSheet].WriteRawStrFormula(Col,Row,FormatIndex,Fmla,Len,'');
end;
finally
FreeMem(Fmla);
end;
end;
procedure TXLSReadII.RREC_FORMULA;
var
P: PByteArray;
begin
InsertRecord := False;
if FXLS.Version xvExcel30 then with PRec2FORMULA(PBuf)^ do begin
if (TByte8Array(Value)[6] = $FF) and (TByte8Array(Value)[7] = $FF) then
ReadFormulaVal(Col,Row,-1,Value,@Data,ParseLen)
else
FXLS.Sheets[FCurrSheet].WriteRawNumFormula(Col,Row,DEFAULT_FORMAT,@Data,ParseLen,Value);
end
else with PRecFORMULA(PBuf)^ do begin
// ATTN: Under some circumstances (don't know why) the Shared Formula bit is set
// in the Options field, even if the formula not is part of a shared formula group.
// There is no SHRFMLA record following the FORMULA record.
// The formula contaions a complete expression.
// This seems to only occure in XLS-97 files.
// Bug in Excel?
// One way to check this is to se if the first PTG in the formula is ptgExp, = part of shared formula.
if ((Options and $0008) = $0008) and (Data[0] = ptgExp) then begin
Header.RecID := FXLSStream.PeekHeader;
if (Header.RecID = BIFFRECID_SHRFMLA) or (Header.RecID = BIFFRECID_SHRFMLA_20) then begin
FXLSStream.ReadHeader(Header);
READ_SHRFMLA
end;
FixupSharedFormula(Col,Row);
end
else if Data[0] = ptgExp then begin
if FXLSStream.PeekHeader = BIFFRECID_ARRAY then begin
FXLSStream.ReadHeader(Header);
GetMem(P,Header.Length);
try
FXLSStream.Read(P^,Header.Length);
FXLS.Sheets[FCurrSheet].WriteRawArrayFormula(Col,Row,FormatIndex,@Data,ParseLen,Value,P,Header.Length);
finally
FreeMem(P);
end;
Exit;
end;
end;
if (TByte8Array(Value)[0] in [$00,$01,$02,$03]) and (TByte8Array(Value)[6] = $FF) and (TByte8Array(Value)[7] = $FF) then
ReadFormulaVal(Col,Row,FormatIndex,Value,@Data,ParseLen)
else if ParseLen <> 0 then begin
// This detects NAN values. A NAN number may cause an "Invalid Floating Point Operation" exception when used.
if (TByte8Array(Value)[0] = $02) and (TByte8Array(Value)[6] = $FF) and (TByte8Array(Value)[7] = $FF) then
FXLS.Sheets[FCurrSheet].WriteRawNumFormula(Col,Row,FormatIndex,@Data,ParseLen,0)
else
FXLS.Sheets[FCurrSheet].WriteRawNumFormula(Col,Row,FormatIndex,@Data,ParseLen,Value);
end;
end;
end;
procedure TXLSReadII.RREC_FORMULA_30;
begin
InsertRecord := False;
with PRecFORMULA3(PBuf)^ do begin
FXLS.Sheets[FCurrSheet].WriteRawNumFormula(Col,Row,FormatIndex,@Data,ParseLen,Value);
if (TByte8Array(Value)[6] = $FF) and (TByte8Array(Value)[7] = $FF) then
ReadFormulaVal(Col,Row,FormatIndex,Value,@Data,ParseLen);
end;
end;
procedure TXLSReadII.RREC_NUMBER;
begin
InsertRecord := False;
with PRecNUMBER(PBuf)^ do
FXLS.Sheets[FCurrSheet].IntWriteNumber(Col,Row,FormatIndex,Value);
end;
procedure TXLSReadII.RREC_INTEGER_20;
begin
InsertRecord := False;
with PRec2INTEGER(PBuf)^ do
FXLS.Sheets[FCurrSheet].IntWriteNumber(Col,Row,DEFAULT_FORMAT,Value);
end;
procedure TXLSReadII.RREC_LABEL_20;
var
S: string;
begin
InsertRecord := False;
with PRec2LABEL(PBuf)^ do begin
SetLength(S,Len);
Move(Data,Pointer(S)^,Len);
FXLS.Sheets[FCurrSheet].IntWriteSSTString(Col,Row,DEFAULT_FORMAT,S);
end;
end;
procedure TXLSReadII.RREC_NUMBER_20;
begin
InsertRecord := False;
with PRec2NUMBER(PBuf)^ do
FXLS.Sheets[FCurrSheet].IntWriteNumber(Col,Row,DEFAULT_FORMAT,Value);
end;
procedure TXLSReadII.RREC_LABELSST;
begin
InsertRecord := False;
with PRecLABELSST(PBuf)^ do
FXLS.Sheets[FCurrSheet].IntWriteSSTStringIndex(Col,Row,FormatIndex,SSTIndex);
end;
procedure TXLSReadII.RREC_LABEL;
var
S: string;
WS: WideString;
begin
InsertRecord := False;
with PRecLABEL(PBuf)^ do begin
if (Len > 0) and (Data[0] = 1) then begin
SetLength(WS,Len);
Move(Data,Pointer(S)^,Len * 2);
FXLS.Sheets[FCurrSheet].IntWriteSSTString(Col,Row,FormatIndex,WS);
end
else if (Len > 0) and (Data[0] = 0) then begin
SetLength(S,Len);
Move(Data,Pointer(S)^,Len);
FXLS.Sheets[FCurrSheet].IntWriteSSTString(Col,Row,FormatIndex,S);
end
else begin
SetLength(S,Len);
Move(Data,Pointer(S)^,Len);
FXLS.Sheets[FCurrSheet].IntWriteSSTString(Col,Row,FormatIndex,S);
end;
end;
end;
procedure TXLSReadII.RREC_RSTRING;
var
S: string;
begin
InsertRecord := False;
with PRecLABEL(PBuf)^ do begin
SetLength(S,Len);
Move(Data,Pointer(S)^,Len);
FXLS.Sheets[FCurrSheet].IntWriteSSTString(Col,Row,FormatIndex,S);
end;
end;
procedure TXLSReadII.RREC_MULBLANK;
var
i: integer;
begin
InsertRecord := False;
with PRecMULBLANK(PBuf)^ do begin
for i := 0 to (Header.Length - 6) div 2 - 1 do
FXLS.Sheets[FCurrSheet].IntWriteBlank(Col1 + i,Row,FormatIndexes[i]);
end;
end;
procedure TXLSReadII.RREC_RK;
begin
InsertRecord := False;
with PRecRK(PBuf)^ do
FXLS.Sheets[FCurrSheet].IntWriteNumber(Col,Row,FormatIndex,DecodeRK(Value));
end;
procedure TXLSReadII.RREC_MULRK;
var
i: integer;
begin
InsertRecord := False;
with PRecMULRK(PBuf)^ do begin
for i := 0 to (Header.Length - 6) div 6 - 1 do
FXLS.Sheets[FCurrSheet].IntWriteNumber(Col1 + i,Row,RKs[i].FormatIndex,DecodeRK(RKs[i].Value));
end;
end;
procedure TXLSReadII.FixupSharedFormula(ACol,ARow: integer);
var
i: integer;
begin
// ATTN: Ranges of shared formulas may overlap. The last one written seems
// to be the correct, therefore all shared formulas has to be searched.
for i := 0 to High(FSharedFormulas) do begin
with FSharedFormulas[i] do begin
if (ACol >= Col1) and (ACol = Col2) and (ARow >= Row1) and (ARow = Row2) then begin
Move(Formula^,PRecFORMULA(PBuf).Data,Len);
PRecFORMULA(PBuf).ParseLen := Len;
ConvertShrFmla(FXLS.Version = xvExcel97,@PRecFORMULA(PBuf).Data,PRecFORMULA(PBuf).ParseLen,ACol,ARow);
Break;
end;
end;
end;
end;
procedure TXLSReadII.READ_SHRFMLA;
var
i: integer;
begin
// ATTN: If Excel saves a SHRFMLA where some cells have been deleted,
// (Ex: If you have 10 formulas in a row, saves it, open the sheet again,
// deletes 4 of them and saves it again) then may the deleted formulas
// still be saved in the SHRFMLA record!
// The only way to check this is to look for the corresponding FORMULA
// records. There is only FORMULA records for formulas that exsists on
// the sheet. I think :-)
SetLength(FSharedFormulas,Length(FSharedFormulas) + 1);
i := High(FSharedFormulas);
FXLSStream.Read(FSharedFormulas[i],6);
FXLSStream.Read(FSharedFormulas[i].Len,2); // Reserved data
FXLSStream.Read(FSharedFormulas[i].Len,2);
GetMem(FSharedFormulas[i].Formula,FSharedFormulas[i].Len);
FXLSStream.Read(FSharedFormulas[i].Formula^,FSharedFormulas[i].Len);
end;
procedure TXLSReadII.RREC_NOTE;
begin
InsertRecord := False;
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_SUFFIXDATA);
with PRecNOTE(PBuf)^ do
FXLS.Sheets[FCurrSheet].EscherDrawing.SetNoteData(Col,Row,Options,ObjId,ByteStrToWideString(PByteArray(@AuthorName),AuthorNameLen));
end;
procedure TXLSReadII.RREC_1904;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_ADDMENU;
begin
// Not used
end;
procedure TXLSReadII.RREC_BACKUP;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_BOOKBOOL;
begin
CurrRecs.UpdateDefault(Header,PBuf);
InsertRecord := False;
TRecordStorageGlobals(CurrRecs).UpdateInternal(INTERNAL_FORMATS);
end;
procedure TXLSReadII.RREC_PALETTE;
var
i: integer;
begin
if PRecPALETTE(PBuf).Count > (Length(ExcelColorPalette) - 8) then
PRecPALETTE(PBuf).Count := Length(ExcelColorPalette) - 8;
for i := 0 to PRecPALETTE(PBuf).Count - 1 do
ExcelColorPalette[i + 8] := PRecPALETTE(PBuf).Color[i];
end;
procedure TXLSReadII.RREC_BOUNDSHEET;
var
S: string;
begin
TRecordStorageGlobals(CurrRecs).UpdateInternal(INTERNAL_BOUNDSHEETS);
InsertRecord := False;
if FXLS.Version xvExcel97 then with PRecBOUNDSHEET7(PBuf)^ do begin
SetLength(S,NameLen);
Move(Name,Pointer(S)^,NameLen);
end
else with PRecBOUNDSHEET8(PBuf)^ do begin
if Name[0] = 1 then begin
SetLength(S,((NameLen * 2) and $00FF) + 1);
Move(Name[0],Pointer(S)^,((NameLen * 2) and $00FF) + 1)
end
else begin
SetLength(S,(NameLen and $00FF) + 1);
Move(Name[0],Pointer(S)^,(NameLen and $00FF) + 1);
end;
end;
FBoundsheets.AddObject(S,TObject(CurrRecs.Count - 1));
end;
procedure TXLSReadII.RREC_CALCCOUNT;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_CALCMODE;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_CODEPAGE;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_COLINFO;
{
var
Col,MaxCol: integer;
}
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_COLINFO);
InsertRecord := False;
FXLS.Sheets[FCurrSheet].Columns.SetRecCOLINFO(PRecCOLINFO(PBuf));
{
MaxCol := PRecCOLINFO(PBuf).Col2;
if PRecCOLINFO(PBuf).Col2 > 255 then
MaxCol := 255;
if Assigned(FXLS.OnColWidth) then begin
for Col := PRecCOLINFO(PBuf).Col1 to MaxCol do
FXLS.OnColWidth(Self,Col,PRecCOLINFO(PBuf).FormatIndex,PRecCOLINFO(PBuf).Width);
end;
}
end;
procedure TXLSReadII.RREC_COUNTRY;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_RECALCID;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_DEFAULTROWHEIGHT;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_DEFCOLWIDTH;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_DELMENU;
begin
// Not used.
end;
procedure TXLSReadII.RREC_DELTA;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_DIMENSIONS;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_DSF;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_FNGROUPCOUNT;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_EOF;
begin
// This shall never happens.
raise Exception.Create(ersEOFUnexpected);
end;
procedure TXLSReadII.RREC_NAME;
begin
case FXLS.Version of
xvExcel97: begin
TRecordStorageGlobals(CurrRecs).UpdateInternal(INTERNAL_NAMES);
FXLS.InternalNames.SetNAME(PRecNAME(PBuf));
InsertRecord := False;
end;
end;
end;
procedure TXLSReadII.RREC_SUPBOOK;
begin
case FXLS.Version of
xvExcel97: begin
TRecordStorageGlobals(CurrRecs).UpdateInternal(INTERNAL_NAMES);
InsertRecord := False;
FXLS.FormulaHandler.ExternalNames.SetSUPBOOK(PRecSUPBOOK(PBuf));
end;
end;
end;
procedure TXLSReadII.RREC_EXTERNNAME;
begin
case FXLS.Version of
xvExcel97: begin
TRecordStorageGlobals(CurrRecs).UpdateInternal(INTERNAL_NAMES);
InsertRecord := False;
FXLS.FormulaHandler.ExternalNames.SetEXTERNNAME(PRecEXTERNNAME8(PBuf));
end;
end;
end;
procedure TXLSReadII.RREC_XCT;
var
i,Count,Index: integer;
begin
InsertRecord := False;
Count := PRecXCT(PBuf).CRNCount;
if Count = $FFFF then
Count := 1;
Index := PRecXCT(PBuf).SheetIndex;
for i := 0 to Count - 1 do begin
if (FXLSStream.ReadHeader(Header) <> SizeOf(TBIFFHeader)) or (Header.RecID <> BIFFRECID_CRN) then
raise Exception.Create('CRN record missing');
FXLSStream.Read(PBuf^,Header.Length);
FXLS.FormulaHandler.ExternalNames.SetCRN(Index,PRecCRN(PBuf),Header.Length);
end;
end;
procedure TXLSReadII.RREC_EXTERNCOUNT;
begin
// if FXLS.Version = xvExcel97 then
// FXLS.NameDefs.ExternCount := PWord(PBuf)^;
end;
procedure TXLSReadII.RREC_EXTERNSHEET;
begin
case FXLS.Version of
xvExcel97: begin
TRecordStorageGlobals(CurrRecs).UpdateInternal(INTERNAL_NAMES);
InsertRecord := False;
FXLS.FormulaHandler.ExternalNames.SetEXTERNSHEET(PBuf);
end;
xvExcel50: begin
end;
end;
end;
procedure TXLSReadII.RREC_FONT;
begin
InsertRecord := False;
with FXLS.Fonts.Add do begin
CharSet := PRecFONT(PBuf).CharSet;
Family := PRecFONT(PBuf).Family;
if PRecFONT(PBuf).ColorIndex > $00FF then
Color := xcBlack
else
Color := TExcelColor(PRecFONT(PBuf).ColorIndex);
Name := ByteStrToWideString(@PRecFONT(PBuf).Name,PRecFONT(PBuf).NameLen);
Size20 := PRecFONT(PBuf).Height;
Style := [];
if PRecFONT(PBuf).Bold >= $02BC then
Style := Style + [xfsBold];
Underline := TXUnderline(PRecFONT(PBuf).Underline);
if (PRecFONT(PBuf).Attributes and $02) = $02 then
Style := Style + [xfsItalic];
if (PRecFONT(PBuf).Attributes and $08) = $08 then
Style := Style + [xfsStrikeout];
// Font #4 does not exsists (and is not stored in the XLS file).
if FXLS.Fonts.Count = 4 then
FXLS.Fonts.Add;
end;
end;
procedure TXLSReadII.RREC_HEADER;
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_HEADER);
if FXLS.Version xvExcel97 then begin
Move(PBuf[1],PBuf[3],Header.Length - 1);
PBuf[1] := 0;
PBuf[2] := 0;
end
else if Header.Length > 0 then
FXLS.Sheets[FCurrSheet].PrintSettings.Header := ByteStrToWideString(@PBuf[2],PWordArray(PBuf)[0])
else
FXLS.Sheets[FCurrSheet].PrintSettings.Header := '';
InsertRecord := False;
end;
procedure TXLSReadII.RREC_FOOTER;
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_HEADER);
if FXLS.Version xvExcel97 then begin
Move(PBuf[1],PBuf[3],Header.Length - 1);
PBuf[1] := 0;
PBuf[2] := 0;
end
else if Header.Length > 0 then
FXLS.Sheets[FCurrSheet].PrintSettings.Footer := ByteStrToWideString(@PBuf[2],PWordArray(PBuf)[0])
else
FXLS.Sheets[FCurrSheet].PrintSettings.Footer := '';
InsertRecord := False;
end;
procedure TXLSReadII.RREC_FORMAT;
begin
InsertRecord := False;
if FXLS.Version xvExcel97 then begin
with PRecFORMAT7(PBuf)^ do
FXLS.AddNumberFormat(ByteStrToWideString(@Data,Len),Index);
end
else begin
with PRecFORMAT8(PBuf)^ do
FXLS.AddNumberFormat(ByteStrToWideString(@Data,Len),Index);
end;
end;
procedure TXLSReadII.RREC_GRIDSET;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_GUTS;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_HCENTER;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_HIDEOBJ;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_HLINK;
begin
if FXLS.Version xvExcel97 then
Exit;
FXLS.Sheets[FCurrSheet].Hyperlinks.LoadFromStream(FXLSStream,Header.Length,PBuf);
InsertRecord := False;
end;
procedure TXLSReadII.RREC_FILEPASS;
var
S: WideString;
begin
if PRecFILEPASS(PBuf).Options = 0 then
raise Exception.Create('File encrypted with non-standard key. French?');
if PRecFILEPASS(PBuf).Options <> 1 then
raise Exception.Create('Can not read file, unknown type of encryption.');
if not Assigned(FXLS.OnPassword) then
raise Exception.Create('File is encrypted. Password required.');
S := '';
FXLS.OnPassword(FXLS,S);
if S = '' then
raise Exception.Create('Password is missing.');
if not FXLSStream.SetReadDecrypt(PRecFILEPASS(PBuf),S) then
raise Exception.Create('Invalid password');
InsertRecord := False;
end;
procedure TXLSReadII.RREC_INTERFACEEND;
begin
// Not used.
end;
procedure TXLSReadII.RREC_INTERFACEHDR;
begin
// Not used.
end;
procedure TXLSReadII.RREC_ITERATION;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_MERGEDCELLS;
var
i,Count: integer;
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_SUFFIXDATA);
InsertRecord := False;
Count := PRecMERGEDCELLS(PBuf).Count;
for i := 0 to Count - 1 do begin
with TMergedCell(FXLS.Sheets[FCurrSheet].MergedCells.Add) do begin
Row1 := PRecMERGEDCELLS(PBuf).Cells[i].Row1;
Row2 := PRecMERGEDCELLS(PBuf).Cells[i].Row2;
Col1 := PRecMERGEDCELLS(PBuf).Cells[i].Col1;
Col2 := PRecMERGEDCELLS(PBuf).Cells[i].Col2;
end;
end;
end;
procedure TXLSReadII.RREC_CONDFMT;
begin
InsertRecord := False;
FXLS.Sheets[FCurrSheet].ConditionalFormats.LoadFromStream(FXLSStream,PBuf);
end;
procedure TXLSReadII.RREC_MSODRAWING;
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_SUFFIXDATA);
FXLS.Sheets[FCurrSheet].EscherDrawing.LoadFromStream(FXLSStream,PBuf);
InsertRecord := False;
end;
procedure TXLSReadII.RREC_MSODRAWINGGROUP;
begin
InsertRecord := False;
TRecordStorageGlobals(CurrRecs).UpdateInternal(INTERNAL_MSODRWGRP);
FXLSStream.BeginCONTINUERead;
try
FXLS.MSOPictures.LoadFromStream(FXLSStream,PBuf);
finally
FXLSStream.EndCONTINUERead;
end;
end;
procedure TXLSReadII.RREC_MSODRAWINGSELECTION;
begin
InsertRecord := False;
end;
procedure TXLSReadII.RREC_PASSWORD;
begin
// Silly password for not encrypted sheets.
// password protected
// InsertRecord := False;
// CurrRecs.UpdateDefault(Header,PBuf);
{
if PWord(PBuf)^ <> 0 then
raise Exception.Create(ersPasswordProtect);
}
end;
procedure TXLSReadII.RREC_PLS;
begin
// InsertRecord := False;
// CurrRecs.AddDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_PRECISION;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_PRINTGRIDLINES;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_PRINTHEADERS;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_PROT4REV;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_PROT4REVPASS;
begin
end;
procedure TXLSReadII.RREC_PROTECT;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_REFMODE;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_REFRESHALL;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_SAVERECALC;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_SELECTION;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_DVAL;
begin
FXLS.Sheets[FCurrSheet].Validations.LoadFromStream(FXLSStream,PBuf);
InsertRecord := False;
end;
procedure TXLSReadII.RREC_BOTTOMMARGIN;
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_MARGINS);
FXLS.Sheets[FCurrSheet].PrintSettings.MarginBottom := PRecMARGIN(PBuf).Value;
InsertRecord := False;
end;
procedure TXLSReadII.RREC_LEFTMARGIN;
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_MARGINS);
FXLS.Sheets[FCurrSheet].PrintSettings.MarginLeft := PRecMARGIN(PBuf).Value;
InsertRecord := False;
end;
procedure TXLSReadII.RREC_RIGHTMARGIN;
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_MARGINS);
FXLS.Sheets[FCurrSheet].PrintSettings.MarginRight := PRecMARGIN(PBuf).Value;
InsertRecord := False;
end;
procedure TXLSReadII.RREC_TOPMARGIN;
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_MARGINS);
FXLS.Sheets[FCurrSheet].PrintSettings.MarginTop := PRecMARGIN(PBuf).Value;
InsertRecord := False;
end;
procedure TXLSReadII.RREC_SETUP;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_SST;
begin
TRecordStorageGlobals(CurrRecs).UpdateInternal(INTERNAL_SST);
InsertRecord := False;
// FXLSStream.Seek2(-(SizeOf(TBIFFHeader) + Header.Length),soFromCurrent);
FXLS.Sheets.ReadSST(FXLSStream,Header.Length);
end;
procedure TXLSReadII.RREC_EXTSST;
begin
InsertRecord := False;
end;
procedure TXLSReadII.RREC_STYLE;
begin
// Only save Built-in styles.
{
if (PRecSTYLE(PBuf).FormatIndex and $8000) = $8000 then
FXLS.Styles.Add(PRecSTYLE(PBuf));
}
end;
procedure TXLSReadII.RREC_USESELFS;
begin
// Not used.
end;
procedure TXLSReadII.RREC_VCENTER;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_WINDOW1;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_WINDOW2;
begin
if FXLS.Version = xvExcel50 then begin
PRecWINDOW2_8(PBuf).Zoom := 0;
PRecWINDOW2_8(PBuf).ZoomPreview := 0;
PRecWINDOW2_8(PBuf).Reserved := 0;
Header.Length := SizeOf(TRecWINDOW2_8);
end;
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_SCL;
begin
FXLS.Sheets[FCurrSheet].Zoom := Round((PRecSCL(PBuf).Numerator / PRecSCL(PBuf).Denominator) * 100);
end;
procedure TXLSReadII.RREC_PANE;
begin
InsertRecord := False;
with PRecPANE(PBuf)^ do begin
FXLS.Sheets[FCurrSheet].Pane.ActivePane := PaneNumber;
FXLS.Sheets[FCurrSheet].Pane.SplitColX := X;
FXLS.Sheets[FCurrSheet].Pane.SplitRowY := Y;
FXLS.Sheets[FCurrSheet].Pane.LeftCol := LeftCol;
FXLS.Sheets[FCurrSheet].Pane.TopRow := TopRow;
if FXLS.Sheets[FCurrSheet].Pane.PaneType = ptNone then
FXLS.Sheets[FCurrSheet].Pane.PaneType := ptSplit;
while FXLSStream.PeekHeader = BIFFRECID_SELECTION do begin
FXLSStream.ReadHeader(Header);
FXLSStream.Read(PBuf^,Header.Length);
FXLS.Sheets[FCurrSheet].Pane.Selections.AddRec(Header,PBuf);
end;
end;
end;
procedure TXLSReadII.RREC_WINDOWPROTECT;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_WRITEACCESS;
begin
InsertRecord := False;
if FXLS.Version xvExcel97 then begin
Move(PBuf[1],PBuf[3],Header.Length - 2);
PBuf[1] := 0;
PBuf[2] := 0;
end;
if Header.Length 112 then begin
FillChar(PBuf[Header.Length],112 - Header.Length,' ');
Header.Length := 112;
end;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_WSBOOL;
begin
InsertRecord := False;
CurrRecs.UpdateDefault(Header,PBuf);
end;
procedure TXLSReadII.RREC_HORIZONTALPAGEBREAKS;
var
i: integer;
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_PAGEBREAKES);
if FXLS.Version >= xvExcel97 then begin
for i := 0 to PRecHORIZONTALPAGEBREAKS(PBuf).Count - 1 do begin
with FXLS.Sheets[FCurrSheet].PrintSettings.HorizPagebreaks.Add do begin
Row := PRecHORIZONTALPAGEBREAKS(PBuf).Breaks[i].Val1 - 1;
Col1 := PRecHORIZONTALPAGEBREAKS(PBuf).Breaks[i].Val2 - 1;
Col2 := PRecHORIZONTALPAGEBREAKS(PBuf).Breaks[i].Val3 - 1;
end;
end;
end
else if FXLS.Version = xvExcel50 then begin
for i := 1 to PWordArray(PBuf)[0] - 1 do begin
with FXLS.Sheets[FCurrSheet].PrintSettings.HorizPagebreaks.Add do begin
Row := PWordArray(PBuf)[i] - 1;
Col1 := 0;
Col2 := 255;
end;
end;
end;
InsertRecord := False;
end;
procedure TXLSReadII.RREC_VERTICALPAGEBREAKS;
var
i: integer;
begin
TRecordStorageSheet(CurrRecs).UpdateInternal(INTERNAL_PAGEBREAKES);
if FXLS.Version >= xvExcel97 then begin
for i := 0 to PRecVERTICALPAGEBREAKS(PBuf).Count - 1 do begin
with FXLS.Sheets[FCurrSheet].PrintSettings.VertPagebreaks.Add do begin
Col := PRecVERTICALPAGEBREAKS(PBuf).Breaks[i].Val1 - 1;
Row1 := PRecVERTICALPAGEBREAKS(PBuf).Breaks[i].Val2 - 1;
Row2 := PRecVERTICALPAGEBREAKS(PBuf).Breaks[i].Val3 - 1;
end;
end;
end
else if FXLS.Version = xvExcel50 then begin
for i := 1 to PWordArray(PBuf)[0] - 1 do begin
with FXLS.Sheets[FCurrSheet].PrintSettings.VertPagebreaks.Add do begin
Col := PWordArray(PBuf)[i] - 1;
Row1 := 0;
Row2 := MAXROW;
end;
end;
end;
InsertRecord := False;
end;
procedure TXLSReadII.RREC_XF;
procedure ReadXF30;
begin
with FXLS.Formats.Add do begin
// Font := FXLS.Fonts[PRecXF3(PBuf).FontIndex];
// FontIndex := PRecXF3(PBuf).FontIndex;
end;
end;
begin
InsertRecord := False;
if FXLS.Version >= xvExcel97 then
FXLS.Formats.Add.FromXF8(PBuf)
else if FXLS.Version >= xvExcel50 then
FXLS.Formats.Add.FromXF7(PBuf)
else if FXLS.Version >= xvExcel30 then
ReadXF30;
end;
end.