⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uxlsescher.pas

📁 TMS Component Pack Pro v4.2
💻 PAS
📖 第 1 页 / 共 2 页
字号:
end;

function TDrawing.GetDrawingRow(index: integer): integer;
begin
  Assert(Index<FRecordCache.Blip.Count,'Index out of range');
  Result:=FRecordCache.Blip[index].Row;
end;

procedure TDrawing.InsertAndCopyRowsAndCols(const FirstRow, LastRow, DestRow, RowCount, FirstCol, LastCol, DestCol,
  ColCount: integer; const SheetInfo: TSheetInfo);
var
  i,k, myDestRow, myFirstRow, myLastRow, myDestCol, myFirstCol, myLastCol: integer;
begin
  if (FDgContainer=nil) or (FRecordCache.Anchor= nil) then exit;  //no drawings on this sheet

  if DestRow>FirstRow then
  begin
    myFirstRow:=FirstRow; myLastRow:=LastRow;
  end else
  begin
    myFirstRow:=FirstRow+RowCount*(LastRow-FirstRow+1);
    myLastRow:=LastRow+RowCount*(LastRow-FirstRow+1);
  end;

  if DestCol>FirstCol then
  begin
    myFirstCol:=FirstCol; myLastCol:=LastCol;
  end else
  begin
    myFirstCol:=FirstCol+ColCount*(LastCol-FirstCol+1);
    myLastCol:=LastCol+ColCount*(LastCol-FirstCol+1);
  end;

  //Insert cells
  ArrangeInsertRowsAndCols(DestRow, RowCount*(LastRow-FirstRow+1), DestCol, ColCount*(LastCol-FirstCol+1), SheetInfo);

  //Copy the images
  //First the rows...
  myDestRow:=DestRow;
  for k:= 0 to RowCount-1 do
  begin
    FDgContainer.ClearCopiedTo;
    for i:= 0 to FRecordCache.Anchor.Count-1 do
      if FRecordCache.Anchor[i].AllowCopy(myFirstRow, myLastRow, 0, Max_Columns+1)then
      begin
         FRecordCache.Anchor[i].CopyDwg(myDestRow-myFirstRow,0);
      end;
    inc(myDestRow, (LastRow-FirstRow+1));
    if FRecordCache.Solver<>nil then FRecordCache.Solver.ArrangeCopyRowsAndCols;
  end;

  //Now the columns... as we already copied the rows, now we will make an array of images
  myDestCol:=DestCol;
  for k:= 0 to ColCount-1 do
  begin
    FDgContainer.ClearCopiedTo;
    for i:= 0 to FRecordCache.Anchor.Count-1 do
      if FRecordCache.Anchor[i].AllowCopy(0, Max_Rows+1, myFirstCol, myLastCol)then
      begin
         FRecordCache.Anchor[i].CopyDwg(0, myDestCol-myFirstCol);
      end;
    inc(myDestCol, (LastCol-FirstCol+1));
    if FRecordCache.Solver<>nil then FRecordCache.Solver.ArrangeCopyRowsAndCols();
  end;

end;

procedure TDrawing.CreateBasicDrawingInfo;
var
  EscherHeader: TEscherRecordHeader;
  Dg: TEscherDgRecord;
  SPRec: TEscherSpContainerRecord;
  SPgrRec:TEscherDataRecord;
  SP: TEscherSPRecord;
