📄 uxlssheet.pas
字号:
until RecordHeader.id = xlr_EOF;
sBOF:=First; //Last statement
end;
procedure TFlxChart.SaveToStream(const DataStream: TStream);
begin
if (sBOF=nil)or(sEOF=nil) then raise Exception.Create(ErrSectionNotLoaded);
sBOF.SaveToStream(DataStream);
FChartRecords.SaveToStream(DataStream);
if (FCodeName<>nil) then FCodeName.SaveToStream(DataStream);
sEOF.SaveToStream(DataStream);
end;
function TFlxChart.TotalSize: int64;
begin
Result:= inherited TotalSize+
FChartRecords.TotalSize;
end;
procedure TFlxChart.SaveRangeToStream(const DataStream: TStream;
const SheetIndex: integer; const CellRange: TXlsCellRange);
begin
//Can't save a chart range
SaveToStream(DataStream);
end;
function TFlxChart.TotalRangeSize(const SheetIndex: integer; const CellRange: TXlsCellRange): int64;
begin
//Can't save a chart range
Result:=TotalSize;
end;
procedure TFlxChart.ArrangeInsertRowsAndCols(const InsRowPos, InsRowCount, InsColPos, InsColCount: integer; const SheetInfo: TSheetInfo);
begin
FChartRecords.ArrangeInsertRowsAndCols( InsRowPos, InsRowCount, InsColPos, InsColCount, SheetInfo);
end;
procedure TFlxChart.SetPageHeaderFooter(const P: TPageHeaderFooterRecord;
const s: Widestring);
var
OldSize: integer;
begin
if P=nil then exit;
OldSize:=P.DataSize;
P.Text:=s;
FChartRecords.AdaptSize(P.DataSize-OldSize);
end;
procedure TFlxChart.AddZoomRecord;
begin
FZoom:=FChartRecords[FChartRecords.Add(TSCLRecord.CreateFromData(100))] as TSCLRecord;
end;
procedure TFlxChart.FixCachePointers;
var
i: integer;
begin
inherited;
for i:=0 to FChartRecords.Count-1 do
LoadCachePointers(FChartRecords[i] as TBaseRecord);
end;
{ TChartList }
procedure TChartList.ArrangeInsertRowsAndCols(const InsRowPos, InsRowCount, InsColPos, InsColCount: integer;
const SheetInfo: TSheetInfo);
var
i: integer;
begin
for i:=0 to Count -1 do Items[i].ArrangeInsertRowsAndCols(InsRowPos, InsRowCount, InsColPos, InsColCount, SheetInfo);
end;
procedure TChartList.SaveToStream(const DataStream: TStream);
var
i:integer;
begin
for i:=0 to Count-1 do Items[i].SaveToStream(DataStream);
end;
{ TWorkSheet }
procedure TWorkSheet.Clear;
begin
inherited;
//Dont Clear CodeName
if FRanges<>nil then FRanges.Clear;
if FCells<>nil then FCells.Clear;
if FNotes<>nil then FNotes.Clear;
if FColumns<>nil then FColumns.Clear;
if FHLinks<>nil then FHLinks.Clear;
//FDrawing should be freed after notes
if FDrawing<>nil then FDrawing.Clear;
if FVPageBreaks<>nil then FVPageBreaks.Clear;
if FHPageBreaks<>nil then FHPageBreaks.Clear;
if FMiscRecords1<>nil then FMiscRecords1.Clear;
if FMiscRecords2<>nil then FMiscRecords2.Clear;
end;
procedure TWorkSheet.AddOrRemovePane(const Add: Boolean);
var
i: integer;
PaneData: PArrayOfByte;
DataSize: integer;
begin
if Add then
begin
if FPane = nil then
if FMiscRecords2.Count > 1 then
begin
DataSize := 10;
GetMem(PaneData, DataSize);
FillChar(PaneData[0], DataSize, 0);
try
FPane := TPaneRecord.Create(xlr_PANE, PaneData, DataSize);
FMiscRecords2.Insert(1, FPane);
except
FreeMem(PaneData);
FPane := nil;
raise;
end; //Except
end
end
else
begin
if FPane = nil then exit;
for i := FMiscRecords2.Count - 1 downto 0 do
if FMiscRecords2[i] = FPane then
begin
FMiscRecords2.Delete(i);
FPane := nil;
exit;
end;
end;
end;
function TWorkSheet.DoCopyTo: TSheet;
begin
Result:= inherited DoCopyTo;
(Result as TWorkSheet).FMiscRecords1.CopyFrom(FMiscRecords1);
(Result as TWorkSheet).FMiscRecords2.CopyFrom(FMiscRecords2);
(Result as TWorkSheet).FHPageBreaks.CopyFrom(FHPageBreaks);
(Result as TWorkSheet).FVPageBreaks.CopyFrom(FVPageBreaks);
(Result as TWorkSheet).FDrawing.CopyFrom(FDrawing);
(Result as TWorkSheet).FCells.CopyFrom(FCells);
(Result as TWorkSheet).FRanges.CopyFrom(FRanges);
(Result as TWorkSheet).FNotes.CopyFrom(FNotes);
(Result as TWorkSheet).FColumns.CopyFrom(FColumns);
(Result as TWorkSheet).FHLinks.CopyFrom(FHLinks);
(Result as TWorkSheet).FNotes.FixDwgIds((Result as TWorkSheet).FDrawing);
(Result as TWorkSheet).FDefColWidth:=FDefColWidth;
(Result as TWorkSheet).FDefRowHeight:=FDefRowHeight;
Result.FixCachePointers;
end;
constructor TWorkSheet.Create(const aWorkbookGlobals: TWorkbookGlobals);
begin
inherited;
FMiscRecords1:= TBaseRecordList.Create;
FMiscRecords2:= TBaseRecordList.Create;
FHPageBreaks:=THPageBreakList.Create;
FVPageBreaks:=TVPageBreakList.Create;
FDrawing:= TDrawing.Create(FWorkbookGlobals.DrawingGroup);
FColumns:= TColInfoList.Create;
FCells:= TCells.Create(aWorkbookGlobals, FColumns);
FRanges :=TRangeList.Create;
FNotes:= TNoteList.Create;
FHLinks:= THLinkList.Create;
FPrintRecords:=FMiscRecords1;
FDefRowHeight:=$FF;
FDefColWidth:=$0A*DefColWidthAdapt;
end;
constructor TWorkSheet.DoCreateFromData(const SST: TSST);
var
P: Pointer;
H: THandle;
MemStream: TMemoryStream;
BOF: TBOFRecord;
BOFData: PArrayOfByte;
begin
H:=FindResource(HINSTANCE, 'FLXEMPTYWSHEET', RT_RCDATA);
P:=LockResource(LoadResource(HINSTANCE, H));
MemStream:=TMemoryStream.Create;
try
MemStream.Write(P^, SizeofResource(HINSTANCE, H));
MemStream.Position:=4;
GetMem(BOFData, 16);
try
MemStream.Read(BOFData[0], 16);
except
FreeMem(BOFData);
raise;
end; //except
BOF:=TBOFRecord.Create(xlr_BOF, BOFData, 16);
try
LoadFromStream(MemStream, BOF, SST);
except
FreeAndNil(BOF);
raise;
end; //except
finally
FreeAndNil(MemStream);
end; //finally
end;
constructor TWorkSheet.CreateFromData(const aWorkbookGlobals: TWorkbookGlobals; const SST: TSST);
begin
Create(aWorkbookGlobals);
DoCreateFromData(SST);
end;
destructor TWorkSheet.Destroy;
begin
FreeAndNil(FRanges);
FreeAndNil(FCells);
FreeAndNil(FNotes);
FreeAndNil(FColumns);
FreeAndNil(FHLinks);
//FDrawing should be freed after notes
FreeAndNil(FDrawing);
FreeAndNil(FVPageBreaks);
FreeAndNil(FHPageBreaks);
FreeAndNil(FMiscRecords1);
FreeAndNil(FMiscRecords2);
FreeAndNil(FCodeName);
inherited;
end;
procedure TWorkSheet.LoadFromStream(const DataStream: TStream;
const First: TBOFRecord; const SST: TSST);
var
RecordHeader: TRecordHeader;
R: TBaseRecord;
MiscRecords: TBaseRecordList;
FShrFmlas: TShrFmlaRecordList;
LastFormula: TFormulaRecord;
HasStandardWidthRec: boolean;
StdW: integer;
begin
Clear;
MiscRecords:=FMiscRecords1;
FShrFmlas:= TShrFmlaRecordList.Create;
LastFormula:=nil;
HasStandardWidthRec:=false;
StdW:=8;
try
repeat
if (DataStream.Read(RecordHeader, sizeof(RecordHeader)) <> sizeof(RecordHeader)) then
raise Exception.Create(ErrExcelInvalid);
R:=LoadRecord(DataStream, RecordHeader);
try
if RecordHeader.Id=xlr_WINDOW2 then
begin
MiscRecords:=FMiscRecords2;
FWindow2:=R as TWindow2Record;
end;
LoadCachePointers(R);
if (R is TFormulaRecord) then LastFormula:=R as TFormulaRecord;
//It looks like standardwidth is used <-> DefColwidth=8
if (R is TDefColWidthRecord) and (not HasStandardWidthRec or ((R as TDefColWidthRecord).Width<>8)) then begin; StdW:=(R as TDefColWidthRecord).Width;FDefColWidth:= StdW*DefColWidthAdapt;end;
if (R is TStandardWidthRecord) and (StdW=8) then begin HasStandardWidthRec:=true; FDefColWidth:= (R as TStandardWidthRecord).Width;end;
if (R is TDefRowHeightRecord) then FDefRowHeight:= (R as TDefRowHeightRecord).Height;
if (R is TLabelSSTRecord) then (R as TLabelSSTRecord).AttachToSST(SST);
if (R is TBofRecord) then raise Exception.Create(ErrExcelInvalid)
else if (R is TDrawingRecord) then FDrawing.LoadFromStream(DataStream, R as TDrawingRecord, SST)
else if (R is TIgnoreRecord) then FreeAndNil(R)
else if (R is TDimensionsRecord) then begin; OriginalDimensions:=(R as TDimensionsRecord).Dim^; FreeAndNil(R);end
else if (R is TNoteRecord) then FNotes.AddRecord(R as TNoteRecord, (R as TNoteRecord).Row)
else if (R is TColInfoRecord) then FColumns.AddRecord(R as TColInfoRecord)
else if (R is TCellRecord) then FCells.AddCell(R as TCellRecord, (R as TCellRecord).Row)
else if (R is TMultipleValueRecord) then begin FCells.AddMultipleCells(R as TMultipleValueRecord);FreeAndNil(R);end
else if (R is TRowRecord) then FCells.AddRow(R as TRowRecord)
else if (R is TCondFmtRecord) then FRanges[FRanges.Add(TCondFmt.Create)].LoadFromStream(DataStream, R as TCondFmtRecord)
else if (R is TCellMergingRecord) then FRanges[FRanges.Add(TMergedCells.Create)].LoadFromStream(DataStream, R as TCellMergingRecord)
else if (R is THLinkRecord) then FHLinks.Add(R as THLinkRecord)
else if (R is TShrFmlaRecord) then begin if LastFormula=nil then raise Exception.Create(ErrExcelInvalid) else begin; (R as TShrFmlaRecord).Key:=LastFormula.Row+LastFormula.Column shl 16; FShrFmlas.Add(R as TShrFmlaRecord);end end
else if (R is THPageBreakRecord) then FHPageBreaks.AddRecord(R as THPageBreakRecord)
else if (R is TVPageBreakRecord) then FVPageBreaks.AddRecord(R as TVPageBreakRecord)
else if (R is TStringRecord) then begin if LastFormula=nil then raise Exception.Create(ErrExcelInvalid) else LastFormula.SetFormulaValue((R as TStringRecord).Value);FreeAndNil(R);end
else if (R is TArrayRecord) then begin if LastFormula=nil then raise Exception.Create(ErrExcelInvalid) else LastFormula.ArrayRecord:=R as TArrayRecord;end
else if (R is TEOFRecord) then sEOF:=(R as TEOFRecord)
else if (R is TCodeNameRecord) then begin; FreeAndNil(FCodeName); FCodeName:=(R as TCodeNameRecord); end
else MiscRecords.Add(R) ;
except
FreeAndNil(R);
Raise;
end; //Finally
until RecordHeader.id = xlr_EOF;
FNotes.FixDwgIds(FDrawing);
FCells.CellList.FixFormulas(FShrFmlas);
finally
FreeAndNil(FShrFmlas);
end; //finally
FCells.FixRows; //if the file was invalid.
//this must be the last statment, so if there is an exception, we dont take First
sBOF:= First;
end;
procedure TWorkSheet.SaveToStream(const DataStream: TStream);
begin
if (sBOF=nil)or(sEOF=nil) then raise Exception.Create(ErrSectionNotLoaded);
sBOF.SaveToStream(DataStream);
if (FGuts<>nil) and FGuts.RecalcNeeded then
begin
FCells.RowList.CalcGuts(FGuts);
FColumns.CalcGuts(FGuts);
FGuts.RecalcNeeded:=false;
end;
FMiscRecords1.SaveToStream(DataStream);
FHPageBreaks.SaveToStream(DataStream);
FVPageBreaks.SaveToStream(DataStream);
FColumns.SaveToStream(DataStream);
FCells.SaveToStream(DataStream);
FDrawing.SaveToStream(DataStream);
FNotes.SaveToStream(DataStream);
FMiscRecords2.SaveToStream(DataStream);
FRanges.SaveToStream(DataStream);
FHLinks.SaveToStream(DataStream);
if (FCodeName<>nil) then FCodeName.SaveToStream(DataStream);
sEOF.SaveToStream(DataStream);
end;
procedure TWorkSheet.SaveRangeToStream(const DataStream: TStream;
const SheetIndex: integer; const CellRange: TXlsCellRange);
begin
if (sBOF=nil)or(sEOF=nil) then raise Exception.Create(ErrSectionNotLoaded);
sBOF.SaveToStream(DataStream);
FMiscRecords1.SaveToStream(DataStream);
FHPageBreaks.SaveRangeToStream(DataStream, CellRange);
FVPageBreaks.SaveRangeToStream(DataStream, CellRange);
FColumns.SaveRangeToStream(DataStream, CellRange);
FCells.SaveRangeToStream(DataStream, CellRange);
//Excel doesnt save drawings to the clipboard
//FDrawing.SaveToStream(DataStream);
FNotes.SaveRangeToStream(DataStream, CellRange);
FMiscRecords2.SaveToStream(DataStream);
FRanges.SaveRangeToStream(DataStream, CellRange);
FHLinks.SaveRangeToStream(DataStream, CellRange);
if (FCodeName<>nil) then FCodeName.SaveToStream(DataStream);
sEOF.SaveToStream(DataStream);
end;
procedure TWorkSheet.InsertAndCopyRowsAndCols(const FirstRow, LastRow, DestRow, aRowCount,FirstCol, LastCol, DestCol, aColCount: integer; const SheetInfo: TSheetInfo; const OnlyFormulas: boolean);
var
r: TXlsCellRange;
begin
if (aRowCount>0) then
begin
FCells.InsertAndCopyRows(FirstRow, LastRow, DestRow, aRowCount, SheetInfo, OnlyFormulas);
FRanges.InsertAndCopyRowsOrCols(FirstRow, LastRow, DestRow, aRowCount, SheetInfo, false);
FNotes.InsertAndCopyRows(FirstRow, LastRow, DestRow, aRowCount, SheetInfo, false);
FHPageBreaks.InsertRows(DestRow, aRowCount);
r.Left:=0;r.Right:=Max_Columns;r.Top:=FirstRow; r.Bottom:=LastRow;
FHLinks.InsertAndCopyRange(r, DestRow, 0, aRowCount, 0, SheetInfo);
end;
if (aColCount>0) then
begin
FCells.InsertAndCopyCols(FirstCol, LastCol, DestCol, aColCount, SheetInfo, OnlyFormulas);
FRanges.InsertAndCopyRowsOrCols(FirstCol, LastCol, DestCol, aColCount, SheetInfo, true);
FNotes.InsertAndCopyCols(FirstCol, LastCol, DestCol, aColCount, SheetInfo, false);
FVPageBreaks.InsertCols(DestCol, aColCount);
r.Top:=0;r.Bottom:=Max_Rows;r.Left:=FirstCol; r.Right:=LastCol;
FHLinks.InsertAndCopyRange(r, 0, DestCol, 0, aColCount, SheetInfo);
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -