电信主站 网通分站
购买流程 付款方式 常见问题 在线提问 续租服务 购物车
用户名: 密 码: 忘记密码?
首 页
域名注册
虚拟主机
双线主机
服务器租用
VPS主机
企业邮局
代理专区
客服中心
虚拟主机行业资讯 虚拟主机评测对比 互联网最新动态 技术学院 站长资讯 在线教程 网站运营
搜索优化 服务器 网络编程 图形图象 站长之家 网页制作 操作系统
冲浪宝典 软件教学 视频通信 办公软件 邮件系统 网络安全 认证考试
您当前位置:西部数码->资讯中心-> 网络编程 -> Delphi教程
修改的一个导出dataset到xls的单元_delphi教程
作者:网友供稿 点击:0
  西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!虚拟主机可在线rar解压,自动数据恢复设置虚拟目录等.虚拟主机免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金!
文章页数:[1] 

//首先感谢原作者,但当初在csdn上搜索到该单元时,就没原作者的信息(程序里的有些乱码的注释应该是原作者留下的吧?呵呵)
//有不足的地方还请各位看官多多指点哈 ^_^

(* Modify By 角落的青苔@2005/05/13
   说明:增加导出过程中的回调功能(用户停止,进度条)
         是否在第一行插入FieldName
         改错:以前只能对word类型数值写入,DWord会Range Check error;已修正,见CellInteger
         //这个单元原来的Col和Row刚好弄反了(已修正):-(
         增加导出分页的功能,因为xls单页不能超过 65536 行(采用的笨办法,不知谁有好一点的方法吗?比如直接写标记表示分页?)
*)

unit UnitXLSFile;

interface

uses
  Windows, Messages, Variants, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  DB,DBGrids, OleServer, Excel2000;

const _MSG_XLSWriterIsRuning=有其它任务正在导出数据,暂时不能执行该操作,请稍后重试!;
type
  TUserCommand=(UserStop, UserNeedSave, UserNotSave, UserSkip, UserDoNothing);
  TExportXls_CallBackProc = procedure(iPos:Real) of object;

  TAtributCell = (acHidden,acLocked,acShaded,acBottomBorder,acTopBorder,
                acRightBorder,acLeftBorder,acLeft,acCenter,acRight,acFill);

  TSetOfAtribut = set of TatributCell;

  TXLSWriter = class(TObject)
  private
    fstream:TFileStream;
    procedure WriteWord(w:word);
    procedure SetCellAtribut(value:TSetOfAtribut;var FAtribut:array of byte);
  protected
    procedure WriteBOF;
    procedure WriteEOF;
    procedure WriteDimension;
  public
    maxCols,maxRows:Word;
    //add by 角落的青苔@2005/05/18
    procedure CellInteger(vRow,vCol:word;aValue:Integer;vAtribut:TSetOfAtribut=[]);
    procedure CellDouble(vRow,vCol:word;aValue:double;vAtribut:TSetOfAtribut=[]);
    procedure CellStr(vRow,vCol:word;aValue:String;vAtribut:TSetOfAtribut=[]);
    procedure WriteField(vRow,vCol:word;Field:TField);
    constructor Create(vFileName:string;const vMaxCols:Integer=100;const vMaxRows:Integer=65534);
    destructor Destroy;override;
  end;

procedure DataSetToXLS(ds:TDataSet;fname:String);
//Add By 角落的青苔@2005/05/13 //只能导出最多65536条记录
procedure DBGridToXLS(Grid:TDBGrid;fname:String; bSetFieldName:Boolean;CallFunc:TExportXls_CallBackProc; bAskForStop:Boolean=True );
//Add By 角落的青苔@2005/05/19
//突破xls单页65536行的限制,把数据分成数页
function DBGridToXlsEx(Grid:TDBGrid;fname:String; bSetFieldName:Boolean;CallFunc:TExportXls_CallBackProc;const bAskForStop:Boolean=True; const bNeedUnite:Boolean=True ):Integer;
//将数个XLS合并成一个(分页),必须保证Path最后无\或/,实际已经做成线程,以免程序无响应
procedure UniteSeveralXLSToOne(const TmpFlag, Path, FileName : String;const iStart, iEnd : Integer);
//procedure StringGridToXLS(grid:TStringGrid;fname:String);

