2005/10/16 | 在delphi中调用excel [1]
类别(语言类学习笔记) | 评论(0) | 阅读(695) | 发表于 16:10
在delphi中调用excel

在delphi中调用excel有四种方式,我们选取其中的一种用OleObject来装载excel工作表的方式来谈delphi控制excel的重要属性和方法。

首先给出通过OLE创建的一些主要代码步进行简单说明:

创建OLE对象:

Var olecon: TOleContainer;
Olecon:= TOleContainer.Create(self);
Olecon.oleobject:= Olecon.CreateObject('excel.sheet',false);

或选择导入一个excel文件来创建OLE对象:

Olecon.oleobject:= Olecon.CreateObjectFromFile(xlsname,false);

最好隐藏excel的几个工具条,这样就好象是嵌在你的程序中的一个表而已了:

Olecon.OleObject.application.CommandBars['Standard'].Visible:=false;
Olecon.OleObject.application.CommandBars['Formatting'].Visible:=false;
Olecon.OleObject.application.CommandBars['Reviewing'].Visible:=false;

然后显示并激活excel表,对TOleContainer定义的对象:

Olecon.show;
Olecon.doverb(0);

这样基本可以了,但TOleContainer有个不好的地方,就是当你一点击其它控件是就它就失去焦点,然后就自动退出,其实并没有真的退出,只是需要你再次激活它而已,关键是当它失去焦点的时候就excel对象就不见了,可以用Timage控件把TOleContainer所在的地方有EXCEL时候的区域图片截下来骗骗用户,我们这里主要不是讲这个,就不详述了。

下面我们就开始讲Excel_TLB中的接口的常用属性和方法,主要是针对导出和设定报表格式的一些接口元素。

单元格的读写属性:

olecon.OleObject.application.cells.item[1,1];
olecon.OleObject.application.cells(1,1);
olecon.OleObject.application.cells[1,1].value;

上面三种都可以对工作表的‘A1’单元进行读写。

在delphi中对单元格(集),区域,工作表等所有对象的操作都是要Variant来实现的。

自己的程序中选定区域赋给Range:

Var range,sheet:Variant;
Range:= olecon.OleObject.application.Range['A1:C3'];

或者:

Sheet:= olecon.OleObject.application.Activesheet;
Range:= olecon.OleObject.application.Range[sheet.cells[1,1],sheet.cells[3,3]];

对上面的Range合并单元格:

Range.merge;
Range. FormulaR1C1:='合并区';//合并后写入文本

注意以后要读合并的单元格里面的文本就是读合并区域的左上角的那个单元格的文本

在excel表中选定区域赋给range:

range:=excel_grid1.OleObject.application.selection;

拆分单元格:

Range.unmerge;

合并后设定单元格(集)的格式:

Range.HorizontalAlignment:= xlCenter;// 文本水平居中方式
Range.VerticalAlignment:= xlCenter//文本垂直居中方式
Range.WrapText:=true;//文本自动换行
Range.Borders.LineStyle:=1//加边框
Range.Interior.ColorIndex:=39;//填充颜色为淡紫色
Range.Font.name:='隶书';//字体
Range.Font.Color:=clBlue;//字体颜色

常用格式也就这些,以上这些对于单个单元格也适用。

在excel表中寻找前后上下的单元格:

Var u1,u2,u3,u4,u5:Variant;
U1:=olecon.oleobject.application.activecell;//获取当前格;
U2:=u1.previous;//非特殊情况就是u1左边的一格;
U3:=ui.next;//非特殊情况就是u2右边的一格;
U4:=olecon.oleobject.application.cells[u1.cells.row-1,u1.cells.column];//非特殊情况为上面一格
U5:=olecon.oleobject.application.cells[u1.cells.row+1,u1.cells.column];//非特殊情况为下面一格

删除和插入一行和一列:

Olecon.oleobject.application.rows[2].delete;
Olecon.oleobject.application.columns[2].delete;
Olecon.oleobject.application.rows[2].insert;
Olecon.oleobject.application.columns[2].insert;

复制指定区域:

Olecon.oleobject.application.range['A1:C3'].copy;

从指定单元格开始粘贴:

Olecon.oleobject.application.range['A4'].PasteSpecial;

常用的就这些了,对delphi中server面板下的EXEL控件和创建EXCEL.Application COM对象的方式都适用。




www.315soft.com诚信软件
致力于应用软件开发和希望工程
QQ群号:8248461
QQ:78874486





315soft



职务:论坛版主
级别:职业侠客
积分:88
经验:1774
文章:59
注册:05-01-07 13:14

发表: 2005-01-23 18:31:44 第2楼

利用Variant变量用DELPHI操作EXCEL,代码摘要:

var
v:Variant;

procedure TForm1.Button1Click(Sender: TObject);
begin //打开EXCEL新建文件
try
v:= CreateOleObject('Excel.Application');
v.Visible := CheckBox1.Checked;//是否显示
v.Workbooks.Add;//新建EXCEL文件
v.Workbooks[1].WorkSheets[1].Name := 'DELPHI演示';
// Sheet:= v.Workbooks[1].WorkSheets['DELPHI演示'];//等效下面的语句
Sheet:= v.Workbooks[1].WorkSheets[1];
Sheet.Cells[1,1] :='315soft';
Sheet.Cells[2,1] :='http://www.315soft.com';
except
Showmessage('初始化Excel失败,可能没装Excel,或者其他错误;请重起再试。');
v.DisplayAlerts := false;//是否提示存盘
v.Quit;//如果出错则退出
exit;
end;
Application.Restore;
Application.BringToFront;
end;




www.315soft.com诚信软件
致力于应用软件开发和希望工程
QQ群号:8248461
QQ:78874486





315soft



职务:论坛版主
级别:职业侠客
积分:88
经验:1774
文章:59
注册:05-01-07 13:14

发表: 2005-01-27 16:12:56 第3楼

[转帖] 浅谈Delphi如何控制Excel操作
  要在Delphi中控制Excel,就必须用到OLE自动化。现在一般采用OLE2来创建OLE对象,当激活一个OLE对象时,服务器程序仅在容器程序内部激活,这就是所谓的“就地激活”(in-place activation)。

  创建Excel文件时,先创建一个OLE对象,然后在对象中建立工作表worksheet,如函数createExcel所示:
  function createExcel:variant;
  var

  v:variant;

  sheet:variant;

  begin

  v:=createoleobject('Excel.Application');//创建OLE对象

  v.visible:=true;

  v.workbooks.add(-4167); //添加工作表

  v.workbooks[1].sheets[1].name:='test';

  sheet:=v.workbooks[1].sheets['test'];

  return v;

  end;
2 数据表格控制

  Excel表格的控制,主要包括数据的导入、修改;单元格的合并、边框的控制;表格的复制、粘贴等。当报表格式一定的情况下,表格的复制、粘贴显得尤为重要,这样,可以先制作一个文件模板,然后按照实际需要输出多页报表即可。

  (1)数据的导入(importData)


  procedure importData;
  var

  I,j:integer;

  v:variant;

begin
  v:=createExcel; //创建Excel文件test

  for I:=0 to maxcolumn do

  begin

  for j:=0 to maxrow do

  v.workbooks[1].sheets[1].cells[I,j]:=I*j; //导入数据

  end;

  end;



  (2)单元格的合并、边框的控制(lineStylecontrol)

  单元格的合并,是在选定合并范围的情况下进行的。边框控制可以操作边框线条的是否显示。其他方式的控制,可以仿照下面过程进行。


  procedure lineStylecontrol;
  var

  v,sheet,range:variant;

  begin

  v:=createExecl;

  sheet:= v.workbooks[1].sheets[1];

  range:=sheet.range[sheet.cells[1,1],sheet.cells[39,30]];//选定表格

  range.select;

  range.merge; //合并单元格

  range.borders.linestyle:=xlcontinuous; //置边框线可见

  range.font.size:=9; //改变表格内文本字体大小

  end;








