uxlssheet.pas

来自「delphi 第三方控件很出色,表格制作的」· PAS 代码 · 共 1,602 行 · 第 1/4 页

PAS
1,602
字号

  if FSetup<> nil then
  begin
    Result.Header:= FSetup.HeaderMargin;
    Result.Footer:= FSetup.FooterMargin;
  end;

end;

procedure TSheet.SetMargins(const Value: TXlsMargins);
begin
  if FLeftMargin=nil then AddMargin(FLeftMargin, xlr_LEFTMARGIN, Value.Left) else FLeftMargin.Value:=Value.Left;
  if FRightMargin=nil then AddMargin(FRightMargin, xlr_RIGHTMARGIN, Value.Right) else FRightMargin.Value:=Value.Right;
  if FTopMargin=nil then AddMargin(FTopMargin, xlr_TOPMARGIN, Value.Top) else FTopMargin.Value:=Value.Top;
  if FBottomMargin=nil then AddMargin(FBottomMargin, xlr_BOTTOMMARGIN, Value.Bottom) else FBottomMargin.Value:=Value.Bottom;

  if FSetup<> nil then
  begin
    FSetup.HeaderMargin:=Value.Header;
    FSetup.FooterMargin:=Value.Footer;
  end;

end;

procedure TSheet.AddMargin(var Margin: TMarginRecord; const aId: integer;
  const Value: extended);
const
  DataSize=SizeOf(Double);
var
  Data: PArrayOfByte;
  i,k, RId: integer;
begin
  //Search for the best position...
  k:=FPrintRecords.Count-1;
  for i:=FPrintRecords.Count-1 downto 0 do
  begin
    RId:=(FPrintRecords[i] as TBaseRecord).Id;
    if (RId=xlr_LEFTMARGIN) or(RId=xlr_RIGHTMARGIN)
       or(RId=xlr_TOPMARGIN) or(RId=xlr_BOTTOMMARGIN)
       or (RId=xlr_VCENTER)or (RId=xlr_DEFAULTROWHEIGHT)then
    begin
      k:=i;
      break;
    end;
  end;
  GetMem(Data, DataSize);
  try
    FPrintRecords.Insert(k +1,TMarginRecord.Create(aId, Data, DataSize));
  except
    FreeMem(Data);
    raise;
  end; //Except
  Margin:=(FPrintRecords[k+1] as TMarginRecord);
  Margin.Value:=Value;
end;

function TSheet.GetSheetZoom: integer;
begin
  if FZoom<>nil then Result:=FZoom.Zoom else Result:=100;
end;

procedure TSheet.SetSheetZoom(const Value: integer);
begin
  if FZoom=nil then AddZoomRecord;
  if FZoom=nil then exit;
  FZoom.Zoom:=Value;
end;

procedure TSheet.FixCachePointers;
begin
  //Nothing here.
end;

procedure TSheet.LoadCachePointers(const R: TBaseRecord);

begin
  if R = nil then exit;

  if R.Id=xlr_WINDOW2 then FWindow2:=R as TWindow2Record else
  if R.Id=xlr_SCL then FZoom:=R as TSCLRecord else
  if R.Id=xlr_FOOTER then FPageFooter:=R as TPageFooterRecord else
  if R.Id=xlr_HEADER then FPageHeader:=R as TPageHeaderRecord else
  if R.Id=xlr_PRINTGRIDLINES then FPrintGridLines:=R as TPrintGridLinesRecord else

  if R.Id=xlr_LEFTMARGIN then FLeftMargin:=R as TMarginRecord else
  if R.Id=xlr_RIGHTMARGIN then FRightMargin:=R as TMarginRecord else
  if R.Id=xlr_TOPMARGIN then FTopMargin:=R as TMarginRecord else
  if R.Id=xlr_BOTTOMMARGIN then FBottomMargin:=R as TMarginRecord else

  if R.Id=xlr_SETUP then FSetup:=R as TSetupRecord else
  if R.Id=xlr_WSBool then FWsBool:=R as TWsBoolRecord;

  if R.Id=xlr_GUTS then FGuts:=R as TGutsRecord;
end;

function TSheet.TotalRangeSize(const SheetIndex: integer;
  const CellRange: TXlsCellRange): int64;
begin
  Result:= inherited TotalRangeSize(SheetIndex, CellRange);
  if (FCodeName<>nil) then inc(Result, FCodeName.TotalSize);
end;

function TSheet.TotalSize: int64;
begin
  Result:= inherited TotalSize;
  if (FCodeName<>nil) then inc(Result, FCodeName.TotalSize);
end;

function TSheet.GetCodeName: widestring;
begin
  if FCodeName<>nil then Result:=FCodeName.SheetName else Result:='';
end;

procedure TSheet.SetCodeName(const Value: widestring);
begin
  FreeAndNil(FCodeName);
  FCodeName:=TCodeNameRecord.CreateNew(Value);
end;

{ TFlxChart }

procedure TFlxChart.ArrangeCopyRowsAndCols(const RowOffset, ColOffset: integer);
begin
  FChartRecords.ArrangeCopyRowsAndCols(RowOffset, ColOffset);
end;

procedure TFlxChart.ArrangeCopySheet(const SheetInfo: TSheetInfo);
begin
  FChartRecords.ArrangeCopySheet(SheetInfo);
end;

procedure TFlxChart.InsertAndCopyRowsAndCols(const FirstRow, LastRow, DestRow, aRowCount,FirstCol, LastCol, DestCol, aColCount: integer; const SheetInfo: TSheetInfo; const OnlyFormulas: boolean);
begin
  //Nothing, we never insert rows in a chart sheet
end;

procedure TFlxChart.DeleteRowsAndCols(const aRow, aRowCount, aCol, aColCount: word; const SheetInfo: TSheetInfo);
begin
  //Nothing, we never delete rows in a chart sheet
end;

procedure TFlxChart.Clear;
begin
  inherited;
  if FChartRecords<>nil then FChartRecords.Clear;
  //We don't clear CodeName.
end;

function TFlxChart.DoCopyTo: TSheet;
begin
  Result:= inherited DoCopyTo;
  (Result as TFlxChart).FChartRecords.CopyFrom(FChartRecords);
  (Result as TFlxChart).FPrintRecords:=(Result as TFlxChart).FChartRecords;
  Result.FixCachePointers;
end;

constructor TFlxChart.Create(const aWorkbookGlobals: TWorkbookGlobals);
begin
  inherited;
  FChartRecords:= TChartRecordList.Create;
  FPrintRecords:=FChartRecords;
end;

destructor TFlxChart.Destroy;
begin
  FreeAndNil(FChartRecords);
  FreeAndNil(FCodeName);
  inherited;
end;

procedure TFlxChart.LoadFromStream(const DataStream: TStream;
  const First: TBOFRecord; const SST: TSST);
var
  RecordHeader: TRecordHeader;
  R: TBaseRecord;
begin
  Clear;
  repeat
    if (DataStream.Read(RecordHeader, sizeof(RecordHeader)) <> sizeof(RecordHeader)) then
      raise Exception.Create(ErrExcelInvalid);

    R:=LoadRecord(DataStream, RecordHeader);
    try
      LoadCachePointers(R);

      if (R is TLabelSSTRecord) then (R as TLabelSSTRecord).AttachToSST(SST);
      if (R is TBofRecord) then raise Exception.Create(ErrExcelInvalid)
      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 TEOFRecord) then sEOF:=(R as TEOFRecord)
      else if (R is TCodeNameRecord) then begin; FreeAndNil(FCodeName); FCodeName:=(R as TCodeNameRecord); end
      else FChartRecords.Add(R) ;
    except
      FreeAndNil(R);
      Raise;
    end; //Finally

  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;

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;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?