delphi dbgrid导出XLS,完成后并打开导出的XLS文件,如何实现

delphi dbgrid导出XLS,完成后并打开导出的XLS文件,如何实现,第1张

有三个API函数可以蠢猛伍运行可执行文件WinExec、ShellExecute和CreateProcess。

1.CreateProcess因为使用复杂,比较少用。

2.WinExec主要运行EXE文件。如:WinExec('Notepad.exe Readme.txt', SW_SHOW)

3.ShellExecute不仅可以运行EXE文件,也可以运行已经关联的文件。

首先必须引用shellapi.pas单元:uses ShellAPI

1).标准用法

ShellExecute函数原型及参数含义如下:

function ShellExecute(hWnd: HWNDOperation, FileName, Parameters,Directory: PCharShowCmd: Integer): HINSTstdcall

●hWnd:用于指定父窗口句柄。当函数调用过程出现错误时,它将作为Windows消息窗口的父窗口。例如,可以将其设置为应用程序主窗口

句柄,即Application.Handle,也可以将其设置为桌面窗口句柄(用GetDesktopWindow函数获得)。

●Operation:用于指定要进行的 *** 作。其中“open” *** 作表示执行由FileName参数指定的程序,或打开由FileName参数指定的文件或文件

夹;“print” *** 作表示打印由FileName参数指定的文件;“explore” *** 作表示浏览由FileName参数指定的文件夹。当参数设为nil时,表示执

行默认 *** 作“open”知握。

●FileName:用于指定要打开的文件名、要执行的程序文件名或要浏览的文件夹名。

●Parameters:若FileName参数是一个可执行程序,则此参数指定命令行参数,否则此参数应为nil或PChar(0)。

●Directory:用于指定默认目录。

●ShowCmd:若FileName参数是一个可执行程序,则此参数指定程序窗口的初始显示方式,否则此参数应设置为0。

若ShellExecute函数调用成功,则返回值为被执行程序的实例句柄。若返回值小于32,则表示出现错误。

上述仅仅是ShellExecute函数的标准用法,下面将介绍它的特殊用法。

2).特殊用法

如果将FileName参数设置为“http:”协议格式,那么该函数将打开默认浏览器并链接到指定的URL地址。若用户机器中安装了多个浏览器

,则该函数将根据Windows 9x/NT注册表中http协议处理程序(Protocols Handler)的设置确定启动哪个浏览器。

格式一:http://网站域名。

  如:ShellExecute(handle, ‘open’, http://www.neu.edu.cn’, nil, nil, SW_SHOWNORMAL)

格式二:http://网站域名/网页文件名。

如:ShellExecute(handle, ‘open’, http://www.neu.edu.cn/default.htm’,nil,nil,SW_SHOWNORMAL)

如果将FileName参数设置为“mailt”协议格式,那么该函数将启动默认邮件客户程序,如Microsoft Outlook(也包括Microsoft

Outlook Express)或Netscape Messanger。若用户机器中安装了多个邮件客户程序,则该函数将根据Windows 9x/NT注册表中mailto协带或议处理

程序的设置确定启动哪个邮件客户程序。

格式一:mailt

如:ShellExecute(handle,‘open’, ‘mailt’, nil, nil, SW_SHOWNORMAL)打开新邮件窗口。

格式二:mailt用户账号@邮件服务器地址

如:ShellExecute(handle, ‘open’,‘ mailtwho@mail.neu.edu.cn’, nil, nil, SW_SHOWNORMAL)打开新邮件窗口,并自动填入收

件人地址。若指定多个收件人地址,则收件人地址之间必须用分号或逗号分隔开(下同)。

格式三:mailt用户账号@邮件服务器地址?subject=邮件主题&body=邮件正文

如:ShellExecute(handle, ‘open’, ‘ mailtwho@mail.neu.edu.cn?subject=Hello&Body=This is a test’, nil, nil,

SW_SHOWNORMAL)打开新邮件窗口,并自动填入收件人地址、邮件主题和邮件正文。若邮件正文包括多行文本,则必须在每行文本之间加入换行

转义字符%0a。

例子(Delphi):

在一个应用程序调用c:\Project1.exe

ShellExecute(handle, 'open','c:\Project1.exe','字串内容',nil, SW_SHOWNORMAL)

在Project1.exe里可以调用:

procedure Tform1.formCreate(Sender: TObject)

var

i: integer

begin

for i:=1 to paramcount do

if ParamStr(i)<>'' then

showmessage(ParamStr(i))

end

最后的那个参数,为窗口指定可视性方面的一个命令。请用下述任何一个常数:

SW_HIDE 隐藏窗口,活动状态给令一个窗口

SW_MINIMIZE 最小化窗口,活动状态给令一个窗口

SW_RESTORE 用原来的大小和位置显示一个窗口,同时令其进入活动状态

SW_SHOW 用当前的大小和位置显示一个窗口,同时令其进入活动状态

SW_SHOWMAXIMIZED 最大化窗口,并将其激活

SW_SHOWMINIMIZED 最小化窗口,并将其激活

SW_SHOWMINNOACTIVE 最小化一个窗口,同时不改变活动窗口

SW_SHOWNA 用当前的大小和位置显示一个窗口,不改变活动窗口

SW_SHOWNOACTIVATE 用最近的大小和位置显示一个窗口,同时不改变活动窗口

SW_SHOWNORMAL 与SW_RESTORE相同

在使用吵神搭 Delphi 语言进行软件应用开发过程中,常见的一种应用是 *** 纵 excel 进行读取、生成报表的功能开发,在此总结一下常用的三种方法及其优缺点:

一、使用 COM 方法

此方法的原理,是通过 CreateOleOjbect 函数来调用 windows 系统中注册的 Excel 信息,来建立对 Excel.Application 的引用来 *** 作 Excel。示例代码如下:

procedure ReadExcels

var

  i,j: Integer

begin

  exlApp := CreateOleObject('Excel.Application')

  exlApp.Visible := False

  exlApp.WorkBooks.Open(fsFileName)

 

  iRowCount := exlApp.ActiveSheet.UsedRange.Rows.Count

  iColCount := exlApp.ActiveSheet.UsedRange.Columns.Count

   

  for i := 2 to iRowCount do

   for j:=1 to icolcount do 

   begin

     ShowMessage(exlApp.workbooks[1].sheets[1].cells[i,j]) 

   end

end

优点:可以动态创建,基本不用管软件运行电脑安装的 Excel 版本都能运行;缺点:需要安装 Excel,程序编写过程中缺乏函数、成员等提示,运行时刻出错不易调试。

二、使用 delphi 自带的 Office 控件

此方法与方法一原理类似,区别在于将 Excel.Application 等封装成控件。示例代码如下:

ExcelApplication1.Workbooks.Open ('c:\test.xls',

  EmptyParam , EmptyParam , EmptyParam , EmptyParam ,

  EmptyParam , EmptyParam , EmptyParam , EmptyParam ,

  EmptyParam , EmptyParam , EmptyParam , EmptyParam , 0)

ExcelApplication1.WorksSheets['Sheet2'] .Activate

ExcelApplication1.Cells[1,4].Value := 'test'

优点:程序编写过程中可以得到函数、成员等提示;缺点:需要安装 Excel,不同的 Excel 版本,需要有针对性的建立组件。

三、使用第三方控件

XLSReadWrite 作为一个优秀瞎枣的 *** 作 Excel 的控件,提供了简便快捷读取、写入Excel文件的好办法。升拿示例代码:

var

  s:string

  xls:TXlsReadWrite

begin

  Xls.filename:='c:\123.xls'

  xls.read

  s:=xls.sheets[0].asstring[0,0]

  showmessage(s)

  xls.sheets[0].asstring[0,0]:='新闻界'

  xls.savetofile('c:\234.xls')

end

优点:可在本机未安装 excel 的前提下读取 Excel 文件,读、写等 *** 作简便;缺点:第三方控件,需要自行安装 。

在开发数据库应用程序中,经常要将类型相同的数据导出来,放到Excel文件中,利用Excel强大的编辑功能,对数据作进一步的加工处理。这有许多的方法,我们可以使用OLE技术,在Delphi中创建一个自动化对象,通过该对象来传送数据。也可以使用ADO,通过与Excel数据存储建立连接,使用ADO这种独立于数据库后端的技术来导出数据集的数据。

可这两种技术都有一个共同的缺点,那就是慢,数据量少还好,用户不会有太多的感觉,可一旦亩枝敬数据量大,比搭档如,超过1千条,速度就让人难以忍受了,那么有没有更好的办法,既可以快速地导出数据,又不用安装附加的软件。也许好多人都想到了剪贴板的方式,这种方式速度是快,可也有不好的一面,那就是数据量大占用内存也大,并且在Excel中调用PASTE方法时,需要锁定输入,这使用起来,就有点不方便了

这里我为大家介迅慎始一种比较好的方法,使用文件流的方式,通过TfileStream直接写入Excel文件。我写了一个函数,通过它可将数据集中的数据直接导入到Excel文件中。测试了一下,1M的数据,不到十秒就完成了。附源程序。

unit Unit1

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs,DB, ADODB, Grids, DBGrids, StdCtrls

type

TForm1 = class(TForm)

DBGrid1: TDBGrid

ADOTable1: TADOTable

DataSource1: TDataSource

ADOConnection1: TADOConnection

ADOTable1record_id: TIntegerField

ADOTable1action_id: TIntegerField

ADOTable1action_name: TStringField

ADOTable1net_name: TStringField

ADOTable1deal_no: TStringField

ADOTable1name: TStringField

ADOTable1getno_date: TDateTimeField

ADOTable1window_no: TIntegerField

ADOTable1staff_id: TStringField

ADOTable1staff_name: TStringField

ADOTable1deal_date: TDateTimeField

ADOTable1deal_type: TStringField

ADOTable1finish_date: TDateTimeField

ADOTable1state: TStringField

ADOTable1appraise: TStringField

ADOTable1appraised_flag: TBooleanField

ADOTable1cancel_led_time: TDateTimeField

ADOTable1wait_time: TBCDField

ADOTable1wait_time2: TStringField

ADOTable1accept_time: TBCDField

ADOTable1accept_time2: TStringField

ADOTable1getnumber_addr: TIntegerField

ADOTable1cust_level: TIntegerField

ADOTable1cust_level_name: TStringField

ADOTable1cust_level_name_remark: TStringField

ADOTable1operation_sum: TIntegerField

Button1: TButton

SaveDialog1: TSaveDialog

procedure Button1Click(Sender: TObject)

private

{ Private declarations }

public

{ Public declarations }

end

var

Form1: TForm1

arXlsBegin: array[0..5] of Word = ($809, 8, 0, $10, 0, 0)

arXlsEnd: array[0..1] of Word = ($0A, 00)

arXlsString: array[0..5] of Word = ($204, 0, 0, 0, 0, 0)

arXlsNumber: array[0..4] of Word = ($203, 14, 0, 0, 0)

arXlsInteger: array[0..4] of Word = ($27E, 10, 0, 0, 0)

arXlsBlank: array[0..4] of Word = ($201, 6, 0, 0, $17)

implementation

{$R *.dfm}

Procedure ExportExcelFile(FileName: stringbWriteTitle: BooleanaDataSet: TDataSet)

var

i, j: integer

Col, row: word

ABookMark: TBookMark

aFileStream: TFileStream

procedure incColRow//增加行列号

begin

if Col = ADataSet.FieldCount - 1 then

begin

Inc(Row)

Col :=0

end

else

Inc(Col)

end

procedure WriteStringCell(AValue: string)//写字符串数据

var

L: Word

begin

L := Length(AValue)

arXlsString[1] := 8 + L

arXlsString[2] := Row

arXlsString[3] := Col

arXlsString[5] := L

aFileStream.WriteBuffer(arXlsString, SizeOf(arXlsString))

aFileStream.WriteBuffer(Pointer(AValue)^, L)

IncColRow

end

procedure WriteIntegerCell(AValue: integer)//写整数

var

V: Integer

begin

arXlsInteger[2] := Row

arXlsInteger[3] := Col

aFileStream.WriteBuffer(arXlsInteger, SizeOf(arXlsInteger))

V := (AValue shl 2) or 2

aFileStream.WriteBuffer(V, 4)

IncColRow

end

procedure WriteFloatCell(AValue: double)//写浮点数

begin

arXlsNumber[2] := Row

arXlsNumber[3] := Col

aFileStream.WriteBuffer(arXlsNumber, SizeOf(arXlsNumber))

aFileStream.WriteBuffer(AValue, 8)

IncColRow

end

begin

if FileExists(FileName) then

DeleteFile(FileName)//文件存在,先删除

aFileStream := TFileStream.Create(FileName, fmCreate)

Try

//写文件头

aFileStream.WriteBuffer(arXlsBegin, SizeOf(arXlsBegin))

//写列头

Col := 0Row := 0

if bWriteTitle then

begin

for i := 0 to aDataSet.FieldCount - 1 do

WriteStringCell(aDataSet.Fields[i].FieldName)

end

//写数据集中的数据

aDataSet.DisableControls

ABookMark := aDataSet.GetBookmark

aDataSet.First

while not aDataSet.Eof do

begin

for i := 0 to aDataSet.FieldCount - 1 do

case ADataSet.Fields[i].DataType of

ftSmallint, ftInteger, ftWord, ftAutoInc, ftBytes:

WriteIntegerCell(aDataSet.Fields[i].AsInteger)

ftFloat, ftCurrency, ftBCD:

WriteFloatCell(aDataSet.Fields[i].AsFloat)

else

WriteStringCell(aDataSet.Fields[i].AsString)

end

aDataSet.Next

end

//写文件尾

AFileStream.WriteBuffer(arXlsEnd, SizeOf(arXlsEnd))

if ADataSet.BookmarkValid(ABookMark) then

aDataSet.GotoBookmark(ABookMark)

finally

AFileStream.Free

ADataSet.EnableControls

end

end

procedure TForm1.Button1Click(Sender: TObject)

begin

if SaveDialog1.Execute then

begin

ExportExcelFile(SaveDialog1.FileName,True,DBGrid1.DataSource.DataSet)

end

end

end.


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/tougao/12149626.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存