首页  编辑  

不利用OLE如何生成XLS文件

Tags: /超级猛料/Office.OA自动化/Excel/   Date Created:

下面的例子是不利用OLE控制Excel把StringGrid导出导XLS文件中。

{2. Without OLE }

procedure XlsWriteCellLabel(XlsStream: TStream; const ACol, ARow: Word;

 const AValue: string);

var

 L: Word;

const

 {$J+}

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

 {$J-}

begin

 L := Length(AValue);

 CXlsLabel[1] := 8 + L;

 CXlsLabel[2] := ARow;

 CXlsLabel[3] := ACol;

 CXlsLabel[5] := L;

 XlsStream.WriteBuffer(CXlsLabel, SizeOf(CXlsLabel));

 XlsStream.WriteBuffer(Pointer(AValue)^, L);

end;

function SaveAsExcelFile(AGrid: TStringGrid; AFileName: string): Boolean;

const

 {$J+} CXlsBof: array[0..5] of Word = ($809, 8, 00, $10, 0, 0); {$J-}

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

var

 FStream: TFileStream;

 I, J: Integer;

begin

 Result := False;

 FStream := TFileStream.Create(PChar(AFileName), fmCreate or fmOpenWrite);

 try

   CXlsBof[4] := 0;

   FStream.WriteBuffer(CXlsBof, SizeOf(CXlsBof));

   for i := 0 to AGrid.ColCount - 1 do

     for j := 0 to AGrid.RowCount - 1 do

       XlsWriteCellLabel(FStream, I, J, AGrid.cells[i, j]);

   FStream.WriteBuffer(CXlsEof, SizeOf(CXlsEof));

   Result := True;

 finally

   FStream.Free;

 end;

end;

// Example:

procedure TForm1.Button2Click(Sender: TObject);

begin

 if SaveAsExcelFile(StringGrid1, 'c:\MyExcelFile.xls') then

   ShowMessage('StringGrid saved!');

end;

**********************************************************

const

 CXlsBof: array[0..5] of Word = ($809, 8, 00, $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);

procedure XlsBeginStream(XlsStream: TStream; const BuildNumber: Word);

begin

 CXlsBof[4] := BuildNumber;

 XlsStream.WriteBuffer(CXlsBof, SizeOf(CXlsBof));

end;

procedure XlsEndStream(XlsStream: TStream);

begin

 XlsStream.WriteBuffer(CXlsEof, SizeOf(CXlsEof));

end;

procedure XlsWriteCellRk(XlsStream: TStream; const ACol, ARow: Word;

 const AValue: Integer);

var

 V: Integer;

begin

 CXlsRk[2] := ARow;

 CXlsRk[3] := ACol;

 XlsStream.WriteBuffer(CXlsRk, SizeOf(CXlsRk));

 V := (AValue shl 2) or 2;

 XlsStream.WriteBuffer(V, 4);

end;

procedure XlsWriteCellNumber(XlsStream: TStream; const ACol, ARow: Word;

 const AValue: Double);

begin

 CXlsNumber[2] := ARow;

 CXlsNumber[3] := ACol;

 XlsStream.WriteBuffer(CXlsNumber, SizeOf(CXlsNumber));

 XlsStream.WriteBuffer(AValue, 8);

end;

procedure XlsWriteCellLabel(XlsStream: TStream; const ACol, ARow: Word;

 const AValue: string);

var

 L: Word;

begin

 L := Length(AValue);

 CXlsLabel[1] := 8 + L;

 CXlsLabel[2] := ARow;

 CXlsLabel[3] := ACol;

 CXlsLabel[5] := L;

 XlsStream.WriteBuffer(CXlsLabel, SizeOf(CXlsLabel));

 XlsStream.WriteBuffer(Pointer(AValue)^, L);

end;

procedure TForm1.Button1Click(Sender: TObject);

var

 FStream: TFileStream;

 I, J: Integer;

begin

 FStream := TFileStream.Create('c:\e.xls', fmCreate);

 try

   XlsBeginStream(FStream, 0);

   for I := 0 to 99 do

     for J := 0 to 99 do

     begin

       XlsWriteCellNumber(FStream, I, J, 34.34);

       // XlsWriteCellRk(FStream, I, J, 3434);

       // XlsWriteCellLabel(FStream, I, J, Format('Cell: %d,%d', [I, J]));

     end;

   XlsEndStream(FStream);

 finally

   FStream.Free;

 end;

end;

---------------------------------------