var
  G_UserCmd:TUserCommand;
  G_XLSWriterIsRuning : Boolean; //是否有XLSWriter实例在运行,因为G_UserCmd是全局变量,防止被非法刷新
implementation

const
{BOF}
  CBOF      = $0009;
  BIT_BIFF5 = $0800;
  BOF_BIFF5 = CBOF or BIT_BIFF5;
{EOF}
  BIFF_EOF = $000a;
{Document types}
  DOCTYPE_XLS = $0010;
{Dimensions}
  DIMENSIONS = $0000;

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);
type
  //合并数个Xls为一个多页面xls的线程
  TUniteSeveralXLSToOneThread = class(TThread)
  private
    TmpFlag : String;
    Path : String;
    FileName : String;
    iStart : Integer;
    iEnd : Integer;
  protected
    mCompleted : Boolean;
    procedure Execute; override;
  public
    constructor Create(const _TmpFlag, _Path, _FileName:String;const _iStart, _iEnd : Integer);
    destructor Destroy; override;
  end;

//根据StrFlags在FullStr最后出现的位置,将FullStr分割成两部分,取得的两部分均不包含StrFlags
procedure SplitStrToTwoPartByLastFlag(const FullStr,StrFlags:String;var strLeft,strRight:String);
var iPos:Integer;
begin
  iPos := LastDelimiter(StrFlags,FullStr);
  strLeft := Copy(FullStr, 1, iPos-1);
  strRight := Copy(FullStr, iPos+1, Length(FullStr)-iPos);
end;

constructor TUniteSeveralXLSToOneThread.Create(const _TmpFlag, _Path, _FileName:String;const _iStart, _iEnd : Integer);
begin
  inherited Create(True);
  TmpFlag := _TmpFlag;
  Path := _Path;
  FileName := _FileName;
  iStart := _iStart;
  iEnd := _iEnd;
  mCompleted := False;
  Resume();
end;

destructor TUniteSeveralXLSToOneThread.Destroy;
begin
  inherited;
end;

procedure TUniteSeveralXLSToOneThread.Execute;
const
  _HeadLetterOfXls:Array [1..52]of String    //注意这里只定义了52列,需要增加就自己动手,最多256列
            = (A,B,C,D,E,F,G,H,I,J,K,L,M,
               N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
               AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,
               AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ);
  _XlsResCaption= FKULWJS_SKSLA_892x_RES;
  _XlsTmpCaption= FKULWJS_SKSLA_892x_TMP;
var
  XlsAppRes, XlsAppTmp: TExcelApplication;
  wkBookRes, wkBookTmp : _WorkBook;
  wkSheetRes, wkSheetTmp : _WorkSheet;
  LCID_Res, LCID_Tmp:Integer;
  Pos_LeftTop, Pos_RightBottom : String; //Xls中左上、右下位置
  XlsAppHwnd:THandle;
  bDontSave : Boolean;
  i : Integer;

  StrName,StrExt:String; //文件名及扩展名
begin
  FreeOnTerminate := True;
  if Terminated then Exit;
  SplitStrToTwoPartByLastFlag(FileName, ., StrName, StrExt);
  try
    Screen.Cursor := crHourGlass;
    bDontSave := False;
    XlsAppRes := TExcelApplication.Create(Nil);
    with XlsAppRes do
    begin
      Connect;
      Visible[0]:=False;
      LCID_Res:=GetUserDefaultLCID();
      DisplayAlerts[LCID_Res]:=False;
      Caption:=_XlsResCaption;
      wkBookRes:=WorkBooks.Add(EmptyParam,LCID_Res);
    end;
    XlsAppTmp := TExcelApplication.Create(Nil);
    with XlsAppTmp do
    begin
      Connect;
      Visible[0]:=False;
      LCID_Tmp :=GetUserDefaultLCID();
      DisplayAlerts[LCID_Tmp]:=False;
      Caption:=_XlsTmpCaption;
    end;
    for i:=iStart to iEnd do
    begin
      if i<=3 then wkSheetRes:=wkBookRes.Sheets[i] as _WorkSheet
      else
      begin
        wkBookRes.Sheets.Add(EmptyParam, wkSheetRes, 1, EmptyParam, LCID_Res);
        wkSheetRes := wkBookRes.Sheets[i] as _WorkSheet;
      end;
      wkBookTmp:= XlsAppTmp.WorkBooks.Open(Path+\+TmpFlag+IntToStr(i)+FileName, EmptyParam,EmptyParam,
                    EmptyParam,EmptyParam,EmptyParam,EmptyParam,
                    EmptyParam,EmptyParam,EmptyParam,EmptyParam,
                    EmptyParam,EmptyParam,LCID_Tmp);
      Pos_LeftTop := A1;
      wkSheetTmp := XlsAppTmp.ActiveSheet as _WorkSheet;
      Pos_RightBottom := _HeadLetterOfXls[wkSheetTmp.UsedRange[LCID_Tmp].Columns.Count]+IntToStr(wkSheetTmp.UsedRange[LCID_Tmp].Rows.Count);
      XlsAppTmp.Range[Pos_LeftTop, Pos_RightBottom].Copy(EmptyParam);
      wkSheetRes.Activate(LCID_Res);
      wkSheetRes.Range[Pos_LeftTop, Pos_RightBottom].Select;
      wkSheetRes.Paste(EmptyParam, EmptyParam, LCID_Res);
      wkSheetRes.Columns.AutoFit;
      wkSheetRes.Range[A1,A1].Select;
      wkSheetRes.Name := StrName+_+IntToStr(i);
    end;
  finally
    try
      (wkBookRes.Sheets[1] as _WorkSheet).Activate(LCID_Res);
      wkBookRes.Close(Not(bDontSave) ,Path+\+FileName,EmptyParam,LCID_Res);
      XlsAppRes.Quit;
      XlsAppRes.Disconnect;
    finally
      //杀死未关闭的Excel进程
      XlsAppHwnd := FindWindow( Nil,_XlsResCaption );
      if XlsAppHwnd<>0 then SendMessage( XlsAppHwnd, WM_CLOSE, 0, 0);
    end;
    try
      //wkBookTmp.Close(False ,Path+\+TmpFlag+IntToStr(i)+FileName,EmptyParam,LCID_Tmp);
      XlsAppTmp.Quit;
      XlsAppTmp.Disconnect;
    finally
      XlsAppHwnd := FindWindow( Nil,_XlsTmpCaption );
      if XlsAppHwnd<>0 then SendMessage( XlsAppHwnd, WM_CLOSE, 0, 0);
        //TerminateProcess(XlsAppHwnd,0);
    end;
    mCompleted := True;
    Screen.Cursor := crDefault;
  end;
end;

procedure DataSetToXLS(ds:TDataSet;fname:String);
var c,r:Integer;
  xls:TXLSWriter;
begin
  xls:=TXLSWriter.create(fname);
  if ds.FieldCount > xls.maxcols then
    xls.maxcols:=ds.fieldcount+1;
  try
    xls.writeBOF;
    xls.WriteDimension;
    for c:=0 to ds.FieldCount-1 do
      xls.Cellstr(0,c,ds.Fields[c].DisplayLabel);
    r:=1;
    ds.first;
    while (not ds.eof) and (r <= xls.maxrows) do begin
      for c:=0 to ds.FieldCount-1 do
        if ds.Fields[c].AsString<> then
          xls.WriteField(r,c,ds.Fields[c]);
      inc(r);
      ds.next;
    end;
    xls.writeEOF;
  finally
    xls.free;
  end;
end;

procedure DBGridToXLS(Grid:TDBGrid;fname:String; bSetFieldName:Boolean;CallFunc:TExportXls_CallBackProc;  bAskForStop:Boolean=True);
var c,r,i :Integer;
  xls:TXLSWriter;
  nTotalCount, nCurrentCount : Integer;
  bDontSave:Boolean;
begin
  bDontSave := False;
  Grid.DataSource.DataSet.DisableControls;
  xls:=TXLSWriter.create(fname);
  if Grid.FieldCount > xls.maxcols then
    xls.maxcols:=Grid.fieldcount+1;
  try      
    G_XLSWriterIsRuning := True;
    xls.writeBOF;
    xls.WriteDimension;
    if bSetFieldName then
    begin
      for c:=0 to Grid.FieldCount-1 do
        xls.Cellstr(0,c,Grid.Fields[c].FieldName);
      r :=2;
    end
    else r:=1;
    for c:=0 to Grid.FieldCount-1 do
      xls.Cellstr(r-1,c,Grid.Fields[c].DisplayLabel);
    nTotalCount := Grid.DataSource.DataSet.RecordCount;
    nCurrentCount := 0;
    bDontSave := False;
    Grid.DataSource.DataSet.First;
    for i:=0 to nTotalCount-1 do
    begin
      Application.ProcessMessages;
      if r > xls.maxrows then Raise Exception.Create(导出的数据超过+IntToStr(xls.maxrows)+条记录,操作失败!);
      Inc(nCurrentCount);
      CallFunc(nCurrentCount/nTotalCount);
      if G_UserCmd=UserStop then
      begin
        if bAskForStop then
        case Application.MessageBox(您停止了导出数据,请问需要保存吗?(选择“取消”继续导出),询问,MB_YESNOCANCEL) of
          IDYES: Break;
          IDNO: begin
                  bDontSave := True;
                  Raise Exception.Create(用户停止,导出数据未保存!);
                end;
          IDCANCEL: G_UserCmd := UserDoNothing;
        end
        else begin bDontSave := True; Raise Exception.Create(用户停止,导出数据未保存!); end;
      end;
      for c:=0 to Grid.FieldCount-1 do
        if (Grid.Fields[c].AsString<>) then
          xls.WriteField(r,c,Grid.Fields[c]);
      inc(r);
      Grid.DataSource.DataSet.Next;
    end;
  finally
    xls.writeEOF;
    xls.free;
    if bDontSave then DeleteFile(fname);
    Grid.DataSource.DataSet.EnableControls;
    G_XLSWriterIsRuning := False;   
  end;
end;

//将数个XLS合并成一个(分页)
procedure UniteSeveralXLSToOne(const TmpFlag, Path, FileName : String;const iStart, iEnd : Integer);
const
  _HeadLetterOfXls:Array [1..52]of String
            = (A,B,C,D,E,F,G,H,I,J,K,L,M,
               N,O,P,Q,R,S,T,U,V,W,X,Y,Z,
               AA,AB,AC,AD,AE,AF,AG,AH,AI,AJ,AK,AL,AM,
               AN,AO,AP,AQ,AR,AS,AT,AU,AV,AW,AX,AY,AZ);
  _XlsResCaption= FKULWJS_SKSLA_892x_RES;
  _XlsTmpCaption= FKULWJS_SKSLA_892x_TMP;
var
  XlsAppRes, XlsAppTmp: TExcelApplication;
  wkBookRes, wkBookTmp : _WorkBook;
  wkSheetRes, wkSheetTmp : _WorkSheet;
  LCID_Res, LCID_Tmp:Integer;
  Pos_LeftTop, Pos_RightBottom : String; //Xls中左上、右下位置
  XlsAppHwnd:THandle;
  bDontSave : Boolean;
  i : Integer;

  StrName,StrExt:String; //文件名及扩展名
begin
  SplitStrToTwoPartByLastFlag(FileName, ., StrName, StrExt);
  try
    bDontSave := False;
    XlsAppRes := TExcelApplication.Create(Nil);
    with XlsAppRes do
    begin
      Connect;
      Visible[0]:=False;
      LCID_Res:=GetUserDefaultLCID();
      DisplayAlerts[LCID_Res]:=False;
      Caption:=_XlsResCaption;
      wkBookRes:=WorkBooks.Add(EmptyParam,LCID_Res);
    end;
    XlsAppTmp := TExcelApplication.Create(Nil);
    with XlsAppTmp do
    begin
      Connect;
      Visible[0]:=False;
      LCID_Tmp :=GetUserDefaultLCID();
      DisplayAlerts[LCID_Tmp]:=False;
      Caption:=_XlsTmpCaption;
    end;
    for i:=iStart to iEnd do
    begin
      if i<=3 then wkSheetRes:=wkBookRes.Sheets[i] as _WorkSheet
      else
      begin
        wkBookRes.Sheets.Add(EmptyParam, wkSheetRes, 1, EmptyParam, LCID_Res);
        wkSheetRes := wkBookRes.Sheets[i] as _WorkSheet;
      end;
      wkBookTmp:= XlsAppTmp.WorkBooks.Open(Path+\+TmpFlag+IntToStr(i)+FileName, EmptyParam,EmptyParam,
                    EmptyParam,EmptyParam,EmptyParam,EmptyParam,
                    EmptyParam,EmptyParam,EmptyParam,EmptyParam,
                    EmptyParam,EmptyParam,LCID_Tmp);
      Pos_LeftTop := A1;
      wkSheetTmp := XlsAppTmp.ActiveSheet as _WorkSheet;
      Pos_RightBottom := _HeadLetterOfXls[wkSheetTmp.UsedRange[LCID_Tmp].Columns.Count]+IntToStr(wkSheetTmp.UsedRange[LCID_Tmp].Rows.Count);
      XlsAppTmp.Range[Pos_LeftTop, Pos_RightBottom].Copy(EmptyParam);
      wkSheetRes.Activate(LCID_Res);
      wkSheetRes.Range[Pos_LeftTop, Pos_RightBottom].Select;
      wkSheetRes.Paste(EmptyParam, EmptyParam, LCID_Res);
      wkSheetRes.Columns.AutoFit;
      wkSheetRes.Range[A1,A1].Select;
      wkSheetRes.Name := StrName+__+IntToStr(i);
    end;
  finally
    try
      (wkBookRes.Sheets[1] as _WorkSheet).Activate(LCID_Res);
      wkBookRes.Close(Not(bDontSave) ,Path+\+FileName,EmptyParam,LCID_Res);
      XlsAppRes.Quit;
      XlsAppRes.Disconnect;
    finally
      //杀死未关闭的Excel进程
      XlsAppHwnd := FindWindow( Nil,_XlsResCaption );
      if XlsAppHwnd<>0 then SendMessage( XlsAppHwnd, WM_CLOSE, 0, 0);
    end;
    try
      //wkBookTmp.Saved[LCID_Tmp]:=True;
      XlsAppTmp.Quit;
      XlsAppTmp.Disconnect;
    finally
      XlsAppHwnd := FindWindow( Nil,_XlsTmpCaption );
      if XlsAppHwnd<>0 then SendMessage( XlsAppHwnd, WM_CLOSE, 0, 0);
    end;
  end;
end;

function DBGridToXlsEx(Grid:TDBGrid;fname:String; bSetFieldName:Boolean;CallFunc:TExportXls_CallBackProc;const bAskForStop:Boolean; const bNeedUnite:Boolean ):Integer;
var
  c,r,i :Integer;
  xls:TXLSWriter;
  nTotalCount, nCurrentCount : Integer;
  bDontSave:Boolean;
  nOneSheetMaxRecord : Integer;
  Path, FileName, tmpFile:String;
  bNotEof : Boolean;
begin
  G_XLSWriterIsRuning := True;
  Result := 0;
  bDontSave := False;
  nTotalCount := Grid.DataSource.DataSet.RecordCount;
  nCurrentCount := 0;
  SplitStrToTwoPartByLastFlag(fname,\/,Path,FileName);
  Grid.DataSource.DataSet.DisableControls;
  bNotEof := True;
  try
    while bNotEof do
    begin
      Inc(Result);
      tmpFile := Path+\$$$+IntToStr(Result)+FileName;
      DeleteFile(tmpFile);
      xls:=TXLSWriter.Create(tmpFile,Grid.FieldCount+1, 65530 );    //65530
      if Grid.FieldCount > xls.maxCols then
        xls.maxCols := Grid.FieldCount+1;
      try
        xls.WriteBOF;
        xls.WriteDimension;
        if bSetFieldName then
        begin
          for c:=0 to Grid.FieldCount-1 do
            xls.Cellstr(0,c,Grid.Fields[c].FieldName);
          r :=2;
        end
        else r:=1;
        for c:=0 to Grid.FieldCount-1 do
          xls.Cellstr(r-1,c,Grid.Fields[c].DisplayLabel);

        Grid.DataSource.DataSet.First;
        Grid.DataSource.DataSet.MoveBy(nCurrentCount);
        if nTotalCount-nCurrentCount>xls.maxrows then nOneSheetMaxRecord := xls.maxRows
        else nOneSheetMaxRecord := nTotalCount-nCurrentCount;
        for i:=0 to nOneSheetMaxRecord-1 do
        begin
          Application.ProcessMessages;
          Inc(nCurrentCount);
          CallFunc(nCurrentCount/nTotalCount);
          if G_UserCmd=UserStop then
          begin
            if bAskForStop then
            case Application.MessageBox(您停止了导出数据,请问需要保存吗?(选择“取消”继续导出),询问,MB_YESNOCANCEL) of
              IDYES:begin
                      G_UserCmd := UserNeedSave;
                      Break;
                    end;
              IDNO: begin
                      G_UserCmd := UserNotSave;
                      bDontSave := True;
                      Raise Exception.Create(用户停止,导出数据未保存!);
                    end;
              IDCANCEL: G_UserCmd := UserDoNothing;
            end
            else begin bDontSave := True; Raise Exception.Create(用户停止,导出数据未保存!); end;
          end;
          for c:=0 to Grid.FieldCount-1 do
            if (Grid.Fields[c].AsString<>) then
              xls.WriteField(r,c,Grid.Fields[c]);
          inc(r);
          Grid.DataSource.DataSet.Next;
        end;
        xls.writeEOF;
      finally
        xls.Free;
      end;
      bNotEof := (Not Grid.DataSource.DataSet.Eof) and (G_UserCmd = UserDoNothing);
    end; //Not Grid.DataSource.DataSet.Eof
  finally
    if bDontSave then
      for i:=1 to Result do DeleteFile(Path+\$$$+IntToStr(i)+FileName);
    Grid.DataSource.DataSet.EnableControls;
  end;
  if bNeedUnite and (Not bDontSave) then
  begin
    if Result=1 then
    begin
      DeleteFile(fname);
      RenameFile(tmpFile, fname)
    end
    else
    begin
      with TUniteSeveralXLSToOneThread.Create($$$, Path, FileName, 1, Result) do
      begin
        while Not mCompleted do
        begin
          Application.ProcessMessages;
          Sleep(0);
        end;
      end;
      for i:=1 to Result do DeleteFile(Path+\$$$+IntToStr(i)+FileName);
    end;
  end;
  G_XLSWriterIsRuning := False;
end;
(*
procedure StringGridToXLS(grid:TStringGrid;fname:String);
var c,r,rMax:Integer;
  xls:TXLSWriter;
begin
  xls:=TXLSWriter.create(fname);
  rMax:=grid.RowCount;
  if grid.ColCount > xls.maxcols then
    xls.maxcols:=grid.ColCount+1;
  if rMax > xls.maxrows then          // &brvbar;&sup1;&reg;&aelig;&brvbar;&iexcl;&sup3;&Igrave;&brvbar;h&yen;u&macr;à&brvbar;s 65535 Rows
    rMax:=xls.maxrows;
  try
    xls.writeBOF;
    xls.WriteDimension;
    for c:=0 to grid.ColCount-1 do
      for r:=0 to rMax-1 do
        xls.Cellstr(r,c,grid.Cells[c,r]);
    xls.writeEOF;
  finally
    xls.free;
  end;
end;
*)
{ TXLSWriter }

constructor TXLSWriter.Create(vFileName:string;const vMaxCols, vMaxRows:Integer);
begin
  inherited create;
  if FileExists(vFilename) then
    fStream:=TFileStream.Create(vFilename,fmOpenWrite)
  else
    fStream:=TFileStream.Create(vFilename,fmCreate);
  if vMaxCols<100 then maxCols := vMaxCols   //modify by 角落的青苔@2005/05/19
  else maxCols := 100;
  if vMaxCols<65535 then maxRows := vMaxRows
  else maxRows := 65535;
  //maxCols:=100;   // <2002-11-17> dllee Column &Agrave;&sup3;&cedil;&Oacute;&not;O¤&pound;&yen;i&macr;à¤j&copy;ó 65535, &copy;&Ograve;&yen;H¤&pound;&brvbar;A&sup3;B&sup2;z
  //maxRows:=65530;//65535; // <2002-11-17> dllee &sup3;o&shy;&Oacute;&reg;&aelig;&brvbar;&iexcl;&sup3;&Igrave;¤j&yen;u&macr;à&sup3;o&raquo;ò¤j&iexcl;A&frac12;&ETH;&ordf;`·N¤j&ordf;&ordm;&cedil;ê&reg;&AElig;&reg;w&laquo;&Uuml;&reg;e&copy;&ouml;&acute;N¤j&copy;ó&sup3;o&shy;&Oacute;&shy;&Egrave;
end;

destructor TXLSWriter.Destroy;
begin
  if fStream <> nil then
    fStream.free;
  inherited;
end;

procedure StreamWriteWordArray(Stream: TStream; wr: array of Word);
var
  i: Integer;
begin
  for i := 0 to Length(wr)-1 do
{$IFDEF CIL}
    Stream.Write(wr[i]);
{$ELSE}
    Stream.Write(wr[i], SizeOf(wr[i]));
{$ENDIF}
end;

procedure StreamWriteAnsiString(Stream: TStream; S: String);
{$IFDEF CIL}
var
  b: TBytes;
{$ENDIF}
begin
{$IFDEF CIL}
    b := BytesOf(AnsiString(S));
    Stream.Write(b, Length(b));
{$ELSE}
    Stream.Write(PChar(S)^, Length(S));
{$ENDIF}
end;

procedure TXLSWriter.WriteBOF;
begin
  Writeword(BOF_BIFF5);
  Writeword(6);           // count of bytes
  Writeword(0);
  Writeword(DOCTYPE_XLS);
  Writeword(0);
end;

procedure TXLSWriter.WriteDimension;
begin
  Writeword(DIMENSIONS);  // dimension OP Code
  Writeword(8);           // count of bytes
  Writeword(0);           // min cols
  Writeword(maxRows);     // max rows
  Writeword(0);           // min rowss
  Writeword(maxcols);     // max cols
end;

procedure TXLSWriter.CellDouble(vRow, vCol: word; aValue: double;
  vAtribut: TSetOfAtribut);
//var  FAtribut:array [0..2] of byte;
begin
  CXlsNumber[2] := vRow;
  CXlsNumber[3] := vCol;
  StreamWriteWordArray(fStream, CXlsNumber);
  //SetCellAtribut(vAtribut,fAtribut);
  //fStream.Write(fAtribut,3);
  fStream.WriteBuffer(aValue, 8);
end;

procedure TXLSWriter.CellInteger(vRow,vCol:word;aValue:Integer;vAtribut:TSetOfAtribut=[]);
var V:Integer;
begin
  CXlsRk[2] := vRow;
  CXlsRk[3] := vCol;
  StreamWriteWordArray(fStream, CXlsRk);
  V := (aValue shl 2) or 2;
  fStream.WriteBuffer(V, 4);
end;

procedure TXLSWriter.CellStr(vRow, vCol: word; aValue: String;
  vAtribut: TSetOfAtribut);
var slen:Word;
begin
  slen := Length(aValue);
  CXlsLabel[1] := 8 + slen;
  CXlsLabel[2] := vRow;
  CXlsLabel[3] := vCol;
  //SetCellAtribut(vAtribut, CXlsLabel[4]);
  CXlsLabel[5] := slen;
  StreamWriteWordArray(fStream, CXlsLabel);
  StreamWriteAnsiString(fStream, aValue);
end;

procedure TXLSWriter.SetCellAtribut(value:TSetOfAtribut;var FAtribut:array of byte);
var
   i:integer;
begin
 //reset
  for i:=0 to High(FAtribut) do
    FAtribut[i]:=0;


     if  acHidden in value then       //byte 0 bit 7:
         FAtribut[0] := FAtribut[0] + 128;

     if  acLocked in value then       //byte 0 bit 6:
         FAtribut[0] := FAtribut[0] + 64 ;

     if  acShaded in value then       //byte 2 bit 7:
         FAtribut[2] := FAtribut[2] + 128;

     if  acBottomBorder in value then //byte 2 bit 6
         FAtribut[2] := FAtribut[2] + 64 ;

     if  acTopBorder in value then    //byte 2 bit 5
         FAtribut[2] := FAtribut[2] + 32;

     if  acRightBorder in value then  //byte 2 bit 4
         FAtribut[2] := FAtribut[2] + 16;

     if  acLeftBorder in value then   //byte 2 bit 3
         FAtribut[2] := FAtribut[2] + 8;

     // <2002-11-17> dllee &sup3;&Igrave;&laquo;á 3 bit &Agrave;&sup3;&yen;u&brvbar;&sup3; 1 &ordm;&Oslash;&iquest;&iuml;&frac34;&Uuml;
     if  acLeft in value then         //byte 2 bit 1
         FAtribut[2] := FAtribut[2] + 1
     else if  acCenter in value then  //byte 2 bit 1
         FAtribut[2] := FAtribut[2] + 2
     else if acRight in value then    //byte 2, bit 0 dan bit 1
         FAtribut[2] := FAtribut[2] + 3
     else if acFill in value then     //byte 2, bit 0
         FAtribut[2] := FAtribut[2] + 4;
end;

procedure TXLSWriter.WriteWord(w: word);
begin
  fstream.Write(w,2);
end;

procedure TXLSWriter.WriteEOF;
begin
  Writeword(BIFF_EOF);
  Writeword(0);
end;

procedure TXLSWriter.WriteField(vRow, vCol: word; Field: TField);
begin
  case field.DataType of
     ftString,ftWideString,ftBoolean,ftDate,ftDateTime,ftTime:
       Cellstr(vRow,vCol,field.asstring);
     ftSmallint, ftInteger, ftWord, ftAutoInc, ftBytes:
       CellInteger(vRow,vCol,field.AsInteger);
     ftFloat, ftBCD:
       CellDouble(vRow,vCol,field.AsFloat);
  else
       Cellstr(vRow,vCol,EmptyStr);   // <2002-11-17> dllee ¨&auml;&yen;L&laquo;&not;&ordm;A&frac14;g¤J&ordf;&Aring;&yen;&Otilde;&brvbar;r&brvbar;ê
  end;
end;

initialization
  G_XLSWriterIsRuning := False;
 
end.


文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!
相关主题
文章页数:[1] 
Google
热门文章
·如何在启动机器时自动运行adsl拨号(1)_delphi教程
·delphi的通配符比较(第五版)_delphi教程
·delphi托盘编程实战演练_delphi教程
·关于中文折行及相关问题的解决方法_delphi教程
·字幕图标控件_delphi教程
·一个很简单的加密算法_delphi教程
·winapi编程关闭qq登录窗体_delphi教程
·组件开发方式_delphi教程
·用ehlib二次开发报表打印程序,实现财务凭证的打印(三)_delphi教程
·delphi+汇编例子1(求和的比较)_delphi教程

最新文章
·阻止windwos xp系统蓝屏的几大绝招_windows xp
·photoshop极坐标滤镜巧绘三维游泳圈_photoshop教程
·photoshop将美女照片转为手绘效果_photoshop教程
·zend studio5.5测试版 兼容三系统_php文摘
·photoshop调整图片对比度方法浅析_photoshop教程
·一个设置任意窗口透明度的命令行delphi程序_delphi教程
·photoshop基础教程:跟我学调色练习3-润色_photoshop教程
·windows xp空间:文件的属性也玩“花样”_windows xp
·轻松清理windows xp系统垃圾_windows xp
·配景的使用与创建_autocad教程


 
 


版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!

特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
  打印  刷新  关闭
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 虚拟主机 | 资讯中心 | 友情链接 | 网站地图

版权所有 西部数码(www.west263.com)
CopyRight (c) 2002~2006 west263.com all right reserved.
公司地址:四川成都市万和路90号天象大厦4楼 邮编:610031
电话总机:028-86262244 86263048 86263408 86263960 86264018 86267838
售前咨询:总机转201 202 203 204 206 208
售后服务:总机转211 212 213 214
财务咨询:总机转224 223 传真:028-86264041 财务QQ:点击发送消息给对方635483282
售前咨询QQ:点击发送消息给对方2182518 点击发送消息给对方241975952 点击发送消息给对方275026793 点击发送消息给对方408235859
售后服务QQ:点击发送消息给对方17708515 点击发送消息给对方307742704 点击发送消息给对方287976517 点击发送消息给对方363783715
《中华人民共和国增值电信业务经营许可证》编号:川B2-20030065号