www.315soft.com诚信软件
致力于应用软件开发和希望工程
QQ群号:8248461
QQ:78874486





315soft



职务:论坛版主
级别:职业侠客
积分:88
经验:1774
文章:59
注册:05-01-07 13:14

发表: 2005-01-27 16:25:24 第4楼

[转帖] 用Delphi轻松控制Excel 2K自动生成报表
 摘 要:Excel是当前最流行的数据报表制作工具。本文介绍如何使用Delphi来控制Excel完成数据库与报表之间的数据交换,讨论了报表制作工程中的一些细节性问题。

  关键字:Delphi,Excel,报表

  引言

  数据报表作为企事业单位上报和下达的重要信息载体,随着信息化建设的不断推进,在实际的工作中得到了前所未有的应用。因此,数据报表已经成为管理信息系统中重要的一项功能,并且,由于数据的多样性和统计信息的增加,数据报表的系统实现变得越来越复杂。

  Delphi是一个高效的可视化数据库管理信息系统开发工具,.但是Delphi开发环境中提供的报表控件在制作复杂报表时显得不够理想,不管是以前版本提供的Quick Report控件组,还是Delphi 7提供的Rave控件组,都不能让用户对生成的报表进行改动,且程序控制很难实现。Excel作为现代办公常用的电子表格制作工具,以它的易操作性和实用性,得到了各行业办公人员的青睐。本文根据实际应用实践,介绍利用Delphi编程控制Excel生成报表的各种方法。

  Delphi控制Excel的方法

  1 创建Excel文件

  要在Delphi中控制Excel,就必须用到OLE自动化。现在一般采用OLE2来创建OLE对象,当激活一个OLE对象时,服务器程序仅在容器程序内部激活,这就是所谓的“就地激活”(in-place activation)。

  创建Excel文件时,先创建一个OLE对象,然后在对象中建立工作表worksheet,如函数createExcel所示:

  function createExcel:variant;

  var

  v:variant;

  sheet:variant;

  begin

  v:=createoleobject('Excel.Application');//创建OLE对象

  v.visible:=true;

  v.workbooks.add(-4167); //添加工作表

  v.workbooks[1].sheets[1].name:='test';

  sheet:=v.workbooks[1].sheets['test'];

  return v;

  end;

  2 数据表格控制

  Excel表格的控制,主要包括数据的导入、修改;单元格的合并、边框的控制;表格的复制、粘贴等。当报表格式一定的情况下,表格的复制、粘贴显得尤为重要,这样,可以先制作一个文件模板,然后按照实际需要输出多页报表即可。

  (1)数据的导入(importData)

  procedure importData;

  var

  I,j:integer;

  v:variant;

  begin

  v:=createExcel; //创建Excel文件test

  for I:=0 to maxcolumn do

  begin

  for j:=0 to maxrow do

  v.workbooks[1].sheets[1].cells[I,j]:=I*j; //导入数据

  end;

  end;

  (2)单元格的合并、边框的控制(lineStylecontrol)

  单元格的合并,是在选定合并范围的情况下进行的。边框控制可以操作边框线条的是否显示。其他方式的控制,可以仿照下面过程进行。

  procedure lineStylecontrol;

  var

  v,sheet,range:variant;

  begin

  v:=createExecl;

  sheet:= v.workbooks[1].sheets[1];

  range:=sheet.range[sheet.cells[1,1],sheet.cells[39,30]];//选定表格

  range.select;

  range.merge; //合并单元格

  range.borders.linestyle:=xlcontinuous; //置边框线可见

  range.font.size:=9; //改变表格内文本字体大小

  end;
(3)表格的复制与粘贴(copyandPaste)

  procedure copyandPaste;

  var

  v,sheet,range:variant;

  begin

  v:=createExecl;

  
sheet:= v.workbooks[1].sheets[1];

  range:=sheet.range[sheet.cells[1,1],sheet.cells[39,30]];

  range.select; //选定要复制的表格

  range.copy; //复制选定的表格

  sheet.range[sheet.cells[40,1],sheet.cells[40,1]].select; //选择要粘贴的位置

  sheet.paste; //粘贴表格

  end;

  3 文件的保存

  文件保存是在创建文件的基础上进行的,过程saveFile说明了文件保存过程中应该注意的问题:

  procedure saveFile;

  var

  sheet,v:variant;

  begin

  v:=createExcel;

  if savedialog.execute then

  begin

  v.workbooks[1].saveas(savedialog.FileName);//保存文件

  v.workbooks[1].close; //关闭工作表

  v.quit; //关闭Excel

  v := unassigned;

  end;

  end;

  报表制作应注意的问题

  (1)报表格式的选择

  报表格式的选择对信息系统报表的实现方法起着决定性的影响。如果在报表的格式要求比较严格的情况下,应当采用模板的方式产生报表。由于模板在数据导入之前就已经按照标准制定好,所以只要在程序中控制模板的复制与粘贴,然后编程实现数据输入指定位置即可。而对于报表格式多变的情况,由于数据的不同,需要合并单元格或者控制边框,可以直接在程序中自动控制报表的生成。

  (2)打印

  对于Excel报表的打印,最好不要在程序中进行控制,因为报表往往需要签字或者进行审查,有许多报表都包含平面图或示意图,为了有效的控制打印质量,最好通过程序控制输出或显示Excel文件,以便修改;另一个重要的原因是Excel具有强大的排版功能,而这正是选择Excel导出报表的重要原因。

  (3)报表时间和表头

  报表时间要有用户可以控制的输出。表头的制作要在事先做好格式,控制输出时,只改动那些诸如上报单位、下达单位、负责人等数据,这样既保证了系统的效率,又不失其实用性。

  结论

  用Delphi控制Excel来完成数据库管理信息系统的数据报表功能,是Delphi制作复杂报表的最佳选择,因为Delphi不但能控制数据的导出与导入,而且可以完成当前Excel应用中的大部分功能。如果深入研究Visual Basic for Application(VBA)就可以制作出符合实际需要的各种Delphi控制Excel的控件。





www.315soft.com诚信软件
致力于应用软件开发和希望工程
QQ群号:8248461
QQ:78874486





315soft



职务:论坛版主
级别:职业侠客
积分:88
经验:1774
文章:59
注册:05-01-07 13:14

发表: 2005-01-27 16:31:09 第5楼

[转帖] 在DELPHI中使用ADO直接访问Excel数据文件

  承蒙各位大鱼大虾的支持,终于顿悟。现在将心经写下来,让后来者提高修成正果的效率,早日成为大鱼大虾。
  要用DELPHI中的ADO系列控件访问Excel数据文件,首先应该建立一些基本概念。你需要将一个Excel数据文件想象为一个关系数据库,Excel文件中的每个工作表就对应该数据库中的一个表,而工作表中的每一列当然就是表的列了。然后,按照下列面的秘诀进行就可以。

  
  1.设置ADOConnection的ConnectionString
构造ConnectionString时,OLE DB的提供者要选择Microsoft Jet 4.0 OLE DB Provider作为ADO的驱动程序。这本来是用于连接Access数据库的驱动程序,但也可打开Excel文件。
连接的数据库名称当然就是你要打开的Excel文件,注意扩展名是*.xls,而不是*.mdb。
最关键的一点是,还要设置扩展属性Extended Properties为“Excel 8.0”,否则,测试连接时会报告无法识别数据格式的错误。Extended Properties的属性值在“所有”参数页中输入。
最后,设置完成后的ConnectionString中的各项参数为:
Provider=Microsoft.Jet.OLEDB.4.0
Data Source=MyExcelFile.xls
Extended Properties=Excel 8.0
Persist Security Info=False

  2.设置ADODataSet或ADOTable
将ADODataSet或ADOTable连接到刚才的ADOConnection。如果不用ADOConnection,也可以参照上面的方法直接设置ADODataSet或ADOTable的ConnectionString属性。
对于ADODataSet,需要将CommandType属性设置为cmdTableDirect,而对于ADOTable,则将TableDirect属性设置为True。因为,访问Excel文件是直接的数据文件访问,不是通过SQL语句来操作游标访问的。如果不设置直接访问,则系统会报告SQL语句格式错误等信息。
然后,当你下拉ADODataSet中的CommandText属性或ADOTable的TableName属性时,就可以选择到要打开的工作表了。注意,表名后面多了加一个$符号。
  3.打开ADODataSet或ADOTable







www.315soft.com诚信软件
致力于应用软件开发和希望工程
QQ群号:8248461
QQ:78874486





315soft



职务:论坛版主
级别:职业侠客
积分:88
经验:1774
文章:59
注册:05-01-07 13:14

发表: 2005-01-27 16:33:47 第6楼

TAdoQuery导出数据到Excel

procedure TFrmZjMoveSch.BitBtn2Click(Sender: TObject);
var
WD: TWriteData ;
begin
WD := TWriteData.Create ;
WD.Qry := qryZjMoveSch;
WD.Summary.Add('铸件移交计划:');
WD.Summary.Add('所有生产批号!');
WD.Summary.Add('Create by: '+FrmMain.UserName);
WD.Summary.Add(DateToStr(now));
try

if SaveDialog1.Execute then
WD.ExportToFile(SaveDialog1.FileName, true);
finally
WD.Free ;
end;
//
end;


unit WriteData;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, DBGridEh, DB, ADODB, StdCtrls, Buttons, XPMenu, DBGrids;

//目标是: 通过普通AdoQuery来导出数据!
//Create by yxf
//Date: 2004-10-05
//

type

TColumnsList = class(TList)
private
function GetColumn(Index: Integer): TColumn;
procedure SetColumn(Index: Integer; const value: TColumn);
public
property Items[Index: Integer]: TColumn read GetColumn write SetColumn; default;
end;

TColCellParams = class
protected
FAlignment: TAlignment;
FBackground: TColor;
FCol: Longint;
FFont: TFont;
FImageIndex: Integer;
FReadOnly: Boolean;
FRow: Longint;
FState: TGridDrawState;
FText: String;
public
property Alignment: TAlignment read FAlignment write FAlignment;
property Background: TColor read FBackground write FBackground;
property Col: Longint read FCol;
property Font: TFont read FFont;
property ImageIndex: Integer read FImageIndex write FImageIndex;
property ReadOnly: Boolean read FReadOnly write FReadOnly;
property Row: Longint read FRow;
property State: TGridDrawState read FState;
property Text: String read FText write FText;
end;

TWriteData = class
private
//FColCellParamsEh: TColCellParamsEh;
FDBGrid: TCustomDBGrid;
FQry: TAdoQuery;
//FExpCols: TColumnsEhList;
FStream: TStream;
//function GetFootervalue(Row, Col: Integer): String;
//procedure CalcFootervalues;
FCol, FRow: Word;
FSummary: TStringList;
// FColumns: TColumnsList;
// FCount: integer;//列总和

protected
// Footervalues: PFootervalues;
procedure WriteBlankCell;
procedure WriteEnter;
procedure WriteIntegerCell(const Avalue: Integer);
procedure WriteFloatCell(const Avalue: Double);
procedure WriteStringCell(const Avalue: String);
procedure IncColRow;
procedure WritePrefix;
procedure WriteSuffix;
procedure WriteTitle;
procedure WriteRecord(ColumnsList: TColumnsList);
procedure WriteDataCell(Column: TColumn; FColCellParams: TColCellParams);
//procedure WriteFooter(ColumnsList: TColumnsEhList; FooterNo: Integer);
//procedure WriteFooterCell(DataCol, Row: Integer; Column: TColumnEh; AFont: TFont;
// Background: TColor; Alignment: TAlignment; Text: String);
property Stream: TStream read FStream write FStream;
//property ExpCols: TColumnsEhList read FExpCols write FExpCols;
public
constructor Create;
destructor Destroy; override;
procedure ExportToStream(AStream: TStream; IsExportAll: Boolean);
procedure ExportToFile(FileName: String; IsExportAll: Boolean);
property Summary: TStringList read FSummary write FSummary;
property Qry: TAdoQuery read FQry write FQry;
property DBGrid: TCustomDBGrid read FDBGrid write FDBGrid;
end;


implementation

{ TWriteData }

var
CXlsBof: array[0..5] of Word = ($809, 8, 0, $10, 0, 0);
CXlsEof: array[0..1] of Word = ($0A, 00);
CXlsLabel: array[0..5] of Word = ($204, 0, 0, 0, 0, 0);
CXlsNumber: array[0..4] of Word = ($203, 14, 0, 0, 0);
CXlsRk: array[0..4] of Word = ($27E, 10, 0, 0, 0);
CXlsBlank: array[0..4] of Word = ($201, 6, 0, 0, $17);

constructor TWriteData.Create;
begin
// FDBGrid := TCustomDBGrid.Create(self);
FSummary := TStringList.Create ;
inherited;
end;

destructor TWriteData.Destroy;
begin
FSummary.Free ;
inherited;
end;

procedure TWriteData.ExportToFile(FileName: String; IsExportAll: Boolean);
var FileStream: TFileStream;
begin
FileStream := TFileStream.Create(FileName, fmCreate);
try
ExportToStream(FileStream, IsExportAll);
finally
FileStream.Free;
end;
end;

procedure TWriteData.ExportToStream(AStream: TStream;
IsExportAll: Boolean);
var
// ColList: TColumnsEhList;
BookMark: Pointer;
i: Integer;
begin

FCol := 0;
FRow := 0;

Stream := AStream;

WritePrefix;
//写标题

WriteTitle;
BookMark := Qry.GetBookmark;

Qry.DisableControls ;
Screen.Cursor := crSQLWait;
try
if not Qry.Active then Qry.Open ;
Qry.First ;
While not Qry.Eof do
begin
for I := 0 to Qry.FieldCount - 1 do
begin
case Qry.Fields[ i ].DataType of
ftSmallint, ftInteger, ftWord, ftAutoInc, ftBytes:
WriteIntegerCell(Qry.Fields[ i ].AsInteger );
ftFloat, ftCurrency, ftBCD{$IFDEF EH_LIB_6}, ftFMTBcd{$ENDIF}:
WriteFloatCell(Qry.Fields[ i ].AsFloat);
else
WriteStringCell(Qry.Fields[ i ].AsString );
end;
end;
Qry.Next ;
end;
finally
Qry.GotoBookmark(BookMark);
Qry.EnableControls ;
Qry.FreeBookmark(BookMark);
WriteEnter;
WriteStringCell('查询条件:');
WriteEnter;
for I:= 0 to FSummary.Count - 1 do
begin
if FSummary.Strings[I] = '#13' then WriteEnter else
WriteStringCell(FSummary.Strings[I]);
WriteEnter;
end;
Screen.Cursor := crdefault;
end;
WriteSuffix;
ShowMessage('数据导入成功完成!');
//具体处理导出设置
end;

procedure TWriteData.IncColRow;
begin
if FCol = Qry.FieldCount - 1 then
begin
Inc(FRow);
FCol := 0;
end else
Inc(FCol);
end;


procedure TWriteData.WriteBlankCell;
begin
CXlsBlank[2] := FRow;
CXlsBlank[3] := FCol;
Stream.WriteBuffer(CXlsBlank, SizeOf(CXlsBlank));
IncColRow;
end;

procedure TWriteData.WriteDataCell(Column: TColumn;
FColCellParams: TColCellParams);
begin
if Column.Field = nil then
WriteBlankCell
// else if Column.GetColumnType = ctKeyPickList then
// WriteStringCell(FColCellParamsEh.Text)
else if Column.Field.IsNull then
WriteBlankCell
else
with Column.Field do
case DataType of
ftSmallint, ftInteger, ftWord, ftAutoInc, ftBytes:
WriteIntegerCell(AsInteger);
ftFloat, ftCurrency, ftBCD:
WriteFloatCell(AsFloat);
else
WriteStringCell(FColCellParams.Text);
end;
end;

procedure TWriteData.WriteEnter;
begin
FCol := Qry.FieldCount - 1;
WriteStringCell('');
// FCol := Qry.FieldCount - 1;
end;

procedure TWriteData.WriteFloatCell(const Avalue: Double);
begin
CXlsNumber[2] := FRow;
CXlsNumber[3] := FCol;
Stream.WriteBuffer(CXlsNumber, SizeOf(CXlsNumber));
Stream.WriteBuffer(Avalue, 8);
IncColRow;
end;

procedure TWriteData.WriteIntegerCell(const Avalue: Integer);
var
V: Integer;
begin
CXlsRk[2] := FRow;
CXlsRk[3] := FCol;
Stream.WriteBuffer(CXlsRk, SizeOf(CXlsRk));
V := (Avalue shl 2) or 2;
Stream.WriteBuffer(V, 4);
IncColRow;
end;

procedure TWriteData.WritePrefix;
begin
Stream.WriteBuffer(CXlsBof, SizeOf(CXlsBof));
end;

procedure TWriteData.WriteRecord(ColumnsList: TColumnsList);
var //i: Integer;
AFont: TFont;
// State:TGridDrawState;
begin
AFont := TFont.Create;
try
// for i := 0 to ColumnsList.Count - 1 do
begin
// AFont.Assign(ColumnsList[i].Font);

// with TColCellParamsEhCracker(FColCellParamsEh) do
begin
// FRow := -1;
//FCol := -1;
// FState := [];
// FFont := AFont;
// Background := ColumnsList[i].Color;
// Alignment := ColumnsList[i].Alignment;
// ImageIndex := ColumnsList[i].GetImageIndex;
// Text := ColumnsList[i].DisplayName;
// CheckboxState := ColumnsList[i].CheckboxState;

// if Assigned(DBGridEh.OnGetCellParams) then
// DBGridEh.OnGetCellParams(DBGridEh, ColumnsList[i], FFont, FBackground, FState);

// ColumnsList[i].GetColCellParams(False, FColCellParamsEh);

//WriteDataCell(ColumnsList[i], FColCellParamsEh);

end;
end;
finally
AFont.Free;
end;
end;

procedure TWriteData.WriteStringCell(const Avalue: String);
var
L: Word;
begin
L := Length(Avalue);
CXlsLabel[1] := 8 + L;
CXlsLabel[2] := FRow;
CXlsLabel[3] := FCol;
CXlsLabel[5] := L;
Stream.WriteBuffer(CXlsLabel, SizeOf(CXlsLabel));
Stream.WriteBuffer(Pointer(Avalue)^, L);
IncColRow;
end;

procedure TWriteData.WriteSuffix;
begin
Stream.WriteBuffer(CXlsEof, SizeOf(CXlsEof));
end;

procedure TWriteData.WriteTitle;
var
I: Integer;
begin

//这里需要重新定义
//遍历列 明细 填写标题
for I := 0 to Qry.FieldCount - 1 do
begin
WriteStringCell(Qry.Fields[i].DisplayLabel );
end;
end;

{ TColumnsList }

function TColumnsList.GetColumn(Index: Integer): TColumn;
begin
Result := Get(Index);
end;

procedure TColumnsList.SetColumn(Index: Integer; const value: TColumn);
begin
Put(Index, value);
end;

end.











0

评论Comments