📄 uxlsbaserecords.pas
字号:
xlr_DBCELL, //To find rows in blocks... we need to calculate it again
xlr_INDEX, //Same as DBCELL
xlr_MSODRAWINGSELECTION // Object selection. We do not need to select any drawing
// ,xlr_OBPROJ If we want to disable macros.
: R:= TIgnoreRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_DIMENSIONS //Used range of a sheet
: R:= TDimensionsRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_SST : R:= TSSTRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_BoundSheet : R:= TBoundSheetRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_CODENAME : R:= TCodeNameRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_OBPROJ : R:= TObProjRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_Array : R:= TArrayRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_Blank : R:= TBlankRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_BoolErr : R:= TBoolErrRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_Number : R:= TNumberRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_MulBlank : R:= TMulBlankRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_MulRK : R:= TMulRKRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_RK : R:= TRKRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_STRING : R:= TStringRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);//String record saves the result of a formula
xlr_XF : R:= TXFRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_FONT : R:= TFontRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_FORMAT : R:= TFormatRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_Palette : R:= TPaletteRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_Style : R:= TStyleRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_LabelSST : R:= TLabelSSTRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_Label : R:= TLabelRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_Row : R:= TRowRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_NAME : R:= TNameRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_TABLE : R:= TTableRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_CELLMERGING : R:= TCellMergingRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_CONDFMT : R:= TCondFmtRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_CF : R:= TCFRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_DVAL : R:= TDValRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_HLINK : R:= THLinkRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_SCREENTIP : R:= TScreenTipRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_Continue : R:= TContinueRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_FOOTER : R:= TPageFooterRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_HEADER : R:= TPageHeaderRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_PRINTGRIDLINES : R:= TPrintGridLinesRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_LEFTMARGIN,
xlr_RIGHTMARGIN,
xlr_TOPMARGIN,
xlr_BOTTOMMARGIN: R:= TMarginRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_SETUP : R:= TSetupRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_PLS : R:= TPlsRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_WSBOOL : R:= TWsBoolRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_XCT, // Cached values of a external workbook... not supported yet
xlr_CRN // Cached values also
: R:=TIgnoreRecord.Create(RecordHeader.Id, Data, RecordHeader.Size); //raise Exception.Create (ErrExtRefsNotSupported);
xlr_SUPBOOK : R:= TSupBookRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_EXTERNSHEET : R:= TExternSheetRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_EXTERNNAME,
xlr_EXTERNNAME2
: R:= TExternNameRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_ChartAI : R:= TChartAIRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_Window1 : R:= TWindow1Record.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_Window2 : R:= TWindow2Record.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_1904 : R:= T1904Record.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_REFMODE : R:= TRefModeRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_PRECISION : R:= TPrecisionRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_BOOKBOOL : R:= TBookBoolRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_PANE : R:= TPaneRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_SCL : R:= TSCLRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_GUTS : R:= TGutsRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_HORIZONTALPAGEBREAKS: R:= THPageBreakRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_VERTICALPAGEBREAKS : R:= TVPageBreakRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_COLINFO : R:= TColInfoRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_DEFCOLWIDTH : R:= TDefColWidthRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_STANDARDWIDTH:R:= TStandardWidthRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_DEFAULTROWHEIGHT: R:= TDefRowHeightRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
xlr_FILEPASS: raise Exception.Create(ErrFileIsPasswordProtected);
else R:= TBaseRecord.Create(RecordHeader.Id, Data, RecordHeader.Size);
end; //case
//Peek at the next record...
if DataStream.Read(NextRecordHeader, SizeOf(NextRecordHeader))= SizeOf(NextRecordHeader) then
begin
if NextRecordHeader.Id = xlr_Continue then R.AddContinue(LoadRecord(DataStream, NextRecordHeader) as TContinueRecord)
else if NextRecordHeader.Id=xlr_Table then
if (R is TFormulaRecord) then
begin
(R as TFormulaRecord).TableRecord:=LoadRecord(DataStream, NextRecordHeader) as TTableRecord;
end
else Exception.Create(ErrExcelInvalid)
else if NextRecordHeader.Id=xlr_Array then
if (R is TFormulaRecord) then
begin
(R as TFormulaRecord).ArrayRecord:=LoadRecord(DataStream, NextRecordHeader) as TArrayRecord;
end
else Exception.Create(ErrExcelInvalid)
else if NextRecordHeader.Id=xlr_ScreenTip then
if (R is THLinkRecord) then
begin
(R as THLinkRecord).AddHint(LoadRecord(DataStream, NextRecordHeader) as TScreenTipRecord);
end
else Exception.Create(ErrExcelInvalid)
else
begin
if NextRecordHeader.Id = xlr_String then
begin
if not (R is TFormulaRecord) and not (R is TShrFmlaRecord) and not (R is TArrayRecord) and not (R is TTableRecord) then raise Exception.Create(ErrExcelInvalid);
end;
DataStream.Seek(-SizeOf(NextRecordHeader),soFromCurrent);
end;
end;
Result:=R;
end;
{ TBaseRecord }
procedure TBaseRecord.AddContinue(const aContinue: TContinueRecord);
begin
if Continue<>nil then raise Exception.Create(ErrInvalidContinue);
Continue:=aContinue;
end;
function TBaseRecord.CopyTo: TBaseRecord;
begin
if Self=nil then Result:= nil //for this to work, this cant be a virtual method
else Result:=DoCopyTo;
end;
constructor TBaseRecord.Create(const aId: word; const aData: PArrayOfByte; const aDataSize: integer);
begin
inherited Create;
Id := aId;
Data := aData;
DataSize := aDataSize;
end;
destructor TBaseRecord.Destroy;
begin
if Data<>nil then FreeMem(Data);
FreeAndNil(Continue);
inherited;
end;
function TBaseRecord.DoCopyTo: TBaseRecord;
var
NewData: PArrayOfByte;
begin
GetMem(NewData, DataSize);
try
Move(Data^, NewData^, DataSize);
Result:= ClassOfTBaseRecord(ClassType).Create(Id, NewData, DataSize);
except
FreeMem(NewData);
raise;
end;
if Continue<>nil then Result.Continue:= Continue.CopyTo as TContinueRecord;
end;
procedure TBaseRecord.SaveDataToStream(const Workbook: TStream;
const aData: PArrayOfByte);
begin
if Workbook.Write(Id, Sizeof(Id)) <> Sizeof(Id) then raise Exception.Create(ErrCantWrite);
if Workbook.Write(DataSize, Sizeof(DataSize)) <> Sizeof(DataSize) then raise Exception.Create(ErrCantWrite);
if DataSize > 0 then
if Workbook.Write(aData^, DataSize) <> DataSize then
raise Exception.Create(ErrCantWrite);
end;
procedure TBaseRecord.SaveToStream(const Workbook: TStream);
begin
SaveDataToStream(Workbook, Data);
if Continue<>nil then Continue.SaveToStream(Workbook);
end;
function TBaseRecord.TotalSize: integer;
begin
Result:=SizeOf(TRecordHeader)+ DataSize;
if Continue<>nil then Result:=Result+Continue.TotalSize;
end;
function TBaseRecord.TotalSizeNoHeaders: integer;
begin
Result:=DataSize;
if Continue<>nil then Result:=Result+Continue.TotalSizeNoHeaders;
end;
{ TBaseRowColRecord }
procedure TBaseRowColRecord.ArrangeInsertRowsAndCols(const aRowPos, aRowCount, aColPos, aColCount:integer; const SheetInfo: TSheetInfo);
begin
if DataSize<4 then raise Exception.CreateFmt(ErrWrongExcelRecord,[Id]);
if (SheetInfo.InsSheet<0) or (SheetInfo.FormulaSheet<> SheetInfo.InsSheet) then exit;
if aRowPos<= Row then IncWord(Data, 0, aRowCount, Max_Rows); //row;
{$IFDEF INTERNAL_ACCESS} //Isues if we have 256 columns.
if aColPos<= Column then IncWord(Data, 2, aColCount, Max_Columns); //col;
{$ENDIF}
end;
constructor TBaseRowColRecord.Create(const aId: word; const aData: PArrayOfByte; const aDataSize: integer);
begin
inherited;
if DataSize<4 then raise Exception.CreateFmt(ErrWrongExcelRecord,[Id]);
end;
procedure TBaseRowColRecord.ArrangeCopyRowsAndCols(const RowOffset, ColOffset: integer);
begin
if DataSize<4 then raise Exception.CreateFmt(ErrWrongExcelRecord,[Id]);
SetWord(Data, 0, Row+RowOffset); //row;
SetWord(Data, 2, Column+ColOffset); //col;
end;
function TBaseRowColRecord.GetColumn: word;
begin
GetColumn:=GetWord(Data,2);
end;
function TBaseRowColRecord.GetRow: word;
begin
GetRow:=GetWord(Data,0);
end;
procedure TBaseRowColRecord.SetColumn(Value: word);
begin
SetWord(Data,2,Value);
end;
procedure TBaseRowColRecord.SetRow(Value: word);
begin
SetWord(Data,0,Value);
end;
{ TIgnoreRecord }
procedure TIgnoreRecord.SaveToStream(const Workbook: TStream);
begin
//nothing
end;
function TIgnoreRecord.TotalSize: integer;
begin
Result:=0;
end;
{ TStringRecord }
//We won't write out this record
procedure TStringRecord.SaveToStream(const Workbook: TStream);
begin
//Nothing.
end;
function TStringRecord.TotalSize: integer;
begin
Result:=0;
end;
function TStringRecord.Value: widestring;
var
xs: TExcelString;
Myself: TBaseRecord;
Ofs: integer;
begin
Myself:=Self;Ofs:=0;
xs:=TExcelString.Create(2, Myself, Ofs);
try
Result:=Xs.Value;
finally
freeAndNil(xs);
end;
end;
{ TRowRecord }
constructor TRowRecord.Create(const aId: word; const aData: PArrayOfByte;
const aDataSize: integer);
begin
inherited;
//Set irwMac=0
SetWord(Data, 8, 0);
end;
constructor TRowRecord.CreateStandard(const Row: word);
var
MyData: PArrayOfByte;
begin
GetMem(myData, 16);
FillChar(myData^,16, 0);
SetWord(myData, 0, Row);
SetWord(myData, 6, $FF);
myData[13]:=1;
myData[14]:=$0F; //Default format.
inherited Create(xlr_ROW, myData, 16);
end;
function TRowRecord.GetHeight: word;
begin
Result:=GetWord(Data, 6);
end;
function TRowRecord.GetMaxCol: word;
begin
Result:=GetWord(Data, 4);
end;
function TRowRecord.GetMinCol: word;
begin
Result:=GetWord(Data, 2);
end;
function TRowRecord.GetXF: word;
begin
if IsFormatted then Result:=GetWord(Data, 14) and $FFF else Result:=15;
end;
function TRowRecord.GetRow: Word;
begin
Result:= GetWord(Data, 0);
end;
procedure TRowRecord.SetHeight(const Value: word);
begin
SetWord( Data, 6, Value);
end;
procedure TRowRecord.SetMaxCol(const Value: word);
begin
SetWord( Data, 4, Value);
end;
procedure TRowRecord.SetMinCol(const Value: word);
begin
SetWord( Data, 2, Value);
end;
procedure TRowRecord.ManualHeight;
begin
Data[12]:= Data[12] or $40;
end;
procedure TRowRecord.AutoHeight;
begin
Data[12]:= Data[12] and not $40;
end;
procedure TRowRecord.Hide(const value: boolean);
begin
if Value then Data[12]:= Data[12] or $20 else Data[12]:= Data[12] and not $20;
end;
function TRowRecord.IsAutoHeight: boolean;
begin
Result:= not (Data[12] and $40 = $40);
end;
function TRowRecord.IsHidden: boolean;
begin
Result:= (Data[12] and $20 = $20);
end;
procedure TRowRecord.SetXF(const Value: word);
begin
Data[12]:= Data[12] or $80;
Data[13]:= Data[13] or $01;
SetWord(Data, 14, Value);
end;
procedure TRowRecord.SaveRangeToStream(const DataStream: TStream; const aMinCol, aMaxCol: integer);
var
sMinCol, sMaxCol: integer;
begin
sMinCol:=MinCol;
sMaxCol:=MaxCol;
try
if sMinCol<aMinCol then MinCol:=aMinCol;
if sMaxCol>aMaxCol+1 then MaxCol:=aMaxCol+1;
inherited SaveToStream(DataStream);
finally
MinCol:=sMinCol;
MaxCol:=sMaxCol;
end; //Finally
end;
function TRowRecord.IsFormatted: boolean;
begin
Result:=Data[12] and $80= $80;
end;
function TRowRecord.IsModified: boolean;
begin
Result:=(Data[12]<>0) or (Data[13]<>1);
end;
function TRowRecord.GetOptions: word;
begin
Result:=GetWord(Data, 12);
end;
procedure TRowRecord.SetOptions(const Value: word);
begin
SetWord(Data, 12, Value);
end;
procedure TRowRecord.SetRowOutlineLevel(const Level: integer);
begin
Data[12]:=(Data[12] and not 7) or (Level and 7);
end;
{ TCellRecord }
function TCellRecord.CanJoinNext(const NextRecord: TCellRecord;
const MaxCol: integer): boolean;
begin
Result:=false;
end;
constructor TCellRecord.CreateFromData(const aId, aDataSize, aRow, aCol, aXF: word);
var
aData: pointer;
begin
GetMem(aData, aDataSize);
FillChar(aData^, aDataSize, 0);
Create(aId, aData, aDataSize);
Row:=aRow;
Column:=aCol;
XF:=aXF;
end;
function TCellRecord.GetValue: Variant;
begin
Result:=unassigned;
end;
function TCellRecord.GetXF: word;
begin
Result:= GetWord(Data, 4);
end;
procedure TCellRecord.SaveFirstMul(const Workbook: TStream;
const JoinedRecordSize: Word);
begin
SaveToStream(Workbook);
end;
procedure TCellRecord.SaveLastMul(const Workbook: TStream);
begin
end;
procedure TCellRecord.SaveMidMul(const Workbook: TStream);
begin
end;
procedure TCellRecord.SetValue(const Value: Variant);
begin
//Nothing
end;
procedure TCellRecord.SetXF(const Value: word);
begin
SetWord(Data, 4, Value);
end;
function TCellRecord.TotalSizeFirst: integer;
begin
Result:=TotalSize;
end;
function TCellRecord.TotalSizeLast: integer;
begin
Result:=TotalSize;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -