如何格式化剪贴板中的行和列来粘贴就像来自Excel?

我正在使用一堆网格,这些网格不支持像Excel那样的表格布局复制行和列。

我们需要能够从网格中复制一些行和列,然后将它们粘贴到一个Outlook格式的正确alignment的列中。 如果你从Excel复制,它很好。

如果我从网格复制,我得到制表符分隔的数据,这是行不通的。 此外,字体不像Courier那样等宽,因此将数据填充到相同数量的字符也不起作用。

我真的很想知道Excel如何设置额外的格式到剪贴板。 顺便说一句,我用delphi,但任何build议表示赞赏。

编辑 :我们不想先通过Excel …我们想直接从网格到剪贴板,然后到电子邮件。

谢谢! 巴特

当您从Excel复制到剪贴板时,剪贴板上会放置许多不同的格式。 您需要find可以复制的格式之一,然后才能获得所需的结果。

我过去实现这个的方式是把HTML放在剪贴板上。 您可以使用这个function:

 procedure ClipboardError; begin raise EMyExceptionClass.Create('Could not complete clipboard operation.'); end; procedure CheckClipboardHandle(Handle: Windows.HGLOBAL); begin if Handle=0 then begin ClipboardError; end; end; procedure CheckClipboardPtr(Ptr: Pointer); begin if not Assigned(Ptr) then begin ClipboardError; end; end; procedure PutInClipboard(ClipboardFormat: UINT; Buffer: Pointer; Count: Integer); var Handle: Windows.HGLOBAL; Ptr: Pointer; begin if Count>0 then begin Clipboard.Open; Try Handle := Windows.GlobalAlloc(GMEM_MOVEABLE, Count); Try CheckClipboardHandle(Handle); Ptr := Windows.GlobalLock(Handle); CheckClipboardPtr(Ptr); Move(Buffer^, Ptr^, Count); Windows.GlobalUnlock(Handle); Clipboard.SetAsHandle(ClipboardFormat, Handle); Except GlobalFree(Handle); raise; End; Finally Clipboard.Close; End; end; end; var HTMLClipboardFormat: UINT; procedure PutHTMLInClipboard(Strings: TStrings); var Data: TStringList; procedure WriteDescription(const StartOffset, EndOffset: Integer); begin while Data.Count<5 do begin Data.Add(''); end; Data[0] := 'Version:0.9'; Data[1] := Format('StartHTML:%.8d', [StartOffset]); Data[2] := Format('EndHTML:%.8d', [EndOffset]); Data[3] := Format('StartFragment:%.8d', [StartOffset]); Data[4] := Format('EndFragment:%.8d', [EndOffset]); end; var StartOffset, EndOffset: Integer; Text: UTF8String; begin Data := TStringList.Create; Try WriteDescription(0, 0);//write out description stub - will be replaced later StartOffset := Length(UTF8String(Data.Text)); Data.AddStrings(Strings); EndOffset := Length(UTF8String(Data.Text))-1; WriteDescription(StartOffset, EndOffset);//now we know the offsets we can write proper description Text := Data.Text; PutInClipBoard(HTMLClipboardFormat, PAnsiChar(Text), Length(Text)); Finally FreeAndNil(Data); End; end; .... initialization HTMLClipboardFormat := Windows.RegisterClipboardFormat('HTML Format'); 

唯一剩下的就是生成传递给该函数的HTML。 这是给你的。 我build议你使用Excel将HTML放在剪贴板上,然后检查它生成的HTML。 用它作为你需要做的事情的指南。

您可以使用此function将您的网格内容导出到Excel以及支持表格数据的其他应用程序:

 procedure ExportDBGrid(DBGrid: TDBGrid; toExcel: Boolean); var bm: TBookmark; col, row: Integer; sline: String; mem: TStringList; ExcelApp: Variant; begin Screen.Cursor := crHourglass; try DBGrid.DataSource.DataSet.DisableControls; bm := DBGrid.DataSource.DataSet.GetBookmark; DBGrid.DataSource.DataSet.First; // create the Excel object if toExcel then begin ExcelApp := CreateOleObject('Excel.Application'); ExcelApp.WorkBooks.Add(1); //xlWBatWorkSheet); ExcelApp.WorkBooks[1].WorkSheets[1].Name := 'Grid Data'; end; // First we send the data to a memo // works faster than doing it directly to Excel mem := TStringList.Create; try sline := ''; // add the info for the column names for col := 0 to DBGrid.FieldCount-1 do if Assigned(DBGrid.Fields[col]) then if DBGrid.Fields[col].Visible then sline := sline + DBGrid.Fields[col].DisplayLabel + #9; mem.Add(sline); // get the data into the memo for row := 0 to DBGrid.DataSource.DataSet.RecordCount-1 do begin sline := ''; for col := 0 to DBGrid.FieldCount-1 do if Assigned(DBGrid.Fields[col]) then if DBGrid.Fields[col].Visible then sline := sline + DBGrid.Fields[col].AsString + #9; mem.Add(sline); DBGrid.DataSource.DataSet.Next; end; // we copy the data to the clipboard Clipboard.AsText := mem.Text; finally mem.Free; end; // if needed, send it to Excel // if not, we already have it in the clipboard if toExcel then begin ExcelApp.Workbooks[1].WorkSheets['Grid Data'].Paste; ExcelApp.Visible := true; end; finally DBGrid.DataSource.DataSet.GotoBookmark(bm); DBGrid.DataSource.DataSet.EnableControls; Screen.Cursor := crDefault; end; end;