{   背景:今天要把DataSet导入Excel,查询以前的贴子,一部分用Ole,速度太慢,

         一部分用ADO连接到Excel文件,也很慢,一气之下把DBGrigEh的导出部分改了出来,

         欢迎大家指教、改进。

   功能:将数据集的数据导入Excel;

   用法:With TDS2Excel.Create(TDataSet(ADOQuery1)) do

         Try

           Save2File(SaveDialog1.FileName, True);

         finally

           Free;

         end;

   作者:Caidao (核心代码来自Ehlib)

   时间:2003-04-09

   地点:汕头

}    

unit UntObject;

interface

Uses

 DB, Classes;

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

 TDS2Excel = Class(TObject)

 Private

   FCol: word;

   FRow: word;

   FDataSet: TDataSet;

   Stream: TStream;

   FWillWriteHead: boolean;

   FBookMark: TBookmark;

   procedure IncColRow;

   procedure WriteBlankCell;

   procedure WriteFloatCell(const AValue: Double);

   procedure WriteIntegerCell(const AValue: Integer);

   procedure WriteStringCell(const AValue: string);

   procedure WritePrefix;

   procedure WriteSuffix;

   procedure WriteTitle;

   procedure WriteDataCell;

   procedure Save2Stream(aStream: TStream);

 Public

   procedure Save2File(FileName: string; WillWriteHead: Boolean);

   Constructor Create(aDataSet: TDataSet);

 end;

implementation

uses SysUtils;

Constructor TDS2Excel.Create(aDataSet: TDataSet);

begin

 inherited Create;

 FDataSet := aDataSet;

end;

procedure TDS2Excel.IncColRow;

begin

 if FCol = FDataSet.FieldCount - 1 then

 begin

   Inc(FRow);

   FCol :=0;

 end

 else

   Inc(FCol);

end;

procedure TDS2Excel.WriteBlankCell;

begin

 CXlsBlank[2] := FRow;

 CXlsBlank[3] := FCol;

 Stream.WriteBuffer(CXlsBlank, SizeOf(CXlsBlank));

 IncColRow;

end;

procedure TDS2Excel.WriteFloatCell(const AValue: Double);

begin

 CXlsNumber[2] := FRow;

 CXlsNumber[3] := FCol;

 Stream.WriteBuffer(CXlsNumber, SizeOf(CXlsNumber));

 Stream.WriteBuffer(AValue, 8);

 IncColRow;

end;

procedure TDS2Excel.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 TDS2Excel.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 TDS2Excel.WritePrefix;

begin

 Stream.WriteBuffer(CXlsBof, SizeOf(CXlsBof));

end;

procedure TDS2Excel.WriteSuffix;

begin

 Stream.WriteBuffer(CXlsEof, SizeOf(CXlsEof));

end;

procedure TDS2Excel.WriteTitle;

var

 n: word;

begin

 for n := 0 to FDataSet.FieldCount - 1 do

   WriteStringCell(FDataSet.Fields[n].FieldName);

end;

procedure TDS2Excel.WriteDataCell;

var

 n: word;

begin

 WritePrefix;

 if FWillWriteHead then WriteTitle;

 FDataSet.DisableControls;

 FBookMark := FDataSet.GetBookmark;

 FDataSet.First;

 while not FDataSet.Eof do

 begin

   for n := 0 to FDataSet.FieldCount - 1 do

   begin

     if FDataSet.Fields[n].IsNull then

       WriteBlankCell

     else begin

       case FDataSet.Fields[n].DataType of

         ftSmallint, ftInteger, ftWord, ftAutoInc, ftBytes:

             WriteIntegerCell(FDataSet.Fields[n].AsInteger);

         ftFloat, ftCurrency, ftBCD:

             WriteFloatCell(FDataSet.Fields[n].AsFloat);

       else

         WriteStringCell(FDataSet.Fields[n].AsString);

       end;

     end;

   end;

   FDataSet.Next;

 end;

 WriteSuffix;

 if FDataSet.BookmarkValid(FBookMark) then FDataSet.GotoBookmark(FBookMark);

 FDataSet.EnableControls;

end;

procedure TDS2Excel.Save2Stream(aStream: TStream);

begin

 FCol := 0;

 FRow := 0;

 Stream := aStream;

 WriteDataCell;

end;

procedure TDS2Excel.Save2File(FileName: string; WillWriteHead: Boolean);

var

 aFileStream: TFileStream;

begin

 FWillWriteHead := WillWriteHead;

 if FileExists(FileName) then DeleteFile(FileName);

 aFileStream := TFileStream.Create(FileName, fmCreate);

 Try

   Save2Stream(aFileStream);

 Finally

   aFileStream.Free;

 end;

end;

end.