begin
  Assert (FDrawingGroup<>nil,'DrawingGroup can''t be nil');
  FRecordCache.MaxObjId:=0;
  FRecordCache.Dg:=nil; FRecordCache.Patriarch:=nil; FRecordCache.Solver:=nil;

  FRecordCache.Anchor:= TEscherAnchorCache.Create;
  FRecordCache.Obj:= TEscherObjCache.Create;
  FRecordCache.Shape:= TEscherShapeCache.Create;
  FRecordCache.Blip:=TEscherOPTCache.Create;

  EscherHeader.Pre:=$F;
  EscherHeader.Id:=MsofbtDgContainer;
  EscherHeader.Size:=0;
  FDgContainer:=TEscherContainerRecord.Create(EscherHeader, FDrawingGroup.RecordCache, @FRecordCache ,nil);
  FDrawingGroup.AddDwg;

  //Add required records...
  Dg:=TEscherDgRecord.CreateFromData(0,$401,FDrawingGroup.RecordCache, @FRecordCache, FDgContainer);
  FDgContainer.ContainedRecords.Add(Dg);

  EscherHeader.Pre:=$F;
  EscherHeader.Id:=MsofbtSpgrContainer;
  EscherHeader.Size:=0;
  FRecordCache.Patriarch:= TEscherSpgrContainerRecord.Create(EscherHeader, FDrawingGroup.RecordCache, @FRecordCache, FDgContainer);
  FDgContainer.ContainedRecords.Add(FRecordCache.Patriarch);

  EscherHeader.Id:=MsofbtSpContainer;
  EscherHeader.Pre:=$F;
  EscherHeader.Size:=0; //Size for a container is calculated later
  SPRec:=TEscherSpContainerRecord.Create(EscherHeader, FDrawingGroup.RecordCache, @FRecordCache, FRecordCache.Patriarch);
  SPRec.LoadedDataSize:=EscherHeader.Size;
  FRecordCache.Patriarch.ContainedRecords.Add(SPRec);

  EscherHeader.Id:=MsofbtSpgr;
  EscherHeader.Pre:=$1;
  EscherHeader.Size:=16;
  SPgrRec:=TEscherDataRecord.Create(EscherHeader, FDrawingGroup.RecordCache, @FRecordCache, FRecordCache.Patriarch);
  SPgrRec.LoadedDataSize:=EscherHeader.Size;
  SPgrRec.ClearData;
  SPRec.ContainedRecords.Add(SPgrRec);

  SP:=TEscherSPRecord.CreateFromData($2,FRecordCache.Dg.IncMaxShapeId, $5 , FDrawingGroup.RecordCache, @FRecordCache, SPRec);
  SPRec.ContainedRecords.Add(SP);


end;

procedure TDrawing.AddImage(Data: string; DataType: TXlsImgTypes; const Properties: TImageProperties;const Anchor: TFlxAnchorType);
var
  SPRec: TEscherSpContainerRecord;
  AnchorRec: TEscherClientAnchorRecord;
  RecordHeader: TEscherRecordHeader;
  ClientAnchor: TClientAnchor;
  ClientData: TEscherClientDataRecord;
  SP: TEscherSPRecord;
  OPTRec:TEscherOPTRecord;
begin
  if Data='' then
  begin
    Data:=EmptyBmp;
    DataType:=xli_Bmp;
  end;
  if (FDgContainer=nil) or (FRecordCache.Anchor= nil) then //no drawings on this sheet
    CreateBasicDrawingInfo;

  if (FRecordCache.Patriarch=nil) then raise Exception.Create(ErrLoadingEscher);

  RecordHeader.Id:=MsofbtSpContainer;
  RecordHeader.Pre:=$F;
  RecordHeader.Size:=0; //Size for a container is calculated later
  SPRec:=TEscherSpContainerRecord.Create(RecordHeader, FDrawingGroup.RecordCache, @FRecordCache, FRecordCache.Patriarch);
  SPRec.LoadedDataSize:=RecordHeader.Size;

  SP:=TEscherSPRecord.CreateFromData($04B2, FRecordCache.Dg.IncMaxShapeId, $A00 , FDrawingGroup.RecordCache, @FRecordCache, SPRec);
  SPRec.ContainedRecords.Add(SP);

  OPTRec:=TEscherOPTRecord.CreateFromDataImg(Data, DataType, Properties.FileName, FDrawingGroup.RecordCache, @FRecordCache, SPRec);
  SPRec.ContainedRecords.Add(OPTRec);

  RecordHeader.Id:=MsofbtClientAnchor;
  RecordHeader.Pre:=0;
  RecordHeader.Size:=SizeOf(TClientAnchor);
  case Anchor of
    at_MoveAndResize: ClientAnchor.Flag:=00;
    at_DontMoveAndDontResize: ClientAnchor.Flag:=03;
    else ClientAnchor.Flag:=02;
  end; //case

  ClientAnchor.Col1:=Properties.Col1;
  ClientAnchor.Dx1:=Properties.dx1;
  ClientAnchor.Col2:=Properties.Col2;
  ClientAnchor.Dx2:=Properties.dx2;
  ClientAnchor.Row1:=Properties.Row1;
  ClientAnchor.Dy1:=Properties.dy1;
  ClientAnchor.Row2:=Properties.Row2;
  ClientAnchor.Dy2:=Properties.dy2;
  AnchorRec:=TEscherClientAnchorRecord.CreateFromData(ClientAnchor, RecordHeader, FDrawingGroup.RecordCache, @FRecordCache, SPRec);
  SPRec.ContainedRecords.Add(AnchorRec);


  RecordHeader.Id:=MsofbtClientData;
  RecordHeader.Pre:=0;
  RecordHeader.Size:=0;
  ClientData:= TEscherClientDataRecord.Create(RecordHeader, FDrawingGroup.RecordCache, @FRecordCache, SPRec);
  ClientData.AssignClientData(TMsObj.CreateEmptyImg(FRecordCache.MaxObjId));
  ClientData.LoadedDataSize:=RecordHeader.Size;
  SPRec.ContainedRecords.Add(ClientData);
  FRecordCache.Patriarch.ContainedRecords.Add(SPRec);
