還是dephi,

// 程式來源 http://delphi.ktop.com.tw
// 原作者:Yudi Wibisono XLSFILE元件
// CCCHEN:改為Function版
// 領航天使:除錯
// dllee: 加入 StringGridToXLS(), 修正一些小 BUG, 指定此格式最大 Rows 數,以免爆了產生出的檔案不能用

unit XLSFile;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Grids, Forms, Dialogs,db,dbctrls,comctrls;

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;

type
  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);
  protected
    procedure WriteBOF;
    procedure WriteEOF;
    procedure WriteDimension;
  public
    maxCols,maxRows:Word;
    procedure CellWord(vCol,vRow:word;aValue:word;vAtribut:TSetOfAtribut=[]);
    procedure CellDouble(vCol,vRow:word;aValue:double;vAtribut:TSetOfAtribut=[]);
    procedure CellStr(vCol,vRow:word;aValue:String;vAtribut:TSetOfAtribut=[]);
    procedure WriteField(vCol,vRow:word;Field:TField);
    constructor create(vFileName:string);
    destructor destroy;override;
  end;

procedure SetCellAtribut(value:TSetOfAtribut;var FAtribut:array of byte);
procedure DataSetToXLS(ds:TDataSet;fname:String);
procedure StringGridToXLS(grid:TStringGrid;fname:String);

implementation

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
     if ds.Fields[c].Visible then                  // add by lee, only visible fields
      xls.Cellstr(0,c,ds.Fields[c].DisplayLabel);
      //xls.Cellstr(0,c,ds.Fields[c].FieldName);  // modify by lee
    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].Visible then             // add by lee, only visible fields
        xls.WriteField(r,c,ds.Fields[c]);
      inc(r);
      ds.next;
    end;
    xls.writeEOF;

    // <2002-11-17> dllee
    // 更新 Dimension 應在 wirteEOF 之後,因為在此 if 內用了 Seek 改變 position
    // if r > xls.maxrows then begin
    //   xls.maxrows:=r+1;
    //   xls.fstream.Seek(10,soFromBeginning);
    //   xls.WriteDimension;
    // end;
    // 但因為已將 maxrows 設為最大值,而且此格式就只能有 65535,所以,不再判斷。
  finally
    xls.free;
  end;
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          // 此格式最多只能存 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);
begin
  inherited create;
  if FileExists(vFilename) then
    fStream:=TFileStream.Create(vFilename,fmOpenWrite)
  else
    fStream:=TFileStream.Create(vFilename,fmCreate);

  maxCols:=100;   // <2002-11-17> dllee Column 應該是不可能大於 65535, 所以不再處理
  maxRows:=65535; // <2002-11-17> dllee 這個格式最大只能這麼大,請注意大的資料庫很容易就大於這個值
end;

destructor TXLSWriter.destroy;
begin
  if fStream <> nil then
    fStream.free;
  inherited;
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(vCol, vRow: word; aValue: double;
  vAtribut: TSetOfAtribut);
var  FAtribut:array [0..2] of byte;
begin
  Writeword(3);           // opcode for double
  Writeword(15);          // count of byte
  Writeword(vCol);
  Writeword(vRow);
  SetCellAtribut(vAtribut,fAtribut);
  fStream.Write(fAtribut,3);
  fStream.Write(aValue,8);
end;

procedure TXLSWriter.CellWord(vCol,vRow:word;aValue:word;vAtribut:TSetOfAtribut=[]);
var  FAtribut:array [0..2] of byte;
begin
  Writeword(2);           // opcode for word
  Writeword(9);           // count of byte
  Writeword(vCol);
  Writeword(vRow);
  SetCellAtribut(vAtribut,fAtribut);
  fStream.Write(fAtribut,3);
  Writeword(aValue);
end;

procedure TXLSWriter.CellStr(vCol, vRow: word; aValue: String;
  vAtribut: TSetOfAtribut);
var  FAtribut:array [0..2] of byte;
  slen:byte;
begin
  Writeword(4);           // opcode for string
  slen:=length(avalue);
  Writeword(slen+8);      // count of byte
  Writeword(vCol);
  Writeword(vRow);
  SetCellAtribut(vAtribut,fAtribut);
  fStream.Write(fAtribut,3);
  fStream.Write(slen,1);
  fStream.Write(aValue[1],slen);
end;

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

     {Byte Offset     Bit   Description                     Contents
     0          7     Cell is not hidden              0b
                      Cell is hidden                  1b
                6     Cell is not locked              0b
                      Cell is locked                  1b
                5-0   Reserved, must be 0             000000b
     1          7-6   Font number (4 possible)
                5-0   Cell format code
     2          7     Cell is not shaded              0b
                      Cell is shaded                  1b
                6     Cell has no bottom border       0b
                      Cell has a bottom border        1b
                5     Cell has no top border          0b
                      Cell has a top border           1b
                4     Cell has no right border        0b
                      Cell has a right border         1b
                3     Cell has no left border         0b
                      Cell has a left border          1b
                2-0   Cell alignment code
                           general                    000b
                           left                       001b
                           center                     010b
                           right                      011b
                           fill                       100b
                           Multiplan default align.   111b
     }

     //  bit sequence 76543210

     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 最後 3 bit 應只有 1 種選擇
     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(vCol, vRow: word; Field: TField);
begin
  case field.DataType of
     ftString,ftWideString,ftBoolean,ftDate,ftDateTime,ftTime,fttimestamp:
       Cellstr(vcol,vrow,field.asstring);
     ftAutoInc,ftSmallint,ftInteger,ftWord:
       CellWord(vcol,vRow,field.AsInteger);
     //ftFloat, ftBCD:                  //modify by lee
     ftFloat, ftBCD, ftFmtBCD:
       CellDouble(vcol,vrow,field.AsFloat);
  else
       Cellstr(vcol,vrow,EmptyStr);   // <2002-11-17> dllee 其他型態寫入空白字串
  end;
end;


end. 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值