首页 Delphi 正文
  • 本文约23595字,阅读需2小时
  • 2322
  • 0
举报该广告
()DbGrid导入Excl控件

()DbGrid导入Excl控件

摘要

unit DBGridExport;
interface
uses
  SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, Db, DBGrids, Comobj, extctrls, comctrls, ActiveX;
type
  TSpaceMark 
= (csComm...

unit DBGridExport;
interface
uses
  SysUtils, Classes, Graphics, Controls, Forms, Dialogs,StdCtrls, Db, DBGrids, Comobj, extctrls, comctrls, ActiveX;
type
  TSpaceMark 
= (csComma, csSemicolon, csTab, csBlank, csEnter);
  TDBGridExport 
= class(TComponent)
  private
    FDB_Grid: TDBGrid; 
{读取DBGrid的源}
    FTxtFileName: string; 
{文本文件}
    FSpaceMark: TSpaceMark; 
{间隔符号}
    FSpace_Ord: Integer; 
{间隔符号的Asc数}
    FTitle: string; 
{显示的标}
    FSheetName: string; 
{工作表标}
    FExcel_Handle: OleVariant; 
{Excel的句}
    FWorkbook_Handle: OleVariant; 
{书签的句}
    FShow_Progress: Boolean; 
{是否显示插入进度}
    FProgress_Form: TForm; 
{进度窗体}
    FRun_Excel_Form: TForm; 
{启动Excel提示窗口}
    FProgressBar: TProgressBar; 
{进度}
    
function Connect_Excel: Boolean; {启动Excel}
    
function New_Workbook: Boolean; {插入新的工作}
    
function InsertData_To_Excel: Boolean; {插入数据}
    
procedure Create_ProgressForm(AOwner: TComponent); {创建进度显示窗口}
    
procedure Create_Run_Excel_Form(AOwner: TComponent); {创建启动Excel窗口}
    
procedure SetSpaceMark(Value: TSpaceMark); {设置导出时的间隔符号}
    protected
  public
    constructor Create(AOwner: TComponent); override; 
{新建}
    destructor Destroy; override; 
{}
    
function Export_To_Excel: Boolean; overload; {导出到Excel}
    
function Export_To_Excel(DB_Grid: TDBGrid): Boolean; overload;
    
function Export_To_Txt(NewFile: Boolean = True): Boolean; overload; {导出到文本文件中}
    
function Export_To_Txt(FileName: string; NewFile: Boolean = True): Boolean; overload;
    
function Export_To_Txt(DB_Grid: TDBGrid; NewFile: Boolean = True): Boolean; overload;
    
function Export_To_Txt(FileName: string; DB_Grid: TDBGrid; NewFile: Boolean = True): Boolean; overload;
    published
    property DB_Grid: TDBGrid read FDB_Grid write FDB_Grid;
    property Show_Progress: Boolean read FShow_Progress write FShow_Progress;
    property TxtFileName: string read FTxtFileName write FTxtFileName;
    property SpaceMark: TSpaceMark read FSpaceMark write SetSpaceMark;
    property Title: string read FTitle write FTitle;
    property SheetName: string read FSheetName write FSheetName;
end;

procedure Register;

implementation

procedure Register;

begin
  RegisterComponents(
'Stone', [TDBGridExport]);
end;
{-------------------------------------------------------------------------------}
{新建}
constructor TDBGridExport.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FShow_Progress :
= True;
  FSpaceMark :
= csTab;
end;

{}
destructor TDBGridExport.Destroy;
begin
  varClear(FExcel_Handle);
  varClear(FWorkbook_Handle);
inherited Destroy;
end;
{===============================================================================}
{导出到文本文件中}
function TDBGridExport.Export_To_Txt(NewFile: Boolean = True): Boolean;
var
  Txt: TStrings;
  Tmp_Str,data_Str,Column_name: string;
  i, j: Integer;
  Data_Set: TDataSet;
  bookmark: pointer;
  Before_Scroll, Afrer_Scroll: TDataSetNotifyEvent;
begin
  Result :
= False;
  
if NewFile = True then
    FTxtFileName :
= '';
  
if FTxtFileName = '' then
  
begin
    
with TSaveDialog.Create(nildo
    
begin
      Title :
= '请选择输出文件';
      DefaultExt :
= 'txt';
      Filter :
= '文本文件(*.Txt)|*.txt';
      Options :
= [ofOverwritePrompt, ofHideReadOnly, ofPathMustExist, ofNoReadOnlyReturn, ofEnableSizing];
      
if Execute then
        FTxtFileName :
= FileName;
      Free;
      
if FTxtFileName = '' then {如果没有选中文件,则直接推出}
      exit;
    
end;

    
if FTxtFileName = '' then
    
begin
      raise exception.Create(
'没有指定输出文件');
      Exit;
    
end;
  
end;
  
if FDB_Grid = nil then
    raise exception.Create(
'请输入DBGrid名称');
  Txt :
= TStringList.Create;
  try
{显示插入进度}
    
if FShow_Progress = True then
    
begin
      Create_ProgressForm(
nil);
      FProgress_Form.Show;
    
end;
    
{第一行,插入标题}
    Tmp_Str :
= ''//FDB_Grid.Columns[0].Title.Caption;
    
for i := 1 to FDB_Grid.Columns.Count do
    
if FDB_Grid.Columns[i - 1].Visible = True then
      Tmp_Str :
= Tmp_Str + FDB_Grid.Columns[i - 1].Title.Caption + Chr(FSpace_Ord);
    Tmp_Str :
= Copy(Tmp_Str, 1, Length(Tmp_Str) - 1);
    Txt.Add(Tmp_Str);
    
{插入DBGrid中的数据}
    Data_Set :
= FDB_Grid.DataSource.DataSet;
    
{记忆当前位置并取消任何事}
    
// new(bookmark);
    bookmark :
= Data_Set.GetBookmark;
    Data_Set.DisableControls;
    Before_Scroll :
= Data_Set.BeforeScroll;
    Afrer_Scroll :
= Data_Set.AfterScroll;
    Data_Set.BeforeScroll :
= nil;
    Data_Set.AfterScroll :
= nil;
    
if FShow_Progress = True then
    
begin
      Data_Set.Last;
      FProgress_Form.Refresh;
      FProgressBar.Max :
= Data_Set.RecordCount;
    
end;
    
{插入DBGrid中的所有字}
    Data_Set.First;
    j :
= 2;
    
while not Data_Set.Eof do
    
begin
      
if FShow_Progress = True then
        FProgressBar.Position :
= j - 2;
      Column_name :
= FDB_Grid.Columns[0].FieldName;
      Tmp_Str :
= ''//Data_Set.FieldByName(Column_name).AsString;
      
for i := 1 to FDB_Grid.Columns.Count do
        
if FDB_Grid.Columns[i - 1].Visible = True then
        
begin
          data_Str :
= FDB_Grid.Fields[i - 1].DisplayText;
          Tmp_Str :
= Tmp_Str + data_Str + Chr(FSpace_Ord);
        
end;
      Tmp_Str :
= Copy(Tmp_Str, 1, Length(Tmp_Str) - 1);
      Txt.Add(Tmp_Str);
      j :
= j + 1;
      Data_Set.Next;
    
end;
    
{恢复原始事件以及标志位置}
    Data_Set.GotoBookmark(bookmark);
    Data_Set.FreeBookmark(bookmark);
    
// dispose(bookmark);
    Data_Set.EnableControls;
    Data_Set.BeforeScroll :
= Before_Scroll;
    Data_Set.AfterScroll :
= Afrer_Scroll;
    
{写到文件}
    Txt.SaveToFile(FTxtFileName);
    Result :
= True;
  finally
    Txt.Free;
    
if FShow_Progress = True then
    
begin
      FProgress_Form.Free;
      FProgress_Form :
= nil;
    
end;
  
end;
end;
function TDBGridExport.Export_To_Txt(FileName: string; NewFile: Boolean = True): Boolean;
begin
  FTxtFileName :
= FileName;
  Result :
= Export_To_Txt(NewFile);
end;

function TDBGridExport.Export_To_Txt(DB_Grid: TDBGrid; NewFile: Boolean = True): Boolean;
begin
  FDB_Grid :
= DB_Grid;
  Result :
= Export_To_Txt(NewFile);
end;

function TDBGridExport.Export_To_Txt(FileName: string; DB_Grid: TDBGrid; NewFile: Boolean = True): Boolean;
begin
  FTxtFileName :
= FileName;
  FDB_Grid :
= DB_Grid;
  Result :
= Export_To_Txt(NewFile);
end;
{-------------------------------------------------------------------------------}
{设置导出时的间隔符号}
procedure TDBGridExport.SetSpaceMark(Value: TSpaceMark);
begin
  FSpaceMark :
= Value;
  
case Value of
    csComma: FSpace_Ord :
= ord(',');
    csSemicolon: FSpace_Ord :
= ord(';');
    csTab: FSpace_Ord :
= 9;
    csBlank: FSpace_Ord :
= 32;
    csEnter: FSpace_Ord :
= 13;
  
end;
end;
{===============================================================================}
{导出到Excel}
function TDBGridExport.Export_To_Excel: Boolean;
begin
  
if FDB_Grid = nil then
    raise exception.Create(
'请输入DBGrid名称');
  Result :
= False;
  
if Connect_Excel = True then
    
if New_Workbook = True then
      
if InsertData_To_Excel = True then
  Result :
= True;
end;

function TDBGridExport.Export_To_Excel(DB_Grid: TDBGrid): Boolean;
begin
  FDB_Grid :
= DB_Grid;
  Result :
= Export_To_Excel;
end;
{-------------------------------------------------------------------------------}
{启动Excel}
function TDBGridExport.Connect_Excel: Boolean;
  
{连接Ole对象}
  
function My_GetActiveOleObject(const ClassName: string; out Ole_Handle: IDispatch): Boolean;
  
var //IDispatch
    ClassID: TCLSID;
    Unknown: IUnknown;
    l_Result: HResult;
  
begin
    Result :
= False;
    l_Result :
= CLSIDFromProgID(PWideChar(WideString(ClassName)), ClassID);
    
if (l_Result and $80000000= 0 then
    
begin
      l_Result :
= GetActiveObject(ClassID, nil, Unknown);
      
if (l_Result and $80000000= 0 then
      
begin
        l_Result :
= Unknown.QueryInterface(IDispatch, Ole_Handle);
        
if (l_Result and $80000000= 0 then
          Result :
= True;
      
end;
    
end;
  
end;
  
{创建OLE对象}
  
function My_CreateOleObject(const ClassName: string; out Ole_Handle: IDispatch): Boolean;
  
var
    ClassID: TCLSID;
    l_Result: HResult;
  
begin
    Result :
= False;
    l_Result :
= CLSIDFromProgID(PWideChar(WideString(ClassName)), ClassID);
    
if (l_Result and $80000000= 0 then
    
begin
      l_Result :
= CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or
      CLSCTX_LOCAL_SERVER, IDispatch, Ole_Handle);
      
if (l_Result and $80000000= 0 then
        Result :
= True;
    
end;
  
end;
var
  l_Excel_Handle: IDispatch;
begin
  
if FShow_Progress = True then
  
begin
    Create_Run_Excel_Form(
nil);
    FRun_Excel_Form.Show;
  
end;
  
if My_GetActiveOleObject('Excel.Application', l_Excel_Handle) = False then
    
if My_CreateOleObject('Excel.Application', l_Excel_Handle) = False then
    
begin
      FRun_Excel_Form.Free;
      FRun_Excel_Form :
= nil;
      raise exception.Create(
'启动Excel失败,可能没有安装Excel');
      Result :
= False;
      Exit;
    
end;
    FExcel_Handle :
= l_Excel_Handle;
    
if FShow_Progress = True then
    
begin
      FRun_Excel_Form.Free;
      FRun_Excel_Form :
= nil;
    
end;
    Result :
= True;
end;
{插入新的工作}
function TDBGridExport.New_Workbook: Boolean;
var
  i: Integer;
begin
  Result :
= True;
  try
    FWorkbook_Handle :
= FExcel_Handle.Workbooks.Add;
  except
    raise exception.Create(
'新建Excel工作表出错!');
    Result :
= False;
    Exit;
  
end;
  
if FTitle <> '' then
    FWorkbook_Handle.Application.ActiveWindow.Caption :
= FTitle;
  
if FSheetName <> '' then
  
begin
    
for i := 2 to FWorkbook_Handle.Sheets.Count do
      
if FSheetName = FWorkbook_Handle.Sheets[i].Name then
      
begin
        raise exception.Create(
'工作表命名重复!');
        Result :
= False;
        exit;
      
end;
    try
      FWorkbook_Handle.Sheets[
1].Name := FSheetName;
    except
      raise exception.Create(
'工作表命名错误!');
      Result :
= False;
      exit;
    
end;
  
end;
end;
{插入数据}
function TDBGridExport.InsertData_To_Excel: Boolean;
var
  i, j, k: Integer;
  data_Str: string;
  Column_name: string;
  Data_Set: TDataSet;
  bookmark: pointer;
  Before_Scroll, Afrer_Scroll: TDataSetNotifyEvent;
begin
  try
    
{显示插入进度}
    
if FShow_Progress = True then
    
begin
      Create_ProgressForm(
nil);
      FProgress_Form.Show;
    
end;
    
{第一行,插入标题}{仅仅插入可见数据}
    j :
= 1;
    
for i := 1 to FDB_Grid.Columns.Count do
      
if FDB_Grid.Columns[i - 1].Visible = True then
      
begin
        FWorkbook_Handle.WorkSheets[
1].Cells[1, j].Value := FDB_Grid.Columns[i - 1].Title.Caption;
        FWorkbook_Handle.WorkSheets[
1].Columns[j].ColumnWidth := FDB_Grid.Columns[i - 1].Width div 6;
        j :
= j + 1
      
end;
    
{插入DBGrid中的数据}
    Data_Set :
= FDB_Grid.DataSource.DataSet;
    
{记忆当前位置并取消任何事}
    
// new(bookmark);
    bookmark :
= Data_Set.GetBookmark;
    Data_Set.DisableControls;
    Before_Scroll :
= Data_Set.BeforeScroll;
    Afrer_Scroll :
= Data_Set.AfterScroll;
    Data_Set.BeforeScroll :
= nil;
    Data_Set.AfterScroll :
= nil;
    
if FShow_Progress = True then
    
begin
      Data_Set.Last;
      FProgress_Form.Refresh;
      FProgressBar.Max :
= Data_Set.RecordCount;
    
end;
    Data_Set.First;
    k :
= 2;
    
while not Data_Set.Eof do
    
begin
      
if FShow_Progress = True then
        FProgressBar.Position :
= k;
      j :
= 1;
      
for i := 1 to FDB_Grid.Columns.Count do
      
begin
        
if FDB_Grid.Columns[i - 1].Visible = True then
        
begin
          Column_name :
= FDB_Grid.Columns[i - 1].FieldName;
          data_Str :
= FDB_Grid.Fields[i - 1].DisplayText;
          FWorkbook_Handle.WorkSheets[
1].Cells[k, j].Value := data_Str;
          j :
= j + 1;
          
end;
      
end;
      k :
= k + 1;
      Data_Set.Next;
    
end;
    
{恢复原始事件以及标志位置}
    Data_Set.GotoBookmark(bookmark);
    Data_Set.FreeBookmark(bookmark);
    
// dispose(bookmark);
    Data_Set.EnableControls;
    Data_Set.BeforeScroll :
= Before_Scroll;
    Data_Set.AfterScroll :
= Afrer_Scroll;
    Result :
= True;
  finally
    FExcel_Handle.Visible :
= True;
    FExcel_Handle.Application.ScreenUpdating :
= True;
    
if FShow_Progress = True then
    
begin
      FProgress_Form.Free;
      FProgress_Form :
= nil;
    
end;
  
end;
end;

 

{启动Excel时给出进度显}
procedure TDBGridExport.Create_Run_Excel_Form(AOwner: TComponent);
var
  Panel: TPanel;
  Prompt: TLabel; 
{提示的标}
begin
  
if assigned(FRun_Excel_Form) then exit;
    FRun_Excel_Form :
= TForm.Create(AOwner);
  
with FRun_Excel_Form do
  
begin
    try
      Font.Name :
= '宋体'{设置字体}
      Font.Size :
= 9;
      BorderStyle :
= bsNone;
      Width :
= 300;
      Height :
= 100;
      BorderWidth :
= 2;
      Color :
= clBlue;
      Position :
= poScreenCenter;
      Panel :
= TPanel.Create(FRun_Excel_Form);
      
with Panel do
      
begin
        Parent :
= FRun_Excel_Form;
        Align :
= alClient;
        BevelInner :
= bvNone;
        BevelOuter :
= bvRaised;
        Caption :
= '';
      
end;
      Prompt :
= TLabel.Create(Panel);
      
with Prompt do
      
begin
        Parent :
= panel;
        AutoSize :
= True;
        Left :
= 25;
        Top :
= 25;
        Caption :
= '正在导出数据,请稍候…';
      
end;
    except
    
end;
  
end;
end;
{===============================================================================}
{创建进度显示窗口}
procedure TDBGridExport.Create_ProgressForm(AOwner: TComponent);
var
  Panel: TPanel;
  Prompt: TLabel; 
{提示的标}
begin
  
if assigned(FProgress_Form) then exit;
    FProgress_Form :
= TForm.Create(AOwner);
  
with FProgress_Form do
  
begin
    try
      Font.Name :
= '宋体'{设置字体}
      Font.Size :
= 9;
      BorderStyle :
= bsNone;
      Width :
= 300;
      Height :
= 100;
      BorderWidth :
= 2;
      Color :
= clBlue;
      Position :
= poScreenCenter;
      Panel :
= TPanel.Create(FProgress_Form);
      
with Panel do
        
begin
        Parent :
= FProgress_Form;
        Align :
= alClient;
        BevelInner :
= bvNone;
        BevelOuter :
= bvRaised;
        Caption :
= '';
      
end;
      Prompt :
= TLabel.Create(Panel);
      
with Prompt do
      
begin
        Parent :
= panel;
        AutoSize :
= True;
        Left :
= 25;
        Top :
= 25;
        Caption :
= '正在导出数据,请稍候…';
      
end;
      FProgressBar :
= TProgressBar.Create(panel);
      
with FProgressBar do
      
begin
        Parent :
= panel;
        Left :
= 20;
        Top :
= 50;
        Height :
= 18;
        Width :
= 260;
      
end;
    except
    
end;
  
end;
end;
end.


📱 扫码关注公众号

公众号二维码

扫描二维码关注我们,获取更多精彩内容
实时更新 · 干货满满

收藏

扫描二维码,在手机上阅读
评论
更换验证码
友情链接