end;

procedure TDrawing.LoadFromStream(const DataStream: TStream;
  const First: TDrawingRecord; const SST: TSST);
var
  aPos, CdPos: integer;
  EscherHeader: TEscherRecordHeader;
  RecordHeader: TRecordHeader;
  MyRecord, CurrentRecord, R, CdRecord: TBaseRecord;
  FClientData: TBaseClientData;
  ClientType: ClassOfTBaseClientData;
begin
  Assert (FDrawingGroup<>nil,'DrawingGroup can''t be nil');
  if FDgContainer<>nil then raise Exception.Create(ErrExcelInvalid);

  FRecordCache.MaxObjId:=0;
  FRecordCache.Dg:=nil; FRecordCache.Patriarch:=nil; FRecordCache.Solver:=nil;
  FRecordCache.Anchor:= TEscherAnchorCache.Create;
  FRecordCache.Obj:= TEscherObjCache.Create;
  FRecordCache.Shape:= TEscherShapeCache.Create;
  FRecordCache.Blip:= TEscherOPTCache.Create;

  aPos:=0;
  MyRecord:= First; CurrentRecord:= First;
  try
    ReadMem(MyRecord, aPos, SizeOf(EscherHeader), @EscherHeader);
    FDgContainer:= TEscherContainerRecord.Create(EscherHeader, FDrawingGroup.RecordCache, @FRecordCache ,nil);
    while (not FDgContainer.Loaded) or FDgContainer.WaitingClientData(ClientType) do
    begin
      if not FDgContainer.WaitingClientData(ClientType) then
      begin
        if (MyRecord.Continue=nil) and (aPos=MyRecord.DataSize) then
        begin
          if CurrentRecord<> First then FreeAndNil(CurrentRecord);
          if (DataStream.Read(RecordHeader, sizeof(RecordHeader)) <> sizeof(RecordHeader)) then
            raise Exception.Create(ErrExcelInvalid);
          CurrentRecord:=LoadRecord(DataStream, RecordHeader);
          MyRecord:= CurrentRecord;
          aPos:=0;
          if not(MyRecord is TDrawingRecord) then raise Exception.Create(ErrExcelInvalid);
        end;
        FDgContainer.Load(MyRecord, aPos);
      end else
      begin
        if not ((MyRecord.Continue=nil) and (aPos=MyRecord.DataSize)) then raise Exception.Create(ErrExcelInvalid);
        if (DataStream.Read(RecordHeader, sizeof(RecordHeader)) <> sizeof(RecordHeader)) then
          raise Exception.Create(ErrExcelInvalid);

         R:=LoadRecord(DataStream, RecordHeader);
         try
           if (R is ClientType.ObjRecord) then
           begin
             FClientData:= ClientType.Create;
             try
               FClientData.LoadFromStream(DataStream, R , SST);
               FDgContainer.AssignClientData(FClientData);
               if FClientData.RemainingData<>nil then
               begin
                 CdRecord:=FClientData.RemainingData; //we dont have to free this
                 CdPos:=0;
                 FDgContainer.Load(CdRecord, CdPos);
               end;
             except
               FreeAndNil(FClientData);
               raise;
             end; //except
           end else raise Exception.Create(ErrInvalidDrawing);
         except
           FreeAndNil(R);
           raise;
         end; //Except
      end;

    end; //while
  finally
    if CurrentRecord<>First then FreeAndNil(CurrentRecord);
  end; //finally

  FRecordCache.Shape.Sort; // only here the values are loaded...
  if FRecordCache.Solver <>nil then FRecordCache.Solver.FixPointers;


  //PENDING: Wmf, emf

  First.Free;   //last statment
end;

procedure TDrawing.SaveToStream(const DataStream: TStream);
var
  BreakList: TBreakList;
  NextPos, RealSize, NewDwg: integer;
begin
  if FDgContainer=nil then exit;
  BreakList:= TBreakList.Create(DataStream.Position);
  try
    NextPos:=0;
    RealSize:=0;
    NewDwg:= xlr_MSODRAWING;
    FDgContainer.SplitRecords(NextPos, RealSize, NewDwg, BreakList);
    BreakList.Add(0, NextPos);
    FDgContainer.SaveToStream(DataStream, BreakList);
  finally
    FreeAndNil(BreakList);
  end; //finally
