Search Results for

    Show / Hide Table of Contents

    Copy and paste (Delphi)

    Note

    This demo is available in your FlexCel installation at <FlexCel Install Folder>\Demo\Delphi\Modules\10.API\40.Copy And Paste and also at https:​//​github.​com/​tmssoftware/​TMS-​FlexCel.​VCL-​demos/​tree/​master/​Delphi/​Modules/​10.​API/​40.​Copy And Paste

    Overview

    ExcelFile has a group of methods allowing you to copy/paste from/to FlexCel to/from Excel in native Excel format. All methods copy and paste the data on BIFF8 and Tabbed-Text format, to allow for copying/pasting from other sources besides Excel.

    Copying and pasting in native BIFF8 format is a great advance over copying/pasting on plain text only. It allows you to keep cell formats/colors/rounding decimals/merged cells/etc. It allows a new world of interoperation between your applications and Excel. Your users will be able to interchange data back and forward between your application and Excel just by copying and pasting. But keep in mind that it has its limitations too:

    • It can't copy/paste images

    • It can't copy/paste strings longer than 255 characters

    • It can't copy the data on multiple sheets.

    I would like to say that these limitations are not FlexCel's fault. The BIFF8 specification is correctly implemented, those are limitations on Excel's part.

    Of course, Excel can copy and paste everything without problems, but this is so because Excel doesn't use the clipboard to do the operation. If you close all instances of Excel, open a Worksheet, copy some cells to the clipboard, close Excel and open it again you will run into the same limitations. Copy/paste limitations on Excel don't show when it is kept in memory.

    Concepts

    • FlexCel methods return datastreams for maximum flexibility. No data will be actually copied/pasted from/to the clipboard by FlexCel, this is your task. Here you can see how it is done.

    Files

    UCopyAndPaste.pas

    unit UCopyAndPaste;
    
    interface
    
    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics,
      Controls, Forms, Dialogs, StdCtrls, ExtCtrls, Clipbrd,
      FlexCel.VCLSupport, FlexCel.Core, FlexCel.XlsAdapter,
      FlexCel.Render;
    
    type
      TForm2 = class(TForm)
        Panel1: TPanel;
        Panel2: TPanel;
        btnNewFile: TButton;
        Panel3: TPanel;
        Panel4: TPanel;
        btnPaste: TButton;
        Panel5: TPanel;
        Panel6: TPanel;
        btnCopy: TButton;
        btnOpenFile: TButton;
        OpenDialog: TOpenDialog;
        procedure btnNewFileClick(Sender: TObject);
        procedure btnPasteClick(Sender: TObject);
        procedure btnCopyClick(Sender: TObject);
        procedure FormDestroy(Sender: TObject);
        procedure btnOpenFileClick(Sender: TObject);
      private
        Xls: TXlsFile;
    
        procedure DoPaste;
      public
        { Public declarations }
      end;
    
    var
      Form2: TForm2;
    
    implementation
    
    {$R *.dfm}
    
    procedure TForm2.FormDestroy(Sender: TObject);
    begin
      FreeAndNil(Xls);
    end;
    
    procedure TForm2.btnNewFileClick(Sender: TObject);
    begin
      FreeAndNil(Xls);
      Xls := TXlsFile.Create(1, TExcelFileFormat.v2016, false);
    end;
    
    procedure TForm2.btnOpenFileClick(Sender: TObject);
    begin
      if not OpenDialog.Execute then exit;
    
      FreeAndNil(Xls);
      Xls := TXlsFile.Create(OpenDialog.Filename, false);
    end;
    
    procedure TForm2.btnPasteClick(Sender: TObject);
    begin
      DoPaste;
    end;
    
    procedure PasteFromBiff8(const Xls: TExcelFile; const Row, Col: integer);
    var
      MyHandle: THandle;
      BiffPtr: pointer;
      BiffSize: Cardinal;
      MemStream: TMemoryStream;
    begin
      ClipBoard.Open;
      try
        MyHandle := Clipboard.GetAsHandle(RegisterClipboardFormat('Biff8'));
        BiffPtr := GlobalLock(MyHandle);
        try
          BiffSize := GlobalSize(MyHandle);
          MemStream := TMemoryStream.Create;
          try
            MemStream.Write(BiffPtr^, BiffSize);
            MemStream.Position := 0;
            Xls.PasteFromXlsClipboardFormat(Row, Col, TFlxInsertMode.NoneDown, MemStream);
    
          finally
            FreeAndNil(MemStream);
          end; //finally
        finally
          GlobalUnlock(MyHandle);
        end;
      finally
        Clipboard.Close;
      end;
    end;
    
    
    procedure TForm2.DoPaste;
    begin
      if (Xls = nil) then
      begin
        ShowMessage('Please push the New File button before pasting');
        exit;
      end;
    
      try
        if Clipboard.HasFormat(RegisterClipboardFormat('Biff8')) then
        begin
          PasteFromBiff8(Xls, 1, 1);
          ShowMessage('NATIVE Data has been pasted at cell A1');
          exit;
        end;
    
        if Clipboard.HasFormat(CF_TEXT) or Clipboard.HasFormat(CF_UNICODETEXT) then
        begin
          Xls.PasteFromTextClipboardFormat(1, 1, TFlxInsertMode.NoneDown, Clipboard.AsText);
          ShowMessage('TEXT Data has been pasted at cell A1');
          exit;
        end;
    
        ShowMessage('There is no Excel or Text data on the clipboard.');
    
      except on ex: Exception do
        begin
          ShowMessage(ex.Message);
          FreeAndNil(Xls);
          Xls := TXlsFile.Create(1, false);
        end;
      end;
    end;
    
    procedure CopyToClipboard(const DataFormat: TFlexCelClipboardFormat; const DataStream: TStream);
    var
      MyHandle: THandle;
      BiffPtr: pointer;
      FreeHandle: boolean;
      Df: string;
    begin
      DataStream.Position := 0;
      FreeHandle := true;
      MyHandle := GlobalAlloc(GMEM_MOVEABLE, DataStream.Size);
      try
        BiffPtr := GlobalLock(MyHandle);
        try
          DataStream.ReadBuffer(BiffPtr^, DataStream.Size);
        finally
          GlobalUnlock(MyHandle);
        end; //finally
    
        Clipboard.Open;
        try
          //Text format is standard, must be handled differently.
          if DataFormat = TFlexCelClipboardFormat.Text then
          begin
             //Setting CF_UNICODE_TEXT will also set CF_TEXT and CF_OEMTEXT
             Clipboard.SetAsHandle(CF_UNICODETEXT, MyHandle);
          end else
          begin
            //Other formats than TEXT must be registered with RegisterClipboardFormat.
            Df := TFlexCelDataFormats.GetString(DataFormat);
            Clipboard.SetAsHandle(RegisterClipboardFormat(PChar(Df)), MyHandle);
          end;
          FreeHandle := false;       //Note that we dont have to free MyHandle if the clipboard takes care of it
        finally
          Clipboard.Close;
        end; //Finally
      except
        if FreeHandle then GlobalFree(MyHandle);
        raise
      end; //except
    end;
    
    procedure TForm2.btnCopyClick(Sender: TObject);
    var
      DataStream: TStream;
      cf: TFlexCelClipboardFormat;
    begin
      if (Xls = nil) then
      begin
        ShowMessage('Please push the New File button before copying');
        exit;
      end;
    
      try
        Clipboard.Clear;
        Clipboard.Open; //The other open calls in CopyToCliboard will be ignored.
        try
          for cf := Low(TFlexCelClipboardFormat) to High(TFlexCelClipboardFormat) do
          begin
            DataStream := TMemoryStream.Create;
            try
              Xls.CopyToClipboard(cf, DataStream);
              CopyToClipboard(cf, DataStream);
            finally
              FreeAndNil(DataStream)
            end;
          end;
        finally
          Clipboard.Close;
        end;
        except on ex: Exception do
        begin
          ShowMessage(ex.Message);
        end;
      end;
    end;
    
    end.
    
    In This Article
    Back to top FlexCel Studio for VCL and FireMonkey v7.24
    © 2002 - 2025 tmssoftware.com