end;

function TDrawing.TotalSize: int64;
var
  NextPos, RealSize, NewDwg: integer;
begin
  if FDgContainer=nil then begin Result:=0; exit;end;

  NextPos:=0; RealSize:=0; NewDwg:= xlr_MSODRAWINGGROUP;
  FDgContainer.SplitRecords(NextPos, RealSize, NewDwg, nil);
  Result:=RealSize;
end;

function TDrawing.AddNewComment(const Properties: TImageProperties): TEscherClientDataRecord;
var
  aTXO: TTXO;
  aMsObj: TMsObj;
  SP: TEscherSPRecord;
  SPRec: TEscherSpContainerRecord;
  RecordHeader: TEscherRecordHeader;
  TXORec: TEscherClientTextBoxRecord;
  Obj: TEscherClientDataRecord;
  ClientAnchor: TClientAnchor;
  AnchorRec: TEscherClientAnchorRecord;
  OPTRec:TEscherOPTRecord;
begin
  FDrawingGroup.EnsureDwgGroup;
  if (FDgContainer=nil) or (FRecordCache.Anchor= nil) then //no drawings on this sheet
    CreateBasicDrawingInfo;

  RecordHeader.Id:=MsofbtSpContainer;
  RecordHeader.Pre:=$F;
  RecordHeader.Size:=0; //Size for a container is calculated later
  SPRec:=TEscherSpContainerRecord.Create(RecordHeader, FDrawingGroup.RecordCache, @FRecordCache, FRecordCache.Patriarch);
  try
    SPRec.LoadedDataSize:=RecordHeader.Size;

    SP:=TEscherSPRecord.CreateFromData($0CA2, FRecordCache.Dg.IncMaxShapeId, $A00 , FDrawingGroup.RecordCache, @FRecordCache, SPRec);
    try
      SPRec.ContainedRecords.Add(SP);
    except
      FreeAndNil(SP);
      raise;
    end; //except

    OPTRec:=TEscherOPTRecord.CreateFromDataNote(FDrawingGroup.RecordCache, @FRecordCache, SPRec);
    try
      SPRec.ContainedRecords.Add(OPTRec);
    except
      FreeAndNil(OPTRec);
      raise;
    end; //except
    
    RecordHeader.Id:=MsofbtClientAnchor;
    RecordHeader.Pre:=0;
    RecordHeader.Size:=SizeOf(TClientAnchor);
    ClientAnchor.Flag:=03;

    ClientAnchor.Col1:=Properties.Col1;
    ClientAnchor.Dx1:=Properties.dx1;
    ClientAnchor.Col2:=Properties.Col2;
    ClientAnchor.Dx2:=Properties.dx2;
    ClientAnchor.Row1:=Properties.Row1;
    ClientAnchor.Dy1:=Properties.dy1;
    ClientAnchor.Row2:=Properties.Row2;
    ClientAnchor.Dy2:=Properties.dy2;
    AnchorRec:=TEscherClientAnchorRecord.CreateFromData(ClientAnchor, RecordHeader, FDrawingGroup.RecordCache, @FRecordCache, SPRec);
    try
      SPRec.ContainedRecords.Add(AnchorRec);
    except
      FreeAndNil(AnchorRec);
      raise;
    end;

    Obj:=TEscherClientDataRecord.CreateFromData(FDrawingGroup.RecordCache, @FRecordCache, SPRec);
    try
      aMsObj:=TMsObj.CreateEmptyNote(FRecordCache.MaxObjId);
      try
        Obj.AssignClientData(aMsObj);
      except
        FreeAndNil(aMsObj);
        raise;
      end; //Except

      SPRec.ContainedRecords.Add(Obj);
    except
      FreeAndNil(Obj);
      raise;
    end;

    TXORec:= TEscherClientTextBoxRecord.CreateFromData(FDrawingGroup.RecordCache, @FRecordCache, SPRec);
    try
      aTXO:=TTXO.CreateFromData;
      try
        TXORec.AssignClientData(aTXO);
      except
        FreeAndNil(aTXO);
        raise;
      end;
      SPRec.ContainedRecords.Add(TXORec);
    except
      FreeAndNil(TXORec);
      raise;
    end; //except

    FRecordCache.Patriarch.ContainedRecords.Add(SPRec);
  except
    FreeAndNil(SPRec);
    raise;
  end; //except

  Result:=Obj;
end;


end.

⌨️ 快捷